diff options
Diffstat (limited to 'gr-utils')
-rw-r--r-- | gr-utils/src/python/Makefile.am | 8 | ||||
-rwxr-xr-x | gr-utils/src/python/gr_plot_const.py | 27 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp2_fft.py | 273 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_fft.py | 309 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_oscope.py | 349 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_rx_nogui.py | 213 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_siggen.py | 331 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_siggen_gui.py | 317 |
8 files changed, 19 insertions, 1808 deletions
diff --git a/gr-utils/src/python/Makefile.am b/gr-utils/src/python/Makefile.am index b422bfd05..11fb038f6 100644 --- a/gr-utils/src/python/Makefile.am +++ b/gr-utils/src/python/Makefile.am @@ -49,10 +49,4 @@ bin_SCRIPTS = \ gr_plot_iq.py \ gr_plot_short.py \ gr_plot_qt.py \ - gr_filter_design.py \ - usrp_fft.py \ - usrp_oscope.py \ - usrp_rx_nogui.py \ - usrp_siggen.py \ - usrp_siggen_gui.py \ - usrp2_fft.py + gr_filter_design.py diff --git a/gr-utils/src/python/gr_plot_const.py b/gr-utils/src/python/gr_plot_const.py index 5dd08c9a0..8873e5b7e 100755 --- a/gr-utils/src/python/gr_plot_const.py +++ b/gr-utils/src/python/gr_plot_const.py @@ -85,16 +85,23 @@ class draw_constellation: except MemoryError: print "End of File" else: - self.reals = scipy.array([r.real for r in iq]) - self.imags = scipy.array([i.imag for i in iq]) + # retesting length here as newer version of scipy does not throw a MemoryError, just + # returns a zero-length array + if(len(iq) > 0): + self.reals = scipy.array([r.real for r in iq]) + self.imags = scipy.array([i.imag for i in iq]) + + self.time = scipy.array([i*(1/self.sample_rate) for i in range(len(self.reals))]) + return True + else: + print "End of File" + return False - self.time = scipy.array([i*(1/self.sample_rate) for i in range(len(self.reals))]) - def make_plots(self): # if specified on the command-line, set file pointer self.hfile.seek(self.sizeof_data*self.start, 1) - self.get_data() + r = self.get_data() # Subplot for real and imaginary parts of signal self.sp_iq = self.fig.add_subplot(2,1,1, position=[0.075, 0.2, 0.4, 0.6]) @@ -175,8 +182,9 @@ class draw_constellation: self.step_forward() def step_forward(self): - self.get_data() - self.update_plots() + r = self.get_data() + if(r): + self.update_plots() def step_backward(self): # Step back in file position @@ -184,8 +192,9 @@ class draw_constellation: self.hfile.seek(-2*self.sizeof_data*self.block_length, 1) else: self.hfile.seek(-self.hfile.tell(),1) - self.get_data() - self.update_plots() + r = self.get_data() + if(r): + self.update_plots() def mouse_button_callback(self, event): diff --git a/gr-utils/src/python/usrp2_fft.py b/gr-utils/src/python/usrp2_fft.py deleted file mode 100755 index 4276e389a..000000000 --- a/gr-utils/src/python/usrp2_fft.py +++ /dev/null @@ -1,273 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2007,2008,2010 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -from gnuradio import gr, gru -from gnuradio import usrp2 -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider -from optparse import OptionParser -import wx -import sys -import numpy - -class app_top_block(stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) - - self.frame = frame - self.panel = panel - - parser = OptionParser(option_class=eng_option) - parser.add_option("-e", "--interface", type="string", default="eth0", - help="select Ethernet interface, default is eth0") - parser.add_option("-m", "--mac-addr", type="string", default="", - help="select USRP by MAC address, default is auto-select") - #parser.add_option("-A", "--antenna", default=None, - # help="select Rx Antenna (only on RFX-series boards)") - parser.add_option("-d", "--decim", type="int", default=16, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - parser.add_option("-W", "--waterfall", action="store_true", default=False, - help="Enable waterfall display") - parser.add_option("-S", "--oscilloscope", action="store_true", default=False, - help="Enable oscilloscope display") - parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1, - help="Set fftsink averaging factor, default=[%default]") - parser.add_option("", "--ref-scale", type="eng_float", default=1.0, - help="Set dBFS=0dB input value, default=[%default]") - parser.add_option("--fft-size", type="int", default=1024, - help="Set number of FFT bins [default=%default]") - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - self.options = options - self.show_debug_info = True - - self.u = usrp2.source_32fc(options.interface, options.mac_addr) - self.u.set_decim(options.decim) - - input_rate = self.u.adc_rate() / self.u.decim() - - if options.waterfall: - self.scope = \ - waterfallsink2.waterfall_sink_c (panel, fft_size=1024, sample_rate=input_rate) - elif options.oscilloscope: - self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate) - else: - self.scope = fftsink2.fft_sink_c (panel, - fft_size=options.fft_size, - sample_rate=input_rate, - ref_scale=options.ref_scale, - ref_level=20.0, - y_divs = 12, - avg_alpha=options.avg_alpha) - - self.connect(self.u, self.scope) - - self._build_gui(vbox) - self._setup_events() - - # set initial values - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.u.gain_range() - options.gain = float(g[0]+g[1])/2 - - if options.freq is None: - # if no freq was specified, use the mid-point - r = self.u.freq_range() - options.freq = float(r[0]+r[1])/2 - - self.set_gain(options.gain) - - #if options.antenna is not None: - # print "Selecting antenna %s" % (options.antenna,) - # self.subdev.select_rx_antenna(options.antenna) - - if self.show_debug_info: - self.myform['decim'].set_value(self.u.decim()) - self.myform['fs@gbe'].set_value(input_rate) - self.myform['dbname'].set_value("0x%04X" % (self.u.daughterboard_id(),)) # FIXME: add text name - self.myform['baseband'].set_value(0) - self.myform['ddc'].set_value(0) - - if not(self.set_freq(options.freq)): - self._set_status_msg("Failed to set initial frequency") - - def _set_status_msg(self, msg): - self.frame.GetStatusBar().SetStatusText(msg, 0) - - def _build_gui(self, vbox): - - def _form_set_freq(kv): - return self.set_freq(kv['freq']) - - vbox.Add(self.scope.win, 10, wx.EXPAND) - - # add control area at the bottom - self.myform = myform = form.form() - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0, 0) - myform['freq'] = form.float_field( - parent=self.panel, sizer=hbox, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - - hbox.Add((5,0), 0, 0) - g = self.u.gain_range() - - # some configurations don't have gain control - if g[1] > g[0]: - myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, - min=int(g[0]), max=int(g[1]), - callback=self.set_gain) - - hbox.Add((5,0), 0, 0) - vbox.Add(hbox, 0, wx.EXPAND) - - self._build_subpanel(vbox) - - def _build_subpanel(self, vbox_arg): - # build a secondary information panel (sometimes hidden) - - # FIXME figure out how to have this be a subpanel that is always - # created, but has its visibility controlled by foo.Show(True/False) - - def _form_set_decim(kv): - return self.set_decim(kv['decim']) - - if not(self.show_debug_info): - return - - panel = self.panel - vbox = vbox_arg - myform = self.myform - - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - - myform['decim'] = form.int_field( - parent=panel, sizer=hbox, label="Decim", - callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg)) - - hbox.Add((5,0), 1) - myform['fs@gbe'] = form.static_float_field( - parent=panel, sizer=hbox, label="Fs@GbE") - - hbox.Add((5,0), 1) - myform['dbname'] = form.static_text_field( - parent=panel, sizer=hbox) - - hbox.Add((5,0), 1) - myform['baseband'] = form.static_float_field( - parent=panel, sizer=hbox, label="Analog BB") - - hbox.Add((5,0), 1) - myform['ddc'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC") - - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = self.u.set_center_freq(target_freq) - - if r: - self.myform['freq'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband'].set_value(r.baseband_freq) - self.myform['ddc'].set_value(r.dxc_freq) - if not self.options.oscilloscope: - self.scope.set_baseband_freq(target_freq) - return True - - return False - - def set_gain(self, gain): - if self.myform.has_key('gain'): - self.myform['gain'].set_value(gain) # update displayed value - self.u.set_gain(gain) - - def set_decim(self, decim): - ok = self.u.set_decim(decim) - if not ok: - print "set_decim failed" - input_rate = self.u.adc_rate() / self.u.decim() - self.scope.set_sample_rate(input_rate) - if self.show_debug_info: # update displayed values - self.myform['decim'].set_value(self.u.decim()) - self.myform['fs@gbe'].set_value(input_rate) - return ok - - def _setup_events(self): - if not self.options.waterfall and not self.options.oscilloscope: - self.scope.win.Bind(wx.EVT_LEFT_DCLICK, self.evt_left_dclick) - - def evt_left_dclick(self, event): - (ux, uy) = self.scope.win.GetXY(event) - if event.CmdDown(): - # Re-center on maximum power - points = self.scope.win._points - if self.scope.win.peak_hold: - if self.scope.win.peak_vals is not None: - ind = numpy.argmax(self.scope.win.peak_vals) - else: - ind = int(points.shape()[0]/2) - else: - ind = numpy.argmax(points[:,1]) - (freq, pwr) = points[ind] - target_freq = freq/self.scope.win._scale_factor - print ind, freq, pwr - self.set_freq(target_freq) - else: - # Re-center on clicked frequency - target_freq = ux/self.scope.win._scale_factor - self.set_freq(target_freq) - - -def main (): - app = stdgui2.stdapp(app_top_block, "USRP2 FFT", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gr-utils/src/python/usrp_fft.py b/gr-utils/src/python/usrp_fft.py deleted file mode 100755 index eda9bd57c..000000000 --- a/gr-utils/src/python/usrp_fft.py +++ /dev/null @@ -1,309 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2007,2008,2010 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -from gnuradio import gr, gru -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider -from optparse import OptionParser -import wx -import sys -import numpy - -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - If there's a daughterboard on A, select A. - If there's a daughterboard on B, select B. - Otherwise, select A. - """ - if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem - return (0, 0) - if u.db(1, 0).dbid() >= 0: - return (1, 0) - return (0, 0) - - -class app_top_block(stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) - - self.frame = frame - self.panel = panel - - parser = OptionParser(option_class=eng_option) - parser.add_option("-w", "--which", type="int", default=0, - help="select which USRP (0, 1, ...) default is %default", - metavar="NUM") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=first one with a daughterboard)") - parser.add_option("-A", "--antenna", default=None, - help="select Rx Antenna (only on RFX-series boards)") - parser.add_option("-d", "--decim", type="int", default=16, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB [default is midpoint]") - parser.add_option("-W", "--waterfall", action="store_true", default=False, - help="Enable waterfall display") - parser.add_option("-8", "--width-8", action="store_true", default=False, - help="Enable 8-bit samples across USB") - parser.add_option( "--no-hb", action="store_true", default=False, - help="don't use halfband filter in usrp") - parser.add_option("-S", "--oscilloscope", action="store_true", default=False, - help="Enable oscilloscope display") - parser.add_option("", "--avg-alpha", type="eng_float", default=1e-1, - help="Set fftsink averaging factor, [default=%default]") - parser.add_option("", "--ref-scale", type="eng_float", default=13490.0, - help="Set dBFS=0dB input value, [default=%default]") - parser.add_option("", "--fft-size", type="int", default=1024, - help="Set FFT frame size, [default=%default]"); - - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - self.options = options - self.show_debug_info = True - - # build the graph - if options.no_hb or (options.decim<8): - #Min decimation of this firmware is 4. - #contains 4 Rx paths without halfbands and 0 tx paths. - self.fpga_filename="std_4rx_0tx.rbf" - self.u = usrp.source_c(which=options.which, decim_rate=options.decim, fpga_filename=self.fpga_filename) - else: - #Min decimation of standard firmware is 8. - #standard fpga firmware "std_2rxhb_2tx.rbf" - #contains 2 Rx paths with halfband filters and 2 tx paths (the default) - self.u = usrp.source_c(which=options.which, decim_rate=options.decim) - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - - if options.width_8: - width = 8 - shift = 8 - format = self.u.make_format(width, shift) - print "format =", hex(format) - r = self.u.set_format(format) - print "set_format =", r - - # determine the daughterboard subdevice we're using - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - - input_rate = self.u.adc_freq() / self.u.decim_rate() - - if options.waterfall: - self.scope = \ - waterfallsink2.waterfall_sink_c (panel, fft_size=options.fft_size, sample_rate=input_rate) - elif options.oscilloscope: - self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate) - else: - self.scope = fftsink2.fft_sink_c (panel, fft_size=options.fft_size, sample_rate=input_rate, - ref_scale=options.ref_scale, ref_level=0.0, y_divs = 10, - avg_alpha=options.avg_alpha) - - self.connect(self.u, self.scope) - - self._build_gui(vbox) - self._setup_events() - - # set initial values - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 - - if options.freq is None: - # if no freq was specified, use the mid-point - r = self.subdev.freq_range() - options.freq = float(r[0]+r[1])/2 - - self.set_gain(options.gain) - - if options.antenna is not None: - print "Selecting antenna %s" % (options.antenna,) - self.subdev.select_rx_antenna(options.antenna) - - if self.show_debug_info: - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) - self.myform['dbname'].set_value(self.subdev.name()) - self.myform['baseband'].set_value(0) - self.myform['ddc'].set_value(0) - - if not(self.set_freq(options.freq)): - self._set_status_msg("Failed to set initial frequency") - - def _set_status_msg(self, msg): - self.frame.GetStatusBar().SetStatusText(msg, 0) - - def _build_gui(self, vbox): - - def _form_set_freq(kv): - return self.set_freq(kv['freq']) - - vbox.Add(self.scope.win, 10, wx.EXPAND) - - # add control area at the bottom - self.myform = myform = form.form() - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0, 0) - myform['freq'] = form.float_field( - parent=self.panel, sizer=hbox, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - - hbox.Add((5,0), 0, 0) - g = self.subdev.gain_range() - myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, - min=int(g[0]), max=int(g[1]), - callback=self.set_gain) - - hbox.Add((5,0), 0, 0) - vbox.Add(hbox, 0, wx.EXPAND) - - self._build_subpanel(vbox) - - def _build_subpanel(self, vbox_arg): - # build a secondary information panel (sometimes hidden) - - # FIXME figure out how to have this be a subpanel that is always - # created, but has its visibility controlled by foo.Show(True/False) - - def _form_set_decim(kv): - return self.set_decim(kv['decim']) - - if not(self.show_debug_info): - return - - panel = self.panel - vbox = vbox_arg - myform = self.myform - - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - - myform['decim'] = form.int_field( - parent=panel, sizer=hbox, label="Decim", - callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg)) - - hbox.Add((5,0), 1) - myform['fs@usb'] = form.static_float_field( - parent=panel, sizer=hbox, label="Fs@USB") - - hbox.Add((5,0), 1) - myform['dbname'] = form.static_text_field( - parent=panel, sizer=hbox) - - hbox.Add((5,0), 1) - myform['baseband'] = form.static_float_field( - parent=panel, sizer=hbox, label="Analog BB") - - hbox.Add((5,0), 1) - myform['ddc'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC") - - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = self.u.tune(0, self.subdev, target_freq) - - if r: - self.myform['freq'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband'].set_value(r.baseband_freq) - self.myform['ddc'].set_value(r.dxc_freq) - if not self.options.oscilloscope: - self.scope.set_baseband_freq(target_freq) - return True - - return False - - def set_gain(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) - - def set_decim(self, decim): - ok = self.u.set_decim_rate(decim) - if not ok: - print "set_decim failed" - input_rate = self.u.adc_freq() / self.u.decim_rate() - self.scope.set_sample_rate(input_rate) - if self.show_debug_info: # update displayed values - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) - return ok - - def _setup_events(self): - if not self.options.waterfall and not self.options.oscilloscope: - self.scope.win.Bind(wx.EVT_LEFT_DCLICK, self.evt_left_dclick) - - def evt_left_dclick(self, event): - (ux, uy) = self.scope.win.GetXY(event) - if event.CmdDown(): - # Re-center on maximum power - points = self.scope.win._points - if self.scope.win.peak_hold: - if self.scope.win.peak_vals is not None: - ind = numpy.argmax(self.scope.win.peak_vals) - else: - ind = int(points.shape()[0]/2) - else: - ind = numpy.argmax(points[:,1]) - (freq, pwr) = points[ind] - target_freq = freq/self.scope.win._scale_factor - print ind, freq, pwr - self.set_freq(target_freq) - else: - # Re-center on clicked frequency - target_freq = ux/self.scope.win._scale_factor - self.set_freq(target_freq) - - -def main (): - app = stdgui2.stdapp(app_top_block, "USRP FFT", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gr-utils/src/python/usrp_oscope.py b/gr-utils/src/python/usrp_oscope.py deleted file mode 100755 index 9921e9873..000000000 --- a/gr-utils/src/python/usrp_oscope.py +++ /dev/null @@ -1,349 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2004,2005,2006,2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -# print "Loading revised usrp_oscope with additional options for scopesink..." - -from gnuradio import gr, gru -from gnuradio import usrp -from gnuradio import eng_notation -from gnuradio.eng_option import eng_option -from gnuradio.wxgui import stdgui2, scopesink2, form, slider -from optparse import OptionParser -import wx -import sys -from usrpm import usrp_dbid - - -def pick_subdevice(u): - """ - The user didn't specify a subdevice on the command line. - If there's a daughterboard on A, select A. - If there's a daughterboard on B, select B. - Otherwise, select A. - """ - if u.db(0, 0).dbid() >= 0: # dbid is < 0 if there's no d'board or a problem - return (0, 0) - if u.db(1, 0).dbid() >= 0: - return (1, 0) - return (0, 0) - - -class app_top_block(stdgui2.std_top_block): - def __init__(self, frame, panel, vbox, argv): - stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv) - - self.frame = frame - self.panel = panel - - parser = OptionParser(option_class=eng_option) - parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None, - help="select USRP Rx side A or B (default=first one with a daughterboard)") - parser.add_option("-d", "--decim", type="int", default=16, - help="set fgpa decimation rate to DECIM [default=%default]") - parser.add_option("-f", "--freq", type="eng_float", default=None, - help="set frequency to FREQ", metavar="FREQ") - parser.add_option("-g", "--gain", type="eng_float", default=None, - help="set gain in dB (default is midpoint)") - parser.add_option("-8", "--width-8", action="store_true", default=False, - help="Enable 8-bit samples across USB") - parser.add_option( "--no-hb", action="store_true", default=False, - help="don't use halfband filter in usrp") - parser.add_option("-C", "--basic-complex", action="store_true", default=False, - help="Use both inputs of a basicRX or LFRX as a single Complex input channel") - parser.add_option("-D", "--basic-dualchan", action="store_true", default=False, - help="Use both inputs of a basicRX or LFRX as seperate Real input channels") - parser.add_option("-n", "--frame-decim", type="int", default=1, - help="set oscope frame decimation factor to n [default=1]") - parser.add_option("-v", "--v-scale", type="eng_float", default=1000, - help="set oscope initial V/div to SCALE [default=%default]") - parser.add_option("-t", "--t-scale", type="eng_float", default=49e-6, - help="set oscope initial s/div to SCALE [default=50us]") - (options, args) = parser.parse_args() - if len(args) != 0: - parser.print_help() - sys.exit(1) - - self.show_debug_info = True - - # build the graph - if options.basic_dualchan: - self.num_inputs=2 - else: - self.num_inputs=1 - if options.no_hb or (options.decim<8): - #Min decimation of this firmware is 4. - #contains 4 Rx paths without halfbands and 0 tx paths. - self.fpga_filename="std_4rx_0tx.rbf" - self.u = usrp.source_c(nchan=self.num_inputs,decim_rate=options.decim, fpga_filename=self.fpga_filename) - else: - #Min decimation of standard firmware is 8. - #standard fpga firmware "std_2rxhb_2tx.rbf" - #contains 2 Rx paths with halfband filters and 2 tx paths (the default) - self.u = usrp.source_c(nchan=self.num_inputs,decim_rate=options.decim) - - if options.rx_subdev_spec is None: - options.rx_subdev_spec = pick_subdevice(self.u) - - if options.width_8: - width = 8 - shift = 8 - format = self.u.make_format(width, shift) - #print "format =", hex(format) - r = self.u.set_format(format) - #print "set_format =", r - - # determine the daughterboard subdevice we're using - self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) - if (options.basic_complex or options.basic_dualchan ): - if ((self.subdev.dbid()==usrp_dbid.BASIC_RX) or (self.subdev.dbid()==usrp_dbid.LF_RX)): - side = options.rx_subdev_spec[0] # side A = 0, side B = 1 - if options.basic_complex: - #force Basic_RX and LF_RX in complex mode (use both I and Q channel) - print "Receiver daughterboard forced in complex mode. Both inputs will combined to form a single complex channel." - self.dualchan=False - if side==0: - self.u.set_mux(0x00000010) #enable adc 0 and 1 to form a single complex input on side A - else: #side ==1 - self.u.set_mux(0x00000032) #enable adc 3 and 2 to form a single complex input on side B - elif options.basic_dualchan: - #force Basic_RX and LF_RX in dualchan mode (use input A for channel 0 and input B for channel 1) - print "Receiver daughterboard forced in dualchannel mode. Each input will be used to form a seperate channel." - self.dualchan=True - if side==0: - self.u.set_mux(gru.hexint(0xf0f0f1f0)) #enable adc 0, side A to form a real input on channel 0 and adc1,side A to form a real input on channel 1 - else: #side ==1 - self.u.set_mux(0xf0f0f3f2) #enable adc 2, side B to form a real input on channel 0 and adc3,side B to form a real input on channel 1 - else: - sys.stderr.write('options basic_dualchan or basic_complex is only supported for Basic Rx or LFRX at the moment\n') - sys.exit(1) - else: - self.dualchan=False - self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) - - input_rate = self.u.adc_freq() / self.u.decim_rate() - - self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate, - frame_decim=options.frame_decim, - v_scale=options.v_scale, - t_scale=options.t_scale, - num_inputs=self.num_inputs) - if self.dualchan: - # deinterleave two channels from FPGA - self.di = gr.deinterleave(gr.sizeof_gr_complex) - self.connect(self.u,self.di) - self.connect((self.di,0),(self.scope,0)) - self.connect((self.di,1),(self.scope,1)) - else: - self.connect(self.u, self.scope) - - self._build_gui(vbox) - - # set initial values - - if options.gain is None: - # if no gain was specified, use the mid-point in dB - g = self.subdev.gain_range() - options.gain = float(g[0]+g[1])/2 - - if options.freq is None: - if ((self.subdev.dbid()==usrp_dbid.BASIC_RX) or (self.subdev.dbid()==usrp_dbid.LF_RX)): - #for Basic RX and LFRX if no freq is specified you probably want 0.0 Hz and not 45 GHz - options.freq=0.0 - else: - # if no freq was specified, use the mid-point - r = self.subdev.freq_range() - options.freq = float(r[0]+r[1])/2 - - self.set_gain(options.gain) - - if self.show_debug_info: - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) - self.myform['dbname'].set_value(self.subdev.name()) - self.myform['baseband'].set_value(0) - self.myform['ddc'].set_value(0) - if self.num_inputs==2: - self.myform['baseband2'].set_value(0) - self.myform['ddc2'].set_value(0) - - if not(self.set_freq(options.freq)): - self._set_status_msg("Failed to set initial frequency") - if self.num_inputs==2: - if not(self.set_freq2(options.freq)): - self._set_status_msg("Failed to set initial frequency for channel 2") - - - def _set_status_msg(self, msg): - self.frame.GetStatusBar().SetStatusText(msg, 0) - - def _build_gui(self, vbox): - - def _form_set_freq(kv): - return self.set_freq(kv['freq']) - - def _form_set_freq2(kv): - return self.set_freq2(kv['freq2']) - vbox.Add(self.scope.win, 10, wx.EXPAND) - - # add control area at the bottom - self.myform = myform = form.form() - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0, 0) - myform['freq'] = form.float_field( - parent=self.panel, sizer=hbox, label="Center freq", weight=1, - callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg)) - if self.num_inputs==2: - myform['freq2'] = form.float_field( - parent=self.panel, sizer=hbox, label="Center freq2", weight=1, - callback=myform.check_input_and_call(_form_set_freq2, self._set_status_msg)) - hbox.Add((5,0), 0, 0) - g = self.subdev.gain_range() - myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain", - weight=3, - min=int(g[0]), max=int(g[1]), - callback=self.set_gain) - - hbox.Add((5,0), 0, 0) - vbox.Add(hbox, 0, wx.EXPAND) - - self._build_subpanel(vbox) - - def _build_subpanel(self, vbox_arg): - # build a secondary information panel (sometimes hidden) - - # FIXME figure out how to have this be a subpanel that is always - # created, but has its visibility controlled by foo.Show(True/False) - - def _form_set_decim(kv): - return self.set_decim(kv['decim']) - - if not(self.show_debug_info): - return - - panel = self.panel - vbox = vbox_arg - myform = self.myform - - #panel = wx.Panel(self.panel, -1) - #vbox = wx.BoxSizer(wx.VERTICAL) - - hbox = wx.BoxSizer(wx.HORIZONTAL) - hbox.Add((5,0), 0) - - myform['decim'] = form.int_field( - parent=panel, sizer=hbox, label="Decim", - callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg)) - - hbox.Add((5,0), 1) - myform['fs@usb'] = form.static_float_field( - parent=panel, sizer=hbox, label="Fs@USB") - - hbox.Add((5,0), 1) - myform['dbname'] = form.static_text_field( - parent=panel, sizer=hbox) - - hbox.Add((5,0), 1) - myform['baseband'] = form.static_float_field( - parent=panel, sizer=hbox, label="Analog BB") - - hbox.Add((5,0), 1) - myform['ddc'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC") - if self.num_inputs==2: - hbox.Add((1,0), 1) - myform['baseband2'] = form.static_float_field( - parent=panel, sizer=hbox, label="BB2") - hbox.Add((1,0), 1) - myform['ddc2'] = form.static_float_field( - parent=panel, sizer=hbox, label="DDC2") - - hbox.Add((5,0), 0) - vbox.Add(hbox, 0, wx.EXPAND) - - - def set_freq(self, target_freq): - """ - Set the center frequency we're interested in. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = usrp.tune(self.u, 0, self.subdev, target_freq) - - if r: - self.myform['freq'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband'].set_value(r.baseband_freq) - self.myform['ddc'].set_value(r.dxc_freq) - return True - - return False - - def set_freq2(self, target_freq): - """ - Set the center frequency of we're interested in for the second channel. - - @param target_freq: frequency in Hz - @rypte: bool - - Tuning is a two step process. First we ask the front-end to - tune as close to the desired frequency as it can. Then we use - the result of that operation and our target_frequency to - determine the value for the digital down converter. - """ - r = usrp.tune(self.u, 1, self.subdev, target_freq) - - if r: - self.myform['freq2'].set_value(target_freq) # update displayed value - if self.show_debug_info: - self.myform['baseband2'].set_value(r.baseband_freq) - self.myform['ddc2'].set_value(r.dxc_freq) - return True - - return False - - def set_gain(self, gain): - self.myform['gain'].set_value(gain) # update displayed value - self.subdev.set_gain(gain) - - def set_decim(self, decim): - ok = self.u.set_decim_rate(decim) - if not ok: - print "set_decim failed" - input_rate = self.u.adc_freq() / self.u.decim_rate() - self.scope.set_sample_rate(input_rate) - if self.show_debug_info: # update displayed values - self.myform['decim'].set_value(self.u.decim_rate()) - self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate()) - return ok - -def main (): - app = stdgui2.stdapp(app_top_block, "USRP O'scope", nstatus=1) - app.MainLoop() - -if __name__ == '__main__': - main () diff --git a/gr-utils/src/python/usrp_rx_nogui.py b/gr-utils/src/python/usrp_rx_nogui.py deleted file mode 100755 index a5d792c8b..000000000 --- a/gr-utils/src/python/usrp_rx_nogui.py +++ /dev/null @@ -1,213 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2006,2007 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -from gnuradio import gr, gru, usrp, optfir, audio, eng_notation, blks2 -from gnuradio.eng_option import eng_option -from optparse import OptionParser -import sys - -""" -This example application demonstrates receiving and demodulating -different types of signals using the USRP. - -A receive chain is built up of the following signal processing -blocks: - -USRP - Daughter board source generating complex baseband signal. -CHAN - Low pass filter to select channel bandwidth -RFSQL - RF squelch zeroing output when input power below threshold -AGC - Automatic gain control leveling signal at [-1.0, +1.0] -DEMOD - Demodulation block appropriate to selected signal type. - This converts the complex baseband to real audio frequencies, - and applies an appropriate low pass decimating filter. -CTCSS - Optional tone squelch zeroing output when tone is not present. -RSAMP - Resampler block to convert audio sample rate to user specified - sound card output rate. -AUDIO - Audio sink for playing final output to speakers. - -The following are required command line parameters: - --f FREQ USRP receive frequency --m MOD Modulation type, select from AM, FM, or WFM - -The following are optional command line parameters: - --R SUBDEV Daughter board specification, defaults to first found --c FREQ Calibration offset. Gets added to receive frequency. - Defaults to 0.0 Hz. --g GAIN Daughterboard gain setting. Defaults to mid-range. --o RATE Sound card output rate. Defaults to 32000. Useful if - your sound card only accepts particular sample rates. --r RFSQL RF squelch in db. Defaults to -50.0. --p FREQ CTCSS frequency. Opens squelch when tone is present. - -Once the program is running, ctrl-break (Ctrl-C) stops operation. - -Please see fm_demod.py and am_demod.py for details of the demodulation -blocks. -""" - -# (usrp_decim, channel_decim, audio_decim, channel_pass, channel_stop, demod) -demod_params = { - 'AM' : (250, 16, 1, 5000, 8000, blks2.demod_10k0a3e_cf), - 'FM' : (250, 8, 4, 8000, 9000, blks2.demod_20k0f3e_cf), - 'WFM' : (250, 1, 8, 90000, 100000, blks2.demod_200kf3e_cf) - } - -class usrp_src(gr.hier_block2): - """ - Create a USRP source object supplying complex floats. - - Selects user supplied subdevice or chooses first available one. - - Calibration value is the offset from the tuned frequency to - the actual frequency. - """ - def __init__(self, subdev_spec, decim, gain=None, calibration=0.0): - gr.hier_block2.__init__(self, "usrp_src", - gr.io_signature(0, 0, 0), # Input signature - gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature - - self._decim = decim - self._src = usrp.source_c() - if subdev_spec is None: - subdev_spec = usrp.pick_rx_subdevice(self._src) - self._subdev = usrp.selected_subdev(self._src, subdev_spec) - self._src.set_mux(usrp.determine_rx_mux_value(self._src, subdev_spec)) - self._src.set_decim_rate(self._decim) - - # If no gain specified, set to midrange - if gain is None: - g = self._subdev.gain_range() - gain = (g[0]+g[1])/2.0 - - self._subdev.set_gain(gain) - self._cal = calibration - self.connect(self._src, self) - - def tune(self, freq): - result = usrp.tune(self._src, 0, self._subdev, freq+self._cal) - # TODO: deal with residual - - def rate(self): - return self._src.adc_rate()/self._decim - -class app_top_block(gr.top_block): - def __init__(self, options): - gr.top_block.__init__(self) - self.options = options - - (usrp_decim, channel_decim, audio_decim, - channel_pass, channel_stop, demod) = demod_params[options.modulation] - - USRP = usrp_src(options.rx_subdev_spec, # Daugherboard spec - usrp_decim, # IF decimation ratio - options.gain, # Receiver gain - options.calibration) # Frequency offset - USRP.tune(options.frequency) - - if_rate = USRP.rate() - channel_rate = if_rate // channel_decim - audio_rate = channel_rate // audio_decim - - CHAN_taps = optfir.low_pass(1.0, # Filter gain - if_rate, # Sample rate - channel_pass, # One sided modulation bandwidth - channel_stop, # One sided channel bandwidth - 0.1, # Passband ripple - 60) # Stopband attenuation - - CHAN = gr.freq_xlating_fir_filter_ccf(channel_decim, # Decimation rate - CHAN_taps, # Filter taps - 0.0, # Offset frequency - if_rate) # Sample rate - - RFSQL = gr.pwr_squelch_cc(options.rf_squelch, # Power threshold - 125.0/channel_rate, # Time constant - channel_rate/20, # 50ms rise/fall - False) # Zero, not gate output - - AGC = gr.agc_cc(1.0/channel_rate, # Time constant - 1.0, # Reference power - 1.0, # Initial gain - 1.0) # Maximum gain - - DEMOD = demod(channel_rate, audio_decim) - - # From RF to audio - self.connect(USRP, CHAN, RFSQL, AGC, DEMOD) - - # Optionally add CTCSS and RSAMP if needed - tail = DEMOD - if options.ctcss != None and options.ctcss > 60.0: - CTCSS = gr.ctcss_squelch_ff(audio_rate, # Sample rate - options.ctcss) # Squelch tone - self.connect(DEMOD, CTCSS) - tail = CTCSS - - if options.output_rate != audio_rate: - out_lcm = gru.lcm(audio_rate, options.output_rate) - out_interp = int(out_lcm // audio_rate) - out_decim = int(out_lcm // options.output_rate) - RSAMP = blks2.rational_resampler_fff(out_interp, out_decim) - self.connect(tail, RSAMP) - tail = RSAMP - - # Send to default audio output - AUDIO = audio.sink(options.output_rate, "") - self.connect(tail, AUDIO) - -def main(): - parser = OptionParser(option_class=eng_option) - parser.add_option("-f", "--frequency", type="eng_float", default=None, - help="set receive frequency to Hz", metavar="Hz") - parser.add_option("-R", "--rx-subdev-spec", type="subdev", - help="select USRP Rx side A or B", metavar="SUBDEV") - parser.add_option("-c", "--calibration", type="eng_float", default=0.0, - help="set frequency offset to Hz", metavar="Hz") - parser.add_option("-g", "--gain", type="int", default=None, - help="set RF gain", metavar="dB") - parser.add_option("-m", "--modulation", type="choice", choices=('AM','FM','WFM'), - help="set modulation type (AM,FM)", metavar="TYPE") - parser.add_option("-o", "--output-rate", type="int", default=32000, - help="set audio output rate to RATE", metavar="RATE") - parser.add_option("-r", "--rf-squelch", type="eng_float", default=-50.0, - help="set RF squelch to dB", metavar="dB") - parser.add_option("-p", "--ctcss", type="float", - help="set CTCSS squelch to FREQ", metavar="FREQ") - (options, args) = parser.parse_args() - - if options.frequency is None: - print "Must supply receive frequency with -f" - sys.exit(1) - - if options.frequency < 1e6: - options.frequency *= 1e6 - - tb = app_top_block(options) - try: - tb.run() - except KeyboardInterrupt: - pass - -if __name__ == "__main__": - main() diff --git a/gr-utils/src/python/usrp_siggen.py b/gr-utils/src/python/usrp_siggen.py deleted file mode 100755 index da83da770..000000000 --- a/gr-utils/src/python/usrp_siggen.py +++ /dev/null @@ -1,331 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2008,2009 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -DESC_KEY = 'desc' -SAMP_RATE_KEY = 'samp_rate' -LINK_RATE_KEY = 'link_rate' -DAC_RATE_KEY = 'dac_rate' -INTERP_KEY = 'interp' -GAIN_KEY = 'gain' -TX_FREQ_KEY = 'tx_freq' -DDC_FREQ_KEY = 'ddc_freq' -BB_FREQ_KEY = 'bb_freq' -AMPLITUDE_KEY = 'amplitude' -AMPL_RANGE_KEY = 'ampl_range' -WAVEFORM_FREQ_KEY = 'waveform_freq' -WAVEFORM_OFFSET_KEY = 'waveform_offset' -WAVEFORM2_FREQ_KEY = 'waveform2_freq' -FREQ_RANGE_KEY = 'freq_range' -GAIN_RANGE_KEY = 'gain_range' -TYPE_KEY = 'type' - -def setter(ps, key, val): ps[key] = val - -from gnuradio import gr, eng_notation -from gnuradio.gr.pubsub import pubsub -from gnuradio.eng_option import eng_option -from gnuradio import usrp_options -from optparse import OptionParser -import sys -import math - -n2s = eng_notation.num_to_str - -waveforms = { gr.GR_SIN_WAVE : "Complex Sinusoid", - gr.GR_CONST_WAVE : "Constant", - gr.GR_GAUSSIAN : "Gaussian Noise", - gr.GR_UNIFORM : "Uniform Noise", - "2tone" : "Two Tone", - "sweep" : "Sweep" } - -# -# GUI-unaware GNU Radio flowgraph. This may be used either with command -# line applications or GUI applications. -# -class top_block(gr.top_block, pubsub): - def __init__(self, options, args): - gr.top_block.__init__(self) - pubsub.__init__(self) - self._verbose = options.verbose - #initialize values from options - self._setup_usrpx(options) - self.subscribe(INTERP_KEY, lambda i: setter(self, SAMP_RATE_KEY, self[DAC_RATE_KEY]/i)) - self.subscribe(SAMP_RATE_KEY, lambda e: setter(self, LINK_RATE_KEY, e*32)) - self[INTERP_KEY] = options.interp or 16 - self[TX_FREQ_KEY] = options.tx_freq - self[AMPLITUDE_KEY] = options.amplitude - self[WAVEFORM_FREQ_KEY] = options.waveform_freq - self[WAVEFORM_OFFSET_KEY] = options.offset - self[WAVEFORM2_FREQ_KEY] = options.waveform2_freq - self[BB_FREQ_KEY] = 0 - self[DDC_FREQ_KEY] = 0 - #subscribe set methods - self.subscribe(INTERP_KEY, self.set_interp) - self.subscribe(GAIN_KEY, self.set_gain) - self.subscribe(TX_FREQ_KEY, self.set_freq) - self.subscribe(AMPLITUDE_KEY, self.set_amplitude) - self.subscribe(WAVEFORM_FREQ_KEY, self.set_waveform_freq) - self.subscribe(WAVEFORM2_FREQ_KEY, self.set_waveform2_freq) - self.subscribe(TYPE_KEY, self.set_waveform) - #force update on pubsub keys - for key in (INTERP_KEY, GAIN_KEY, TX_FREQ_KEY, - AMPLITUDE_KEY, WAVEFORM_FREQ_KEY, WAVEFORM_OFFSET_KEY, WAVEFORM2_FREQ_KEY): - self[key] = self[key] - self[TYPE_KEY] = options.type #set type last - - def _setup_usrpx(self, options): - self._u = usrp_options.create_usrp_sink(options) - self.publish(DESC_KEY, lambda: str(self._u)) - self.publish(DAC_RATE_KEY, self._u.dac_rate) - self.publish(FREQ_RANGE_KEY, self._u.freq_range) - self.publish(GAIN_RANGE_KEY, self._u.gain_range) - self.publish(GAIN_KEY, self._u.gain) - if self._verbose: print str(self._u) - - def _set_tx_amplitude(self, ampl): - """ - Sets the transmit amplitude sent to the USRP - @param ampl the amplitude or None for automatic - """ - ampl_range = self[AMPL_RANGE_KEY] - if ampl is None: ampl = (ampl_range[1] - ampl_range[0])*0.15 + ampl_range[0] - self[AMPLITUDE_KEY] = max(ampl_range[0], min(ampl, ampl_range[1])) - - def set_interp(self, interp): - if not self._u.set_interp(interp): - raise RuntimeError("Failed to set interpolation rate %i" % (interp,)) - - if self._verbose: - print "USRP interpolation rate:", interp - print "USRP IF bandwidth: %sHz" % (n2s(self[SAMP_RATE_KEY]),) - - if self[TYPE_KEY] in (gr.GR_SIN_WAVE, gr.GR_CONST_WAVE): - self._src.set_sampling_freq(self[SAMP_RATE_KEY]) - elif self[TYPE_KEY] == "2tone": - self._src1.set_sampling_freq(self[SAMP_RATE_KEY]) - self._src2.set_sampling_freq(self[SAMP_RATE_KEY]) - elif self[TYPE_KEY] == "sweep": - self._src1.set_sampling_freq(self[SAMP_RATE_KEY]) - self._src2.set_sampling_freq(self[WAVEFORM_FREQ_KEY]*2*math.pi/self[SAMP_RATE_KEY]) - else: - return True # Waveform not yet set - - if self._verbose: print "Set interpolation rate to:", interp - return True - - def set_gain(self, gain): - if gain is None: - g = self[GAIN_RANGE_KEY] - gain = float(g[0]+g[1])/2 - if self._verbose: - print "Using auto-calculated mid-point TX gain" - self[GAIN_KEY] = gain - return - self._u.set_gain(gain) - if self._verbose: - print "Set TX gain to:", gain - - def set_freq(self, target_freq): - - if target_freq is None: - f = self[FREQ_RANGE_KEY] - target_freq = float(f[0]+f[1])/2.0 - if self._verbose: - print "Using auto-calculated mid-point frequency" - self[TX_FREQ_KEY] = target_freq - return - - tr = self._u.set_center_freq(target_freq) - fs = "%sHz" % (n2s(target_freq),) - if tr is not None: - self._freq = target_freq - self[DDC_FREQ_KEY] = tr.dxc_freq - self[BB_FREQ_KEY] = tr.baseband_freq - if self._verbose: - print "Set center frequency to", fs - print "Tx baseband frequency: %sHz" % (n2s(tr.baseband_freq),) - print "Tx DDC frequency: %sHz" % (n2s(tr.dxc_freq),) - print "Tx residual frequency: %sHz" % (n2s(tr.residual_freq),) - elif self._verbose: print "Failed to set freq." - return tr - - def set_waveform_freq(self, freq): - if self[TYPE_KEY] == gr.GR_SIN_WAVE: - self._src.set_frequency(freq) - elif self[TYPE_KEY] == "2tone": - self._src1.set_frequency(freq) - elif self[TYPE_KEY] == 'sweep': - #there is no set sensitivity, redo fg - self[TYPE_KEY] = self[TYPE_KEY] - return True - - def set_waveform2_freq(self, freq): - if freq is None: - self[WAVEFORM2_FREQ_KEY] = -self[WAVEFORM_FREQ_KEY] - return - if self[TYPE_KEY] == "2tone": - self._src2.set_frequency(freq) - elif self[TYPE_KEY] == "sweep": - self._src1.set_frequency(freq) - return True - - def set_waveform(self, type): - self.lock() - self.disconnect_all() - if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE: - self._src = gr.sig_source_c(self[SAMP_RATE_KEY], # Sample rate - type, # Waveform type - self[WAVEFORM_FREQ_KEY], # Waveform frequency - self[AMPLITUDE_KEY], # Waveform amplitude - self[WAVEFORM_OFFSET_KEY]) # Waveform offset - elif type == gr.GR_GAUSSIAN or type == gr.GR_UNIFORM: - self._src = gr.noise_source_c(type, self[AMPLITUDE_KEY]) - elif type == "2tone": - self._src1 = gr.sig_source_c(self[SAMP_RATE_KEY], - gr.GR_SIN_WAVE, - self[WAVEFORM_FREQ_KEY], - self[AMPLITUDE_KEY]/2.0, - 0) - if(self[WAVEFORM2_FREQ_KEY] is None): - self[WAVEFORM2_FREQ_KEY] = -self[WAVEFORM_FREQ_KEY] - - self._src2 = gr.sig_source_c(self[SAMP_RATE_KEY], - gr.GR_SIN_WAVE, - self[WAVEFORM2_FREQ_KEY], - self[AMPLITUDE_KEY]/2.0, - 0) - self._src = gr.add_cc() - self.connect(self._src1,(self._src,0)) - self.connect(self._src2,(self._src,1)) - elif type == "sweep": - # rf freq is center frequency - # waveform_freq is total swept width - # waveform2_freq is sweep rate - # will sweep from (rf_freq-waveform_freq/2) to (rf_freq+waveform_freq/2) - if self[WAVEFORM2_FREQ_KEY] is None: - self[WAVEFORM2_FREQ_KEY] = 0.1 - - self._src1 = gr.sig_source_f(self[SAMP_RATE_KEY], - gr.GR_TRI_WAVE, - self[WAVEFORM2_FREQ_KEY], - 1.0, - -0.5) - self._src2 = gr.frequency_modulator_fc(self[WAVEFORM_FREQ_KEY]*2*math.pi/self[SAMP_RATE_KEY]) - self._src = gr.multiply_const_cc(self[AMPLITUDE_KEY]) - self.connect(self._src1,self._src2,self._src) - else: - raise RuntimeError("Unknown waveform type") - - self.connect(self._src, self._u) - self.unlock() - - if self._verbose: - print "Set baseband modulation to:", waveforms[type] - if type == gr.GR_SIN_WAVE: - print "Modulation frequency: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),) - print "Initial phase:", self[WAVEFORM_OFFSET_KEY] - elif type == "2tone": - print "Tone 1: %sHz" % (n2s(self[WAVEFORM_FREQ_KEY]),) - print "Tone 2: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),) - elif type == "sweep": - print "Sweeping across %sHz to %sHz" % (n2s(-self[WAVEFORM_FREQ_KEY]/2.0),n2s(self[WAVEFORM_FREQ_KEY]/2.0)) - print "Sweep rate: %sHz" % (n2s(self[WAVEFORM2_FREQ_KEY]),) - print "TX amplitude:", self[AMPLITUDE_KEY] - - - def set_amplitude(self, amplitude): - if amplitude < 0.0 or amplitude > 1.0: - if self._verbose: print "Amplitude out of range:", amplitude - return False - - if self[TYPE_KEY] in (gr.GR_SIN_WAVE, gr.GR_CONST_WAVE, gr.GR_GAUSSIAN, gr.GR_UNIFORM): - self._src.set_amplitude(amplitude) - elif self[TYPE_KEY] == "2tone": - self._src1.set_amplitude(amplitude/2.0) - self._src2.set_amplitude(amplitude/2.0) - elif self[TYPE_KEY] == "sweep": - self._src.set_k(amplitude) - else: - return True # Waveform not yet set - - if self._verbose: print "Set amplitude to:", amplitude - return True - -def get_options(): - usage="%prog: [options]" - - parser = OptionParser(option_class=eng_option, usage=usage) - usrp_options.add_tx_options(parser) - parser.add_option("-f", "--tx-freq", type="eng_float", default=None, - help="Set carrier frequency to FREQ [default=mid-point]", metavar="FREQ") - parser.add_option("-x", "--waveform-freq", type="eng_float", default=0, - help="Set baseband waveform frequency to FREQ [default=%default]") - parser.add_option("-y", "--waveform2-freq", type="eng_float", default=None, - help="Set 2nd waveform frequency to FREQ [default=%default]") - parser.add_option("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE, - help="Generate a carrier modulated by a complex sine wave", default=gr.GR_SIN_WAVE) - parser.add_option("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, - help="Generate a constant carrier") - parser.add_option("--offset", type="eng_float", default=0, - help="Set waveform phase offset to OFFSET [default=%default]") - parser.add_option("--gaussian", dest="type", action="store_const", const=gr.GR_GAUSSIAN, - help="Generate Gaussian random output") - parser.add_option("--uniform", dest="type", action="store_const", const=gr.GR_UNIFORM, - help="Generate Uniform random output") - parser.add_option("--2tone", dest="type", action="store_const", const="2tone", - help="Generate Two Tone signal for IMD testing") - parser.add_option("--sweep", dest="type", action="store_const", const="sweep", - help="Generate a swept sine wave") - parser.add_option("-A", "--amplitude", type="eng_float", default=0.15, - help="Set output amplitude to AMPL (0.0-1.0) [default=%default]", metavar="AMPL") - parser.add_option("-v", "--verbose", action="store_true", default=False, - help="Use verbose console output [default=%default]") - - (options, args) = parser.parse_args() - - return (options, args) - -# If this script is executed, the following runs. If it is imported, the below does not run. -def main(): - if gr.enable_realtime_scheduling() != gr.RT_OK: - print "Note: failed to enable realtime scheduling, continuing" - - # Grab command line options and create top block - try: - (options, args) = get_options() - tb = top_block(options, args) - - 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() diff --git a/gr-utils/src/python/usrp_siggen_gui.py b/gr-utils/src/python/usrp_siggen_gui.py deleted file mode 100755 index 47d47bdb3..000000000 --- a/gr-utils/src/python/usrp_siggen_gui.py +++ /dev/null @@ -1,317 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2009 Free Software Foundation, Inc. -# -# This file is part of GNU Radio -# -# GNU Radio is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 3, or (at your option) -# any later version. -# -# GNU Radio is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Radio; see the file COPYING. If not, write to -# the Free Software Foundation, Inc., 51 Franklin Street, -# Boston, MA 02110-1301, USA. -# - -import wx -from gnuradio import gr -from gnuradio.gr.pubsub import pubsub -from gnuradio.wxgui import gui, forms -import usrp_siggen -import sys, math - -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(5) - 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(10) - 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(usrp_siggen.TYPE_KEY, set_type) - #create sine forms - sine_bb_hbox.AddSpacer(10) - forms.text_box( - parent=self.panel, sizer=sine_bb_hbox, - label='Frequency (Hz)', - ps=self.tb, - key=usrp_siggen.WAVEFORM_FREQ_KEY, - converter=forms.float_converter(), - ) - sine_bb_hbox.AddStretchSpacer() - #create sweep forms - sweep_bb_hbox.AddSpacer(10) - forms.text_box( - parent=self.panel, sizer=sweep_bb_hbox, - label='Sweep Width (Hz)', - ps=self.tb, - key=usrp_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=usrp_siggen.WAVEFORM2_FREQ_KEY, - converter=forms.float_converter(), - ) - sweep_bb_hbox.AddStretchSpacer() - #create 2tone forms - tone_bb_hbox.AddSpacer(10) - forms.text_box( - parent=self.panel, sizer=tone_bb_hbox, - label='Tone 1 (Hz)', - ps=self.tb, - key=usrp_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=usrp_siggen.WAVEFORM2_FREQ_KEY, - converter=forms.float_converter(), - ) - tone_bb_hbox.AddStretchSpacer() - forms.radio_buttons( - parent=self.panel, sizer=bb_vbox, - choices=usrp_siggen.waveforms.keys(), - labels=usrp_siggen.waveforms.values(), - ps=self.tb, - key=usrp_siggen.TYPE_KEY, - style=wx.NO_BORDER | wx.RA_HORIZONTAL, - ) - bb_vbox.AddSpacer(10) - 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[usrp_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(5) - # First row of frequency controls (center frequency) - freq_hbox = wx.BoxSizer(wx.HORIZONTAL) - fc_vbox.Add(freq_hbox, 0, wx.EXPAND) - fc_vbox.AddSpacer(10) - # Second row of frequency controls (results) - tr_hbox = wx.BoxSizer(wx.HORIZONTAL) - fc_vbox.Add(tr_hbox, 0, wx.EXPAND) - fc_vbox.AddSpacer(5) - # Add frequency controls to top window sizer - self.vbox.Add(fc_vbox, 0, wx.EXPAND) - self.vbox.AddSpacer(10) - self.vbox.AddStretchSpacer() - freq_hbox.AddSpacer(5) - forms.text_box( - parent=self.panel, sizer=freq_hbox, - proportion=1, - converter=forms.float_converter(), - ps=self.tb, - key=usrp_siggen.TX_FREQ_KEY, - ) - freq_hbox.AddSpacer(10) - forms.slider( - parent=self.panel, sizer=freq_hbox, - proportion=2, - ps=self.tb, - key=usrp_siggen.TX_FREQ_KEY, - minimum=self.tb[usrp_siggen.FREQ_RANGE_KEY][0], - maximum=self.tb[usrp_siggen.FREQ_RANGE_KEY][1], - num_steps=100, - ) - freq_hbox.AddSpacer(5) - tr_hbox.AddSpacer(5) - forms.static_text( - parent=self.panel, sizer=tr_hbox, - label='Daughterboard (Hz)', - ps=self.tb, - key=usrp_siggen.BB_FREQ_KEY, - converter=forms.float_converter(), - proportion=1, - ) - tr_hbox.AddSpacer(10) - forms.static_text( - parent=self.panel, sizer=tr_hbox, - label='USRP DDC (Hz)', - ps=self.tb, - key=usrp_siggen.DDC_FREQ_KEY, - converter=forms.float_converter(), - proportion=1, - ) - tr_hbox.AddSpacer(5) - ################################################## - # Amplitude controls - ################################################## - amp_hbox = forms.static_box_sizer(parent=self.panel, label="Amplitude", orient=wx.VERTICAL, bold=True) - amp_hbox.AddSpacer(5) - # First row of amp controls (ampl) - lvl_hbox = wx.BoxSizer(wx.HORIZONTAL) - amp_hbox.Add(lvl_hbox, 0, wx.EXPAND) - amp_hbox.AddSpacer(10) - # Second row of amp controls (tx gain) - gain_hbox = wx.BoxSizer(wx.HORIZONTAL) - amp_hbox.Add(gain_hbox, 0, wx.EXPAND) - amp_hbox.AddSpacer(5) - self.vbox.Add(amp_hbox, 0, wx.EXPAND) - self.vbox.AddSpacer(10) - self.vbox.AddStretchSpacer() - lvl_hbox.AddSpacer(5) - forms.text_box( - parent=self.panel, sizer=lvl_hbox, - proportion=1, - converter=forms.float_converter(), - ps=self.tb, - key=usrp_siggen.AMPLITUDE_KEY, - label="Level (0.0-1.0)", - ) - lvl_hbox.AddSpacer(10) - forms.log_slider( - parent=self.panel, sizer=lvl_hbox, - proportion=2, - ps=self.tb, - key=usrp_siggen.AMPLITUDE_KEY, - min_exp=-6, - max_exp=0, - base=10, - num_steps=100, - ) - lvl_hbox.AddSpacer(5) - if self.tb[usrp_siggen.GAIN_RANGE_KEY][0] < self.tb[usrp_siggen.GAIN_RANGE_KEY][1]: - gain_hbox.AddSpacer(5) - forms.text_box( - parent=self.panel, sizer=gain_hbox, - proportion=1, - converter=forms.float_converter(), - ps=self.tb, - key=usrp_siggen.GAIN_KEY, - label="TX Gain (dB)", - ) - gain_hbox.AddSpacer(10) - forms.slider( - parent=self.panel, sizer=gain_hbox, - proportion=2, - ps=self.tb, - key=usrp_siggen.GAIN_KEY, - minimum=self.tb[usrp_siggen.GAIN_RANGE_KEY][0], - maximum=self.tb[usrp_siggen.GAIN_RANGE_KEY][1], - step_size=self.tb[usrp_siggen.GAIN_RANGE_KEY][2], - ) - gain_hbox.AddSpacer(5) - ################################################## - # 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(10) - self.vbox.AddStretchSpacer() - sam_hbox.AddSpacer(5) - forms.text_box( - parent=self.panel, sizer=sam_hbox, - converter=forms.int_converter(), - ps=self.tb, - key=usrp_siggen.INTERP_KEY, - label="Interpolation", - ) - sam_hbox.AddStretchSpacer(20) - forms.static_text( - parent=self.panel, sizer=sam_hbox, - label='Sample Rate (sps)', - ps=self.tb, - key=usrp_siggen.SAMP_RATE_KEY, - converter=forms.float_converter(), - ) - sam_hbox.AddStretchSpacer(20) - forms.static_text( - parent=self.panel, sizer=sam_hbox, - label='Link Rate (bits/sec)', - ps=self.tb, - key=usrp_siggen.LINK_RATE_KEY, - converter=forms.float_converter(), - ) - sam_hbox.AddSpacer(5) - ################################################## - # USRP status - ################################################## - u2_hbox = forms.static_box_sizer(parent=self.panel, label="USRP Status", orient=wx.HORIZONTAL, bold=True) - self.vbox.Add(u2_hbox, 0, wx.EXPAND) - self.vbox.AddSpacer(10) - self.vbox.AddStretchSpacer() - u2_hbox.AddSpacer(10) - forms.static_text( - parent=self.panel, sizer=u2_hbox, - ps=self.tb, - key=usrp_siggen.DESC_KEY, - converter=forms.str_converter(), - ) - self.vbox.AddSpacer(5) - self.vbox.AddStretchSpacer() - -def main(): - try: - # Get command line parameters - (options, args) = usrp_siggen.get_options() - - # Create the top block using these - tb = usrp_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="USRP 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) - -# 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() |