diff options
author | jcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5> | 2007-09-04 02:43:56 +0000 |
---|---|---|
committer | jcorgan <jcorgan@221aa14e-8319-0410-a670-987f0aec2ac5> | 2007-09-04 02:43:56 +0000 |
commit | 54d6b9281dc233e0b2acf26884073d973b7663de (patch) | |
tree | 15cd1fa40207e68c5035a50fd7d54536831c4599 /gr-utils/src | |
parent | 2c37e57fe4626ac30eb8c042e4d7daf64a0d45f5 (diff) |
Merged r6271:6278 from jcorgan/t182 into trunk. Implements ticket:182.
Created new top-level component, gr-utils, to hold commonly used utility
scripts (originally in gnuradio-examples). These now install into the
system path, allowing their use from wherever.
Reorganization of gnuradio-examples component:
* Commonly used utility scripts moved from python/usrp into gr-utils.
* Examples now install into $(prefix)/share/gnuradio/examples/...
* Channel coding examples moved into gr-trellis/src/examples, now install
from there, only if gr-atsc itself is going to built and installed.
* ATSC example scripts now install into example hierarchy
* Cruft has been moved into 'limbo' in repository, do not get installed
Trunk passes 'make distcheck'.
git-svn-id: http://gnuradio.org/svn/gnuradio/trunk@6279 221aa14e-8319-0410-a670-987f0aec2ac5
Diffstat (limited to 'gr-utils/src')
-rw-r--r-- | gr-utils/src/Makefile.am | 22 | ||||
-rw-r--r-- | gr-utils/src/lib/Makefile.am | 20 | ||||
-rw-r--r-- | gr-utils/src/python/Makefile.am | 35 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_benchmark_usb.py | 106 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_fft.py | 254 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_oscope.py | 252 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_print_db.py | 42 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_rx_cfile.py | 107 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_rx_nogui.py | 186 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_siggen.py | 180 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_test_counting.py | 53 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_test_loop.py | 65 | ||||
-rwxr-xr-x | gr-utils/src/python/usrp_test_loop_lfsr.py | 62 |
13 files changed, 1384 insertions, 0 deletions
diff --git a/gr-utils/src/Makefile.am b/gr-utils/src/Makefile.am new file mode 100644 index 0000000000..7a94121138 --- /dev/null +++ b/gr-utils/src/Makefile.am @@ -0,0 +1,22 @@ +# +# Copyright 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. +# + +SUBDIRS = lib python diff --git a/gr-utils/src/lib/Makefile.am b/gr-utils/src/lib/Makefile.am new file mode 100644 index 0000000000..67f9dad59a --- /dev/null +++ b/gr-utils/src/lib/Makefile.am @@ -0,0 +1,20 @@ +# +# Copyright 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. +# diff --git a/gr-utils/src/python/Makefile.am b/gr-utils/src/python/Makefile.am new file mode 100644 index 0000000000..cb8e9811c9 --- /dev/null +++ b/gr-utils/src/python/Makefile.am @@ -0,0 +1,35 @@ +# +# Copyright 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. +# + +EXTRA_DIST = \ + $(bin_SCRIPTS) + +bin_SCRIPTS = \ + usrp_benchmark_usb.py \ + usrp_fft.py \ + usrp_oscope.py \ + usrp_print_db.py \ + usrp_rx_cfile.py \ + usrp_rx_nogui.py \ + usrp_siggen.py \ + usrp_test_counting.py \ + usrp_test_loop.py \ + usrp_test_loop_lfsr.py diff --git a/gr-utils/src/python/usrp_benchmark_usb.py b/gr-utils/src/python/usrp_benchmark_usb.py new file mode 100755 index 0000000000..fc01514a13 --- /dev/null +++ b/gr-utils/src/python/usrp_benchmark_usb.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python +# +# Copyright 2004,2005 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. +# + +""" +Benchmark the USB/USRP throughput. Finds the maximum full-duplex speed +the USRP/USB combination can sustain without errors. + +This program does not currently give reliable results. Sorry about that... +""" + +from gnuradio import gr +from gnuradio import usrp +from gnuradio import eng_notation + +import sys + +def run_test (usb_throughput, verbose): + # usb_throughput is in bytes/sec. + # + # Returns True or False + + nsec = 1 + stream_length = int (usb_throughput/2 * nsec) # length of stream to examine + + adc_freq = 64e6 + dac_freq = 128e6 + sizeof_sample = 2 * gr.sizeof_short + + usb_throughput_in_samples = usb_throughput / sizeof_sample + + # allocate usb throughput 50/50 between Tx and Rx + + tx_interp = int (dac_freq) / int (usb_throughput_in_samples / 2) + rx_decim = int (adc_freq) / int (usb_throughput_in_samples / 2) + + # print "tx_interp =", tx_interp, "rx_decim =", rx_decim + assert (tx_interp == 2 * rx_decim) + + fg = gr.flow_graph () + + # Build the Tx pipeline + data_src = gr.lfsr_32k_source_s () + src_head = gr.head (gr.sizeof_short, int (stream_length * 2)) + usrp_tx = usrp.sink_s (0, tx_interp) + fg.connect (data_src, src_head, usrp_tx) + + # and the Rx pipeline + usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK) + head = gr.head (gr.sizeof_short, stream_length) + check = gr.check_lfsr_32k_s () + fg.connect (usrp_rx, head, check) + + fg.run () + + ntotal = check.ntotal () + nright = check.nright () + runlength = check.runlength () + + if verbose: + print "usb_throughput =", eng_notation.num_to_str (usb_throughput) + print "ntotal =", ntotal + print "nright =", nright + print "runlength =", runlength + print "delta =", ntotal - runlength + + return runlength >= stream_length - 80000 + +def main (): + verbose = True + best_rate = 0 + usb_rate = [ 2e6, 4e6, 8e6, 16e6, 32e6 ] + #usb_rate = [ 32e6, 32e6, 32e6, 32e6, 32e6 ] + # usb_rate.reverse () + for rate in usb_rate: + sys.stdout.write ("Testing %sB/sec... " % (eng_notation.num_to_str (rate))) + sys.stdout.flush () + ok = run_test (rate, verbose) + if ok: + best_rate = max (best_rate, rate) + sys.stdout.write ("OK\n") + else: + sys.stdout.write ("FAILED\n") + + print "Max USB/USRP throughput = %sB/sec" % (eng_notation.num_to_str (best_rate),) + +if __name__ == '__main__': + main () diff --git a/gr-utils/src/python/usrp_fft.py b/gr-utils/src/python/usrp_fft.py new file mode 100755 index 0000000000..353c89218f --- /dev/null +++ b/gr-utils/src/python/usrp_fft.py @@ -0,0 +1,254 @@ +#!/usr/bin/env python +# +# Copyright 2004,2005 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 stdgui, fftsink, waterfallsink, scopesink, form, slider +from optparse import OptionParser +import wx +import sys + + +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_flow_graph(stdgui.gui_flow_graph): + def __init__(self, frame, panel, vbox, argv): + stdgui.gui_flow_graph.__init__(self) + + 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("-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("-S", "--oscilloscope", action="store_true", default=False, + help="Enable oscilloscope display") + (options, args) = parser.parse_args() + if len(args) != 0: + parser.print_help() + sys.exit(1) + + self.show_debug_info = True + + # build the graph + + 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 = \ + waterfallsink.waterfall_sink_c (self, panel, fft_size=1024, sample_rate=input_rate) + elif options.oscilloscope: + self.scope = scopesink.scope_sink_c(self, panel, sample_rate=input_rate) + else: + self.scope = fftsink.fft_sink_c (self, panel, fft_size=1024, sample_rate=input_rate) + + 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 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 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) + 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 = stdgui.stdapp(app_flow_graph, "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 new file mode 100755 index 0000000000..5d71492816 --- /dev/null +++ b/gr-utils/src/python/usrp_oscope.py @@ -0,0 +1,252 @@ +#!/usr/bin/env python +# +# Copyright 2004,2005,2006 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 stdgui, fftsink, waterfallsink, scopesink, form, slider +from optparse import OptionParser +import wx +import sys + + +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_flow_graph(stdgui.gui_flow_graph): + def __init__(self, frame, panel, vbox, argv): + stdgui.gui_flow_graph.__init__(self) + + 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("-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 + + self.u = usrp.source_c(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() + + self.scope = scopesink.scope_sink_c(self, panel, sample_rate=input_rate, + frame_decim=options.frame_decim, + v_scale=options.v_scale, + t_scale=options.t_scale) + 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 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 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 = 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_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 = stdgui.stdapp(app_flow_graph, "USRP O'scope", nstatus=1) + app.MainLoop() + +if __name__ == '__main__': + main () diff --git a/gr-utils/src/python/usrp_print_db.py b/gr-utils/src/python/usrp_print_db.py new file mode 100755 index 0000000000..b082cb073a --- /dev/null +++ b/gr-utils/src/python/usrp_print_db.py @@ -0,0 +1,42 @@ +#!/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. +# + +#!/usr/bin/env python + +from gnuradio import gr +from gnuradio import usrp +from optparse import OptionParser +from usrpm import usrp_dbid + +u_source = usrp.source_c() +u_sink = usrp.sink_c() + +subdev_Ar = usrp.selected_subdev(u_source, (0,0)) +subdev_Br = usrp.selected_subdev(u_source, (1,0)) +subdev_At = usrp.selected_subdev(u_sink, (0,0)) +subdev_Bt = usrp.selected_subdev(u_sink, (1,0)) + +print "RX d'board %s" % (subdev_Ar.side_and_name(),) +print "RX d'board %s" % (subdev_Br.side_and_name(),) +print "TX d'board %s" % (subdev_At.side_and_name(),) +print "TX d'board %s" % (subdev_Bt.side_and_name(),) + diff --git a/gr-utils/src/python/usrp_rx_cfile.py b/gr-utils/src/python/usrp_rx_cfile.py new file mode 100755 index 0000000000..306e101d35 --- /dev/null +++ b/gr-utils/src/python/usrp_rx_cfile.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python + +""" +Read samples from the USRP and write to file formatted as binary +outputs single precision complex float values or complex short values (interleaved 16 bit signed short integers). + +""" + +from gnuradio import gr, eng_notation +from gnuradio import audio +from gnuradio import usrp +from gnuradio.eng_option import eng_option +from optparse import OptionParser + +class my_graph(gr.flow_graph): + + def __init__(self): + gr.flow_graph.__init__(self) + + usage="%prog: [options] output_filename" + parser = OptionParser(option_class=eng_option, usage=usage) + parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=(0, 0), + help="select USRP Rx side A or B (default=A)") + 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( "-s","--output-shorts", action="store_true", default=False, + help="output interleaved shorts in stead of complex floats") + parser.add_option("-N", "--nsamples", type="eng_float", default=None, + help="number of samples to collect [default=+inf]") + (options, args) = parser.parse_args () + if len(args) != 1: + parser.print_help() + raise SystemExit, 1 + filename = args[0] + + if options.freq is None: + parser.print_help() + sys.stderr.write('You must specify the frequency with -f FREQ\n'); + raise SystemExit, 1 + + # build the graph + if options.no_hb or (options.decim<8): + self.fpga_filename="std_4rx_0tx.rbf" #Min decimation of this firmware is 4. contains 4 Rx paths without halfbands and 0 tx paths. + if options.output_shorts: + self.u = usrp.source_s(decim_rate=options.decim,fpga_filename=self.fpga_filename) + else: + self.u = usrp.source_c(decim_rate=options.decim,fpga_filename=self.fpga_filename) + else: + #standard fpga firmware "std_2rxhb_2tx.rbf" contains 2 Rx paths with halfband filters and 2 tx paths (the default) min decimation 8 + if options.output_shorts: + self.u = usrp.source_s(decim_rate=options.decim) + else: + self.u = usrp.source_c(decim_rate=options.decim) + if options.width_8: + sample_width = 8 + sample_shift = 8 + format = self.u.make_format(sample_width, sample_shift) + r = self.u.set_format(format) + if options.output_shorts: + self.dst = gr.file_sink(gr.sizeof_short, filename) + else: + self.dst = gr.file_sink(gr.sizeof_gr_complex, filename) + if options.nsamples is None: + self.connect(self.u, self.dst) + else: + if options.output_shorts: + self.head = gr.head(gr.sizeof_short, int(options.nsamples)*2) + else: + self.head = gr.head(gr.sizeof_gr_complex, int(options.nsamples)) + self.connect(self.u, self.head, self.dst) + + if options.rx_subdev_spec is None: + options.rx_subdev_spec = usrp.pick_rx_subdevice(self.u) + self.u.set_mux(usrp.determine_rx_mux_value(self.u, options.rx_subdev_spec)) + + # determine the daughterboard subdevice we're using + self.subdev = usrp.selected_subdev(self.u, options.rx_subdev_spec) + print "Using RX d'board %s" % (self.subdev.side_and_name(),) + input_rate = self.u.adc_freq() / self.u.decim_rate() + print "USB sample rate %s" % (eng_notation.num_to_str(input_rate)) + + 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 + + self.subdev.set_gain(options.gain) + + r = self.u.tune(0, self.subdev, options.freq) + if not r: + sys.stderr.write('Failed to set frequency\n') + raise SystemExit, 1 + + +if __name__ == '__main__': + try: + my_graph().run() + except KeyboardInterrupt: + pass diff --git a/gr-utils/src/python/usrp_rx_nogui.py b/gr-utils/src/python/usrp_rx_nogui.py new file mode 100755 index 0000000000..b33d626e28 --- /dev/null +++ b/gr-utils/src/python/usrp_rx_nogui.py @@ -0,0 +1,186 @@ +#!/usr/bin/env python + +from gnuradio import gr, gru, usrp, optfir, audio, eng_notation, blks +from gnuradio.eng_option import eng_option +from optparse import OptionParser + +""" +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, blks.demod_10k0a3e_cf), + 'FM' : (250, 8, 4, 8000, 9000, blks.demod_20k0f3e_cf), + 'WFM' : (250, 1, 8, 90000, 100000, blks.demod_200kf3e_cf) + } + +class usrp_source_c(gr.hier_block): + """ + 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, fg, subdev_spec, decim, gain=None, calibration=0.0): + 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 + gr.hier_block.__init__(self, fg, self._src, self._src) + + 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_flow_graph(gr.flow_graph): + def __init__(self, options, args): + gr.flow_graph.__init__(self) + self.options = options + self.args = args + + (usrp_decim, channel_decim, audio_decim, + channel_pass, channel_stop, demod) = demod_params[options.modulation] + + USRP = usrp_source_c(self, # Flow graph + 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(self, 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 = blks.rational_resampler_fff(self, 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", + 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 < 1e6: + options.frequency *= 1e6 + + fg = app_flow_graph(options, args) + try: + fg.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 new file mode 100755 index 0000000000..7f5285885b --- /dev/null +++ b/gr-utils/src/python/usrp_siggen.py @@ -0,0 +1,180 @@ +#!/usr/bin/env python + +from gnuradio import gr, gru +from gnuradio import usrp +from gnuradio.eng_option import eng_option +from gnuradio import eng_notation +from optparse import OptionParser +import sys + + +class my_graph(gr.flow_graph): + def __init__ (self): + gr.flow_graph.__init__(self) + + # controllable values + self.interp = 64 + self.waveform_type = gr.GR_SIN_WAVE + self.waveform_ampl = 16000 + self.waveform_freq = 100.12345e3 + self.waveform_offset = 0 + self._instantiate_blocks () + self.set_waveform_type (self.waveform_type) + + def usb_freq (self): + return self.u.dac_freq() / self.interp + + def usb_throughput (self): + return self.usb_freq () * 4 + + def set_waveform_type (self, type): + ''' + valid waveform types are: gr.GR_SIN_WAVE, gr.GR_CONST_WAVE, + gr.GR_UNIFORM and gr.GR_GAUSSIAN + ''' + self._configure_graph (type) + self.waveform_type = type + + def set_waveform_ampl (self, ampl): + self.waveform_ampl = ampl + self.siggen.set_amplitude (ampl) + self.noisegen.set_amplitude (ampl) + + def set_waveform_freq (self, freq): + self.waveform_freq = freq + self.siggen.set_frequency (freq) + + def set_waveform_offset (self, offset): + self.waveform_offset = offset + self.siggen.set_offset (offset) + + def set_interpolator (self, interp): + self.interp = interp + self.siggen.set_sampling_freq (self.usb_freq ()) + self.u.set_interp_rate (interp) + + def _instantiate_blocks (self): + self.src = None + self.u = usrp.sink_c (0, self.interp) + + self.siggen = gr.sig_source_c (self.usb_freq (), + gr.GR_SIN_WAVE, + self.waveform_freq, + self.waveform_ampl, + self.waveform_offset) + + self.noisegen = gr.noise_source_c (gr.GR_UNIFORM, + self.waveform_ampl) + + # self.file_sink = gr.file_sink (gr.sizeof_gr_complex, "siggen.dat") + + def _configure_graph (self, type): + was_running = self.is_running () + if was_running: + self.stop () + self.disconnect_all () + if type == gr.GR_SIN_WAVE or type == gr.GR_CONST_WAVE: + self.connect (self.siggen, self.u) + # self.connect (self.siggen, self.file_sink) + self.siggen.set_waveform (type) + self.src = self.siggen + elif type == gr.GR_UNIFORM or type == gr.GR_GAUSSIAN: + self.connect (self.noisegen, self.u) + self.noisegen.set_type (type) + self.src = self.noisegen + else: + raise ValueError, type + if was_running: + self.start () + + 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 up converter. + """ + r = self.u.tune(self.subdev._which, self.subdev, target_freq) + if r: + #print "r.baseband_freq =", eng_notation.num_to_str(r.baseband_freq) + #print "r.dxc_freq =", eng_notation.num_to_str(r.dxc_freq) + #print "r.residual_freq =", eng_notation.num_to_str(r.residual_freq) + #print "r.inverted =", r.inverted + return True + + return False + + + +def main (): + parser = OptionParser (option_class=eng_option) + parser.add_option ("-T", "--tx-subdev-spec", type="subdev", default=(0, 0), + help="select USRP Tx side A or B") + parser.add_option ("-f", "--rf-freq", type="eng_float", default=None, + help="set RF center frequency to FREQ") + parser.add_option ("-i", "--interp", type="int", default=64, + help="set fgpa interpolation rate to INTERP [default=%default]") + + parser.add_option ("--sine", dest="type", action="store_const", const=gr.GR_SIN_WAVE, + help="generate a complex sinusoid [default]", default=gr.GR_SIN_WAVE) + parser.add_option ("--const", dest="type", action="store_const", const=gr.GR_CONST_WAVE, + help="generate a constant output") + 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 ("-w", "--waveform-freq", type="eng_float", default=100e3, + help="set waveform frequency to FREQ [default=%default]") + parser.add_option ("-a", "--amplitude", type="eng_float", default=16e3, + help="set waveform amplitude to AMPLITUDE [default=%default]", metavar="AMPL") + parser.add_option ("-o", "--offset", type="eng_float", default=0, + help="set waveform offset to OFFSET [default=%default]") + (options, args) = parser.parse_args () + + if len(args) != 0: + parser.print_help() + raise SystemExit + + if options.rf_freq is None: + sys.stderr.write("usrp_siggen: must specify RF center frequency with -f RF_FREQ\n") + parser.print_help() + raise SystemExit + + fg = my_graph() + fg.set_interpolator (options.interp) + fg.set_waveform_type (options.type) + fg.set_waveform_freq (options.waveform_freq) + fg.set_waveform_ampl (options.amplitude) + fg.set_waveform_offset (options.offset) + + # determine the daughterboard subdevice we're using + if options.tx_subdev_spec is None: + options.tx_subdev_spec = usrp.pick_tx_subdevice(fg.u) + + m = usrp.determine_tx_mux_value(fg.u, options.tx_subdev_spec) + #print "mux = %#04x" % (m,) + fg.u.set_mux(m) + fg.subdev = usrp.selected_subdev(fg.u, options.tx_subdev_spec) + print "Using TX d'board %s" % (fg.subdev.side_and_name(),) + + fg.subdev.set_gain(fg.subdev.gain_range()[1]) # set max Tx gain + + if not fg.set_freq(options.rf_freq): + sys.stderr.write('Failed to set RF frequency\n') + raise SystemExit + + fg.subdev.set_enable(True) # enable transmitter + + try: + fg.run() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main () diff --git a/gr-utils/src/python/usrp_test_counting.py b/gr-utils/src/python/usrp_test_counting.py new file mode 100755 index 0000000000..ccfa948c61 --- /dev/null +++ b/gr-utils/src/python/usrp_test_counting.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python +# +# Copyright 2004 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. +# + +""" +Check Rx path or USRP Rev 1. + +This configures the USRP to return a periodic sequence of integers +""" + +from gnuradio import gr +from gnuradio import usrp + +def build_graph (): + rx_decim = 32 + + fg = gr.flow_graph () + usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_COUNTING) + sink = gr.check_counting_s () + fg.connect (usrp_rx, sink) + + # file_sink = gr.file_sink (gr.sizeof_short, 'counting.dat') + # fg.connect (usrp_rx, file_sink) + + return fg + +def main (): + fg = build_graph () + try: + fg.run() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main () diff --git a/gr-utils/src/python/usrp_test_loop.py b/gr-utils/src/python/usrp_test_loop.py new file mode 100755 index 0000000000..51a705a057 --- /dev/null +++ b/gr-utils/src/python/usrp_test_loop.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python +# +# Copyright 2004 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. +# + +""" +Digital loopback (Tx to Rx) for the USRP Rev1. +""" + + +from gnuradio import gr +from gnuradio import usrp + + +def ramp_source (fg): + period = 2**16 + src = gr.vector_source_s (range (-period/2, period/2, 1), True) + return src + +def build_graph (): + tx_interp = 32 # tx should be twice rx + rx_decim = 16 + + fg = gr.flow_graph () + + data_src = ramp_source (fg) + # usrp_tx = usrp.sink_s (0, tx_interp, 1, 0x98) + usrp_tx = usrp.sink_s (0, tx_interp) + fg.connect (data_src, usrp_tx) + + usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK) + sink = gr.check_counting_s () + fg.connect (usrp_rx, sink) + + # file_sink = gr.file_sink (gr.sizeof_short, "loopback.dat") + # fg.connect (usrp_rx, file_sink) + + return fg + +def main (): + fg = build_graph () + try: + fg.run() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main () diff --git a/gr-utils/src/python/usrp_test_loop_lfsr.py b/gr-utils/src/python/usrp_test_loop_lfsr.py new file mode 100755 index 0000000000..446ca30a16 --- /dev/null +++ b/gr-utils/src/python/usrp_test_loop_lfsr.py @@ -0,0 +1,62 @@ +#!/usr/bin/env python +# +# Copyright 2004 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. +# + +""" +Digital loopback (Tx to Rx) for the USRP Rev1. +""" + +from gnuradio import gr +from gnuradio import usrp + + +def build_graph (): + tx_interp = 32 # tx should be twice rx + rx_decim = 16 + + fg = gr.flow_graph () + + data_src = gr.lfsr_32k_source_s () + + # usrp_tx = usrp.sink_s (0, tx_interp, 1, 0x98) + usrp_tx = usrp.sink_s (0, tx_interp) + + fg.connect (data_src, usrp_tx) + + usrp_rx = usrp.source_s (0, rx_decim, 1, 0x32103210, usrp.FPGA_MODE_LOOPBACK) + + sink = gr.check_lfsr_32k_s () + fg.connect (usrp_rx, sink) + + # file_sink = gr.file_sink (gr.sizeof_short, "loopback.dat") + # fg.connect (usrp_rx, file_sink) + + return fg + +def main (): + fg = build_graph () + try: + fg.run() + except KeyboardInterrupt: + pass + +if __name__ == '__main__': + main () |