aboutsummaryrefslogtreecommitdiffstats
path: root/apps/osmocom_siggen
diff options
context:
space:
mode:
authorDimitri Stolnikov <horiz0n@gmx.net>2013-05-09 13:48:16 +0200
committerDimitri Stolnikov <horiz0n@gmx.net>2013-05-09 13:48:16 +0200
commit3393647bec42b37a5f05ac67d171da9ac8e837d4 (patch)
tree62757d8af9403b54a66dbab03be3ce4823f85ba7 /apps/osmocom_siggen
parent7c22e6975ccb1f2a4b5072e49fad1a928f0ceeee (diff)
apps: add named gain controls to fft and siggen apps
usage examples: osmocom_fft -a hackrf -v osmocom_fft -a rtl=0 -v osmocom_fft -a uhd -v osmocom_siggen -a hackrf -f 100e6 --sweep -x 2e6 -y 10 -v osmocom_siggen -a uhd,subdev=A:0 -f 100e6 --sweep -x 2e6 -y 10 -s 4e6 -v
Diffstat (limited to 'apps/osmocom_siggen')
-rwxr-xr-xapps/osmocom_siggen352
1 files changed, 334 insertions, 18 deletions
diff --git a/apps/osmocom_siggen b/apps/osmocom_siggen
index 0283fcf..3724c5b 100755
--- a/apps/osmocom_siggen
+++ b/apps/osmocom_siggen
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2008,2009,2011,2012 Free Software Foundation, Inc.
+# Copyright 2009,2011,2012 Free Software Foundation, Inc.
#
# This file is part of GNU Radio
#
@@ -21,31 +21,347 @@
#
from gnuradio import gr
+from gnuradio.gr.pubsub import pubsub
from osmosdr import osmocom_siggen_base as osmocom_siggen
-import sys
+import sys, math
-def main():
- if gr.enable_realtime_scheduling() != gr.RT_OK:
- print "Note: failed to enable realtime scheduling, continuing"
+try:
+ from gnuradio.wxgui import gui, forms
+ import wx
+except ImportError:
+ sys.stderr.write("Error importing GNU Radio's wxgui. Please make sure gr-wxgui is installed.\n")
+ sys.exit(1)
+
+class app_gui(pubsub):
+ def __init__(self, frame, panel, vbox, top_block, options, args):
+ pubsub.__init__(self)
+ self.frame = frame # Use for top-level application window frame
+ self.panel = panel # Use as parent class for created windows
+ self.vbox = vbox # Use as sizer for created windows
+ self.tb = top_block # GUI-unaware flowgraph class
+ self.options = options # Supplied command-line options
+ self.args = args # Supplied command-line arguments
+ self.build_gui()
+
+ # Event response handlers
+ def evt_set_status_msg(self, msg):
+ self.frame.SetStatusText(msg, 0)
+
+ # GUI construction
+ def build_gui(self):
+ self.vbox.AddSpacer(3)
+ self.vbox.AddStretchSpacer()
+ ##################################################
+ # Baseband controls
+ ##################################################
+ bb_vbox = forms.static_box_sizer(parent=self.panel, label="Baseband Modulation", orient=wx.VERTICAL, bold=True)
+ self.vbox.Add(bb_vbox, 0, wx.EXPAND)
+ sine_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
+ sweep_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
+ tone_bb_hbox = wx.BoxSizer(wx.HORIZONTAL)
+ self.vbox.AddSpacer(5)
+ self.vbox.AddStretchSpacer()
+ #callback to show/hide forms
+ def set_type(type):
+ sine_bb_hbox.ShowItems(type == gr.GR_SIN_WAVE)
+ sweep_bb_hbox.ShowItems(type == 'sweep')
+ tone_bb_hbox.ShowItems(type == '2tone')
+ self.vbox.Layout()
+ self.tb.subscribe(osmocom_siggen.TYPE_KEY, set_type)
+ #create sine forms
+ sine_bb_hbox.AddSpacer(5)
+ forms.text_box(
+ parent=self.panel, sizer=sine_bb_hbox,
+ label='Frequency (Hz)',
+ ps=self.tb,
+ key=osmocom_siggen.WAVEFORM_FREQ_KEY,
+ converter=forms.float_converter(),
+ )
+ sine_bb_hbox.AddStretchSpacer()
+ #create sweep forms
+ sweep_bb_hbox.AddSpacer(5)
+ forms.text_box(
+ parent=self.panel, sizer=sweep_bb_hbox,
+ label='Sweep Width (Hz)',
+ ps=self.tb,
+ key=osmocom_siggen.WAVEFORM_FREQ_KEY,
+ converter=forms.float_converter(),
+ )
+ sweep_bb_hbox.AddStretchSpacer()
+ forms.text_box(
+ parent=self.panel, sizer=sweep_bb_hbox,
+ label='Sweep Rate (Hz)',
+ ps=self.tb,
+ key=osmocom_siggen.WAVEFORM2_FREQ_KEY,
+ converter=forms.float_converter(),
+ )
+ sweep_bb_hbox.AddStretchSpacer()
+ #create 2tone forms
+ tone_bb_hbox.AddSpacer(5)
+ forms.text_box(
+ parent=self.panel, sizer=tone_bb_hbox,
+ label='Tone 1 (Hz)',
+ ps=self.tb,
+ key=osmocom_siggen.WAVEFORM_FREQ_KEY,
+ converter=forms.float_converter(),
+ )
+ tone_bb_hbox.AddStretchSpacer()
+ forms.text_box(
+ parent=self.panel, sizer=tone_bb_hbox,
+ label='Tone 2 (Hz)',
+ ps=self.tb,
+ key=osmocom_siggen.WAVEFORM2_FREQ_KEY,
+ converter=forms.float_converter(),
+ )
+ tone_bb_hbox.AddStretchSpacer()
+ forms.radio_buttons(
+ parent=self.panel, sizer=bb_vbox,
+ choices=osmocom_siggen.waveforms.keys(),
+ labels=osmocom_siggen.waveforms.values(),
+ ps=self.tb,
+ key=osmocom_siggen.TYPE_KEY,
+ style=wx.NO_BORDER | wx.RA_HORIZONTAL,
+ )
+ bb_vbox.AddSpacer(5)
+ bb_vbox.Add(sine_bb_hbox, 0, wx.EXPAND)
+ bb_vbox.Add(sweep_bb_hbox, 0, wx.EXPAND)
+ bb_vbox.Add(tone_bb_hbox, 0, wx.EXPAND)
+ set_type(self.tb[osmocom_siggen.TYPE_KEY])
+
+ ##################################################
+ # Frequency controls
+ ##################################################
+ fc_vbox = forms.static_box_sizer(parent=self.panel,
+ label="Center Frequency",
+ orient=wx.VERTICAL,
+ bold=True)
+ fc_vbox.AddSpacer(3)
+
+ # First row of frequency controls (center frequency)
+ freq_hbox = wx.BoxSizer(wx.HORIZONTAL)
+ fc_vbox.Add(freq_hbox, 0, wx.EXPAND)
+ fc_vbox.AddSpacer(5)
+
+ # Second row of frequency controls (freq. correction)
+ corr_hbox = wx.BoxSizer(wx.HORIZONTAL)
+ fc_vbox.Add(corr_hbox, 0, wx.EXPAND)
+ fc_vbox.AddSpacer(3)
+
+ # Add frequency controls to top window sizer
+ self.vbox.Add(fc_vbox, 0, wx.EXPAND)
+ self.vbox.AddSpacer(5)
+ self.vbox.AddStretchSpacer()
+
+ freq_hbox.AddSpacer(3)
+ forms.text_box(
+ parent=self.panel, sizer=freq_hbox,
+ label='Center Frequency (Hz)',
+ proportion=1,
+ converter=forms.float_converter(),
+ ps=self.tb,
+ key=osmocom_siggen.TX_FREQ_KEY,
+ )
+ freq_hbox.AddSpacer(5)
+
+ forms.slider(
+ parent=self.panel, sizer=freq_hbox,
+ proportion=2,
+ ps=self.tb,
+ key=osmocom_siggen.TX_FREQ_KEY,
+ minimum=self.tb[osmocom_siggen.FREQ_RANGE_KEY].start(),
+ maximum=self.tb[osmocom_siggen.FREQ_RANGE_KEY].stop(),
+ num_steps=101,
+ )
+ freq_hbox.AddSpacer(3)
+
+ corr_hbox.AddSpacer(3)
+ forms.text_box(
+ parent=self.panel, sizer=corr_hbox,
+ label='Freq. Correction (ppm)',
+ proportion=1,
+ converter=forms.int_converter(),
+ ps=self.tb,
+ key=osmocom_siggen.FREQ_CORR_KEY,
+ )
+ corr_hbox.AddSpacer(5)
+
+ forms.slider(
+ parent=self.panel, sizer=corr_hbox,
+ proportion=2,
+ ps=self.tb,
+ key=osmocom_siggen.FREQ_CORR_KEY,
+ minimum=-100,
+ maximum=+100,
+ num_steps=201,
+ step_size=1,
+ )
+ corr_hbox.AddSpacer(3)
+
+ ##################################################
+ # Amplitude controls
+ ##################################################
+ amp_vbox = forms.static_box_sizer(parent=self.panel,
+ label="Amplitude",
+ orient=wx.VERTICAL,
+ bold=True)
+ amp_vbox.AddSpacer(3)
+
+ # First row of amp controls (ampl)
+ lvl_hbox = wx.BoxSizer(wx.HORIZONTAL)
+ amp_vbox.Add(lvl_hbox, 0, wx.EXPAND)
+ amp_vbox.AddSpacer(5)
+
+ self.vbox.Add(amp_vbox, 0, wx.EXPAND)
+ self.vbox.AddSpacer(5)
+ self.vbox.AddStretchSpacer()
- # Grab command line options and create top block
+ lvl_hbox.AddSpacer(3)
+ forms.text_box(
+ parent=self.panel, sizer=lvl_hbox,
+ proportion=1,
+ converter=forms.float_converter(),
+ ps=self.tb,
+ key=osmocom_siggen.AMPLITUDE_KEY,
+ label="Level (0.1-1.0)",
+ )
+ lvl_hbox.AddSpacer(5)
+ forms.log_slider(
+ parent=self.panel, sizer=lvl_hbox,
+ proportion=2,
+ ps=self.tb,
+ key=osmocom_siggen.AMPLITUDE_KEY,
+ min_exp=-1,
+ max_exp=0,
+ base=10,
+ num_steps=100,
+ )
+ lvl_hbox.AddSpacer(3)
+
+ for gain_name in self.tb.get_gain_names():
+ range = self.tb[osmocom_siggen.GAIN_RANGE_KEY(gain_name)]
+ gain = self.tb[osmocom_siggen.GAIN_KEY(gain_name)]
+
+ #print gain_name, gain, range.to_pp_string()
+ if range.start() < range.stop():
+ gain_hbox = wx.BoxSizer(wx.HORIZONTAL)
+ amp_vbox.Add(gain_hbox, 0, wx.EXPAND)
+ amp_vbox.AddSpacer(3)
+
+ gain_hbox.AddSpacer(3)
+ forms.text_box(
+ parent=self.panel, sizer=gain_hbox,
+ proportion=1,
+ converter=forms.float_converter(),
+ ps=self.tb,
+ key=osmocom_siggen.GAIN_KEY(gain_name),
+ label=gain_name + " Gain (dB)",
+ )
+ gain_hbox.AddSpacer(5)
+ forms.slider(
+ parent=self.panel, sizer=gain_hbox,
+ proportion=2,
+ ps=self.tb,
+ key=osmocom_siggen.GAIN_KEY(gain_name),
+ minimum=range.start(),
+ maximum=range.stop(),
+ step_size=range.step(),
+ )
+ gain_hbox.AddSpacer(3)
+
+ ##################################################
+ # Bandwidth controls
+ ##################################################
+ try:
+
+ bw_range = self.tb[osmocom_siggen.BWIDTH_RANGE_KEY]
+ #print bw_range.to_pp_string()
+ #if bw_range.start() < bw_range.stop():
+ if 0:
+ bwidth_vbox = forms.static_box_sizer(parent=self.panel,
+ label="Bandwidth",
+ orient=wx.VERTICAL,
+ bold=True)
+ bwidth_vbox.AddSpacer(3)
+ bwidth_hbox = wx.BoxSizer(wx.HORIZONTAL)
+ bwidth_vbox.Add(bwidth_hbox, 0, wx.EXPAND)
+ bwidth_vbox.AddSpacer(3)
+
+ self.vbox.Add(bwidth_vbox, 0, wx.EXPAND)
+ self.vbox.AddSpacer(5)
+ self.vbox.AddStretchSpacer()
+
+ bwidth_hbox.AddSpacer(3)
+ forms.text_box(
+ parent=self.panel, sizer=bwidth_hbox,
+ proportion=1,
+ converter=forms.float_converter(),
+ ps=self.tb,
+ key=osmocom_siggen.BWIDTH_KEY,
+ label="Bandwidth (Hz)",
+ )
+ bwidth_hbox.AddSpacer(5)
+ forms.slider(
+ parent=self.panel, sizer=bwidth_hbox,
+ proportion=2,
+ ps=self.tb,
+ key=osmocom_siggen.BWIDTH_KEY,
+ minimum=bw_range.start(),
+ maximum=bw_range.stop(),
+ step_size=bw_range.step(),
+ )
+ bwidth_hbox.AddSpacer(3)
+
+ except RuntimeError:
+ pass
+
+ ##################################################
+ # Sample Rate controls
+ ##################################################
+ sam_hbox = forms.static_box_sizer(parent=self.panel,
+ label="Sample Rate",
+ orient=wx.HORIZONTAL,
+ bold=True)
+ self.vbox.Add(sam_hbox, 0, wx.EXPAND)
+ self.vbox.AddSpacer(5)
+ self.vbox.AddStretchSpacer()
+ sam_hbox.AddStretchSpacer(20)
+ forms.static_text(
+ parent=self.panel, sizer=sam_hbox,
+ label='Sample Rate (sps)',
+ ps=self.tb,
+ key=osmocom_siggen.SAMP_RATE_KEY,
+ converter=forms.float_converter(),
+ )
+ sam_hbox.AddStretchSpacer(20)
+
+def main():
try:
+ # Get command line parameters
(options, args) = osmocom_siggen.get_options()
+
+ # Create the top block using these
tb = osmocom_siggen.top_block(options, args)
+ # Create the GUI application
+ app = gui.app(top_block=tb, # Constructed top block
+ gui=app_gui, # User interface class
+ options=options, # Command line options
+ args=args, # Command line args
+ title="OSMOCOM Signal Generator", # Top window title
+ nstatus=1, # Number of status lines
+ start=True, # Whether to start flowgraph
+ realtime=True) # Whether to set realtime priority
+
+ # And run it
+ app.MainLoop()
+
except RuntimeError, e:
print e
sys.exit(1)
- tb.start()
- raw_input('Press Enter to quit: ')
- tb.stop()
- tb.wait()
-
-# Make sure to create the top block (tb) within a function:
-# That code in main will allow tb to go out of scope on return,
-# which will call the decontructor on usrp and stop transmit.
-# Whats odd is that grc works fine with tb in the __main__,
-# perhaps its because the try/except clauses around tb.
-if __name__ == "__main__":
- main()
+# Make sure to create the top block (tb) within a function: That code
+# in main will allow tb to go out of scope on return, which will call
+# the decontructor on radio device and stop transmit. Whats odd is that
+# grc works fine with tb in the __main__, perhaps its because the
+# try/except clauses around tb.
+if __name__ == "__main__": main()