diff options
Diffstat (limited to 'gnuradio-examples/python')
-rwxr-xr-x | gnuradio-examples/python/digital/benchmark_loopback.py | 5 | ||||
-rwxr-xr-x | gnuradio-examples/python/digital/benchmark_qt_loopback2.py | 37 | ||||
-rwxr-xr-x | gnuradio-examples/python/digital/benchmark_qt_rx2.py | 23 | ||||
-rwxr-xr-x | gnuradio-examples/python/digital/benchmark_rx2.py | 114 | ||||
-rwxr-xr-x | gnuradio-examples/python/digital/benchmark_tx2.py | 135 | ||||
-rw-r--r-- | gnuradio-examples/python/digital/pick_bitrate2.py | 154 | ||||
-rw-r--r-- | gnuradio-examples/python/digital/receive_path.py | 4 | ||||
-rw-r--r-- | gnuradio-examples/python/digital/transmit_path.py | 4 | ||||
-rw-r--r-- | gnuradio-examples/python/digital/usrp_receive_path.py | 30 | ||||
-rw-r--r-- | gnuradio-examples/python/digital/usrp_receive_path2.py | 96 | ||||
-rw-r--r-- | gnuradio-examples/python/digital/usrp_transmit_path.py | 32 | ||||
-rw-r--r-- | gnuradio-examples/python/digital/usrp_transmit_path2.py | 101 |
12 files changed, 683 insertions, 52 deletions
diff --git a/gnuradio-examples/python/digital/benchmark_loopback.py b/gnuradio-examples/python/digital/benchmark_loopback.py index 4cc4a7bee..47e4f2028 100755 --- a/gnuradio-examples/python/digital/benchmark_loopback.py +++ b/gnuradio-examples/python/digital/benchmark_loopback.py @@ -44,6 +44,11 @@ class my_top_block(gr.top_block): noise_power = power_in_signal/SNR noise_voltage = math.sqrt(noise_power) + # With new interface, sps does not get set by default, but + # in the loopback, we don't recalculate it; so just force it here + if(options.samples_per_symbol == None): + options.samples_per_symbol = 2 + self.txpath = transmit_path(mod_class, options) self.throttle = gr.throttle(gr.sizeof_gr_complex, options.sample_rate) self.rxpath = receive_path(demod_class, rx_callback, options) diff --git a/gnuradio-examples/python/digital/benchmark_qt_loopback2.py b/gnuradio-examples/python/digital/benchmark_qt_loopback2.py index 1cb95198e..56c6c7f52 100755 --- a/gnuradio-examples/python/digital/benchmark_qt_loopback2.py +++ b/gnuradio-examples/python/digital/benchmark_qt_loopback2.py @@ -1,6 +1,26 @@ #!/usr/bin/env python - -from gnuradio import gr, gru, modulation_utils +# +# Copyright 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, modulation_utils2 from gnuradio import eng_notation from gnuradio.eng_option import eng_option from optparse import OptionParser @@ -223,6 +243,11 @@ class my_top_block(gr.top_block): self._noise_voltage = self.get_noise_voltage(self._snr_dB) + # With new interface, sps does not get set by default, but + # in the loopback, we don't recalculate it; so just force it here + if(options.samples_per_symbol == None): + options.samples_per_symbol = 2 + self.txpath = transmit_path(mod_class, options) self.throttle = gr.throttle(gr.sizeof_gr_complex, self.sample_rate()) self.rxpath = receive_path(demod_class, rx_callback, options) @@ -269,6 +294,7 @@ class my_top_block(gr.top_block): self.phase_recov = self.rxpath.packet_receiver._demodulator.phase_recov self.time_recov = self.rxpath.packet_receiver._demodulator.time_recov self.freq_recov.set_alpha(self._gain_freq) + self.freq_recov.set_beta(self._gain_freq/10.0) self.phase_recov.set_alpha(self._gain_phase) self.phase_recov.set_beta(0.25*self._gain_phase*self._gain_phase) self.time_recov.set_alpha(self._gain_clock) @@ -367,6 +393,7 @@ class my_top_block(gr.top_block): self._gain_freq = gain_freq #self._gain_freq_beta = .25 * self._gain_freq * self._gain_freq self.rxpath.packet_receiver._demodulator.freq_recov.set_alpha(self._gain_freq) + self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_freq/10.0) #self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_fre_beta) @@ -431,15 +458,15 @@ def main(): def send_pkt(payload='', eof=False): return tb.txpath.send_pkt(payload, eof) - mods = modulation_utils.type_1_mods() - demods = modulation_utils.type_1_demods() + mods = modulation_utils2.type_1_mods() + demods = modulation_utils2.type_1_demods() parser = OptionParser(option_class=eng_option, conflict_handler="resolve") expert_grp = parser.add_option_group("Expert") channel_grp = parser.add_option_group("Channel") parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), - default='dbpsk', + default='dbpsk2', help="Select modulation from: %s [default=%%default]" % (', '.join(mods.keys()),)) diff --git a/gnuradio-examples/python/digital/benchmark_qt_rx2.py b/gnuradio-examples/python/digital/benchmark_qt_rx2.py index cabbecb6f..0c37f4c6a 100755 --- a/gnuradio-examples/python/digital/benchmark_qt_rx2.py +++ b/gnuradio-examples/python/digital/benchmark_qt_rx2.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright 2005,2006,2007,2009 Free Software Foundation, Inc. +# Copyright 2010 Free Software Foundation, Inc. # # This file is part of GNU Radio # @@ -20,7 +20,7 @@ # Boston, MA 02110-1301, USA. # -from gnuradio import gr, gru, modulation_utils +from gnuradio import gr, gru, modulation_utils2 from gnuradio import usrp from gnuradio import eng_notation from gnuradio.eng_option import eng_option @@ -33,7 +33,7 @@ import sys # from current dir from receive_path import receive_path -from pick_bitrate import pick_rx_bitrate +from pick_bitrate2 import pick_rx_bitrate try: from gnuradio.qtgui import qtgui @@ -219,7 +219,7 @@ class my_top_block(gr.top_block): # FIXME: do better exposure to lower issues for control self._gain_clock = self.rxpath.packet_receiver._demodulator._timing_alpha - self._gain_phase = self.rxpath.packet_receiver._demodulator._costas_alpha + self._gain_phase = self.rxpath.packet_receiver._demodulator._phase_alpha self._gain_freq = self.rxpath.packet_receiver._demodulator._freq_alpha self.connect(self.u, self.rxpath) @@ -242,8 +242,8 @@ class my_top_block(gr.top_block): # Connect to the QT sinks # FIXME: make better exposure to receiver from rxpath - #self.receiver = self.rxpath.packet_receiver._demodulator.phase_recov - self.receiver = self.rxpath.packet_receiver._demodulator.freq_recov + self.receiver = self.rxpath.packet_receiver._demodulator.phase_recov + #self.receiver = self.rxpath.packet_receiver._demodulator.freq_recov self.connect(self.u, self.snk_rxin) self.connect(self.receiver, self.snk_rx) @@ -267,9 +267,9 @@ class my_top_block(gr.top_block): self.u.set_decim(self._decim) (self._bitrate, self._samples_per_symbol, self._decim) = \ - pick_rx_bitrate(self._bitrate, self._demod_class.bits_per_symbol(), \ - self._samples_per_symbol, self._decim, adc_rate, \ - self.u.get_decim_rates()) + pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \ + options.samples_per_symbol, options.decim, \ + adc_rate, self.u.get_decim_rates()) self.u.set_decim(self._decim) self.set_auto_tr(True) # enable Auto Transmit/Receive switching @@ -353,6 +353,7 @@ class my_top_block(gr.top_block): self._gain_freq = gain_freq #self._gain_freq_beta = .25 * self._gain_freq * self._gain_freq self.rxpath.packet_receiver._demodulator.freq_recov.set_alpha(self._gain_freq) + self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_freq/10.0) #self.rxpath.packet_receiver._demodulator.freq_recov.set_beta(self._gain_fre_beta) @@ -423,14 +424,14 @@ def main(): ok, pktno, n_rcvd, n_right) - demods = modulation_utils.type_1_demods() + demods = modulation_utils2.type_1_demods() # Create Options Parser: parser = OptionParser (option_class=eng_option, conflict_handler="resolve") expert_grp = parser.add_option_group("Expert") parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(), - default='dbpsk', + default='dbpsk2', help="Select modulation from: %s [default=%%default]" % (', '.join(demods.keys()),)) diff --git a/gnuradio-examples/python/digital/benchmark_rx2.py b/gnuradio-examples/python/digital/benchmark_rx2.py new file mode 100755 index 000000000..fe422be83 --- /dev/null +++ b/gnuradio-examples/python/digital/benchmark_rx2.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +# +# Copyright 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, modulation_utils2 +from gnuradio import usrp +from gnuradio import eng_notation +from gnuradio.eng_option import eng_option +from optparse import OptionParser + +import random +import struct +import sys + +# from current dir +import usrp_receive_path2 + +#import os +#print os.getpid() +#raw_input('Attach and press enter: ') + +class my_top_block(gr.top_block): + def __init__(self, demodulator, rx_callback, options): + gr.top_block.__init__(self) + + # Set up receive path + self.rxpath = usrp_receive_path2.usrp_receive_path(demodulator, rx_callback, options) + + self.connect(self.rxpath) + +# ///////////////////////////////////////////////////////////////////////////// +# main +# ///////////////////////////////////////////////////////////////////////////// + +global n_rcvd, n_right + +def main(): + global n_rcvd, n_right + + n_rcvd = 0 + n_right = 0 + + def rx_callback(ok, payload): + global n_rcvd, n_right + (pktno,) = struct.unpack('!H', payload[0:2]) + n_rcvd += 1 + if ok: + n_right += 1 + + print "ok = %5s pktno = %4d n_rcvd = %4d n_right = %4d" % ( + ok, pktno, n_rcvd, n_right) + + + demods = modulation_utils2.type_1_demods() + + # Create Options Parser: + parser = OptionParser (option_class=eng_option, conflict_handler="resolve") + expert_grp = parser.add_option_group("Expert") + + parser.add_option("-m", "--modulation", type="choice", choices=demods.keys(), + default='dbpsk2', + help="Select modulation from: %s [default=%%default]" + % (', '.join(demods.keys()),)) + + usrp_receive_path2.add_options(parser, expert_grp) + + for mod in demods.values(): + mod.add_options(expert_grp) + + (options, args) = parser.parse_args () + + if len(args) != 0: + parser.print_help(sys.stderr) + sys.exit(1) + + if options.rx_freq is None: + sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") + parser.print_help(sys.stderr) + sys.exit(1) + + + # build the graph + tb = my_top_block(demods[options.modulation], rx_callback, options) + + r = gr.enable_realtime_scheduling() + if r != gr.RT_OK: + print "Warning: Failed to enable realtime scheduling." + + tb.start() # start flow graph + tb.wait() # wait for it to finish + +if __name__ == '__main__': + try: + main() + except KeyboardInterrupt: + pass diff --git a/gnuradio-examples/python/digital/benchmark_tx2.py b/gnuradio-examples/python/digital/benchmark_tx2.py new file mode 100755 index 000000000..6093dba61 --- /dev/null +++ b/gnuradio-examples/python/digital/benchmark_tx2.py @@ -0,0 +1,135 @@ +#!/usr/bin/env python +# +# Copyright 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, modulation_utils2 +from gnuradio import usrp +from gnuradio import eng_notation +from gnuradio.eng_option import eng_option +from optparse import OptionParser + +import random, time, struct, sys + +# from current dir +import usrp_transmit_path2 + +#import os +#print os.getpid() +#raw_input('Attach and press enter') + +class my_top_block(gr.top_block): + def __init__(self, modulator, options): + gr.top_block.__init__(self) + + self.txpath = usrp_transmit_path2.usrp_transmit_path(modulator, options) + + self.connect(self.txpath) + +# ///////////////////////////////////////////////////////////////////////////// +# main +# ///////////////////////////////////////////////////////////////////////////// + +def main(): + + def send_pkt(payload='', eof=False): + return tb.txpath.send_pkt(payload, eof) + + def rx_callback(ok, payload): + print "ok = %r, payload = '%s'" % (ok, payload) + + mods = modulation_utils2.type_1_mods() + + parser = OptionParser(option_class=eng_option, conflict_handler="resolve") + expert_grp = parser.add_option_group("Expert") + + parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(), + default='dbpsk2', + help="Select modulation from: %s [default=%%default]" + % (', '.join(mods.keys()),)) + + parser.add_option("-s", "--size", type="eng_float", default=1500, + help="set packet size [default=%default]") + parser.add_option("-M", "--megabytes", type="eng_float", default=1.0, + help="set megabytes to transmit [default=%default]") + parser.add_option("","--discontinuous", action="store_true", default=False, + help="enable discontinous transmission (bursts of 5 packets)") + parser.add_option("","--from-file", default=None, + help="use file for packet contents") + + usrp_transmit_path2.add_options(parser, expert_grp) + + for mod in mods.values(): + mod.add_options(expert_grp) + + (options, args) = parser.parse_args () + + if len(args) != 0: + parser.print_help() + sys.exit(1) + + if options.tx_freq is None: + sys.stderr.write("You must specify -f FREQ or --freq FREQ\n") + parser.print_help(sys.stderr) + sys.exit(1) + + if options.from_file is not None: + source_file = open(options.from_file, 'r') + + # build the graph + tb = my_top_block(mods[options.modulation], options) + + r = gr.enable_realtime_scheduling() + if r != gr.RT_OK: + print "Warning: failed to enable realtime scheduling" + + tb.start() # start flow graph + + # generate and send packets + nbytes = int(1e6 * options.megabytes) + n = 0 + pktno = 0 + pkt_size = int(options.size) + + while n < nbytes: + if options.from_file is None: + data = (pkt_size - 2) * chr(pktno & 0xff) + else: + data = source_file.read(pkt_size - 2) + if data == '': + break; + + payload = struct.pack('!H', pktno & 0xffff) + data + send_pkt(payload) + n += len(payload) + sys.stderr.write('.') + if options.discontinuous and pktno % 5 == 4: + time.sleep(1) + pktno += 1 + + send_pkt(eof=True) + + tb.wait() # wait for it to finish + +if __name__ == '__main__': + try: + main() + except KeyboardInterrupt: + pass diff --git a/gnuradio-examples/python/digital/pick_bitrate2.py b/gnuradio-examples/python/digital/pick_bitrate2.py new file mode 100644 index 000000000..92539560c --- /dev/null +++ b/gnuradio-examples/python/digital/pick_bitrate2.py @@ -0,0 +1,154 @@ +# +# Copyright 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 eng_notation + +_default_bitrate = 500e3 +_sps_min = 2 +_sps_max = 100 + +def _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, + xrate, converter_rate, xrates): + """ + @returns tuple (bitrate, samples_per_symbol, interp_rate_or_decim_rate) + """ + + if not isinstance(bits_per_symbol, int) or bits_per_symbol < 1: + raise ValueError, "bits_per_symbol must be an int >= 1" + + converter_rate = float(converter_rate) + bits_per_symbol = float(bits_per_symbol) + + # completely determined; if bitrate is specified, this overwrites it + if (samples_per_symbol is not None) and (xrate is not None): + bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol + + # If only SPS is given + if (bitrate is None) and (samples_per_symbol is not None) and (xrate is None): + xrate = max(xrates) + bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol + + # If only xrate is given, just set SPS to 2 and calculate bitrate + if (bitrate is None) and (samples_per_symbol is None) and (xrate is not None): + samples_per_symbol = 2.0 + bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol + + # If no parameters are give, use the default bit rate + if (bitrate is None) and (samples_per_symbol is None) and (xrate is None): + bitrate = _default_bitrate + + # If only bitrate is specified, return max xrate and appropriate + # samples per symbol (minimum of 2.0) to reach bit rate + if (samples_per_symbol is None) and (xrate is None): + xrates.sort() + for i in xrange(len(xrates)): + if((converter_rate / bits_per_symbol / xrates[i]) >= 2*bitrate): + rate = xrates[i] + else: + break + + try: + xrate = rate + except UnboundLocalError: + raise ValueError("Requested bitrate out of bounds") + + samples_per_symbol = converter_rate / bits_per_symbol / rate / bitrate + bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol + + # If bitrate and xrate are specified + if(samples_per_symbol is None): + samples_per_symbol = converter_rate / xrate / bits_per_symbol / bitrate + + # If bitrate and SPS are specified + if(xrate is None): + xrate = converter_rate / samples_per_symbol / bits_per_symbol / bitrate + if((xrate in xrates) == False): + # Find the closest avaiable rate larger than the calculated one + xrates.sort() + for x in xrates: + if(x > xrate): + xrate = x + break + if(xrate > max(xrates)): + xrate = max(xrates) + + bitrate = converter_rate / bits_per_symbol / xrate / samples_per_symbol + print "Could not find suitable rate for specified SPS and Bitrate" + print "Using rate = %d for bitrate of %sbps" % \ + (xrate, (eng_notation.num_to_str(bitrate))) + + if((xrate in xrates) == False): + raise ValueError(("Invalid rate (rate = %d)" % xrate)) + if((samples_per_symbol < _sps_min) or (samples_per_symbol > _sps_max)): + raise ValueError(("Invalid samples per symbol (sps = %.2f). Must be in [%.0f, %.0f]." \ + % (samples_per_symbol, _sps_min, _sps_max))) + + return (bitrate, samples_per_symbol, int(xrate)) + + +def pick_tx_bitrate(bitrate, bits_per_symbol, samples_per_symbol, + interp_rate, converter_rate, possible_interps): + """ + Given the 4 input parameters, return at configuration that matches + + @param bitrate: desired bitrate or None + @type bitrate: number or None + @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3 + @type bits_per_symbol: integer >= 1 + @param samples_per_symbol: samples/baud (aka samples/symbol) + @type samples_per_symbol: number or None + @param interp_rate: USRP interpolation factor + @type interp_rate: integer or None + @param converter_rate: converter sample rate in Hz + @type converter_rate: number + @param possible_interps: a list of possible rates + @type possible_interps: a list of integers + + @returns tuple (bitrate, samples_per_symbol, interp_rate) + """ + + return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, + interp_rate, converter_rate, possible_interps) + + +def pick_rx_bitrate(bitrate, bits_per_symbol, samples_per_symbol, + decim_rate, converter_rate, possible_decims): + """ + Given the 4 input parameters, return at configuration that matches + + @param bitrate: desired bitrate or None + @type bitrate: number or None + @param bits_per_symbol: E.g., BPSK -> 1, QPSK -> 2, 8-PSK -> 3 + @type bits_per_symbol: integer >= 1 + @param samples_per_symbol: samples/baud (aka samples/symbol) + @type samples_per_symbol: number or None + @param decim_rate: USRP decimation factor + @type decim_rate: integer or None + @param converter_rate: converter sample rate in Hz + @type converter_rate: number + @param possible_decims: a list of possible rates + @type possible_decims: a list of integers + + @returns tuple (bitrate, samples_per_symbol, decim_rate) + """ + + return _pick_bitrate(bitrate, bits_per_symbol, samples_per_symbol, + decim_rate, converter_rate, possible_decims) diff --git a/gnuradio-examples/python/digital/receive_path.py b/gnuradio-examples/python/digital/receive_path.py index c229aa9e4..0024d6941 100644 --- a/gnuradio-examples/python/digital/receive_path.py +++ b/gnuradio-examples/python/digital/receive_path.py @@ -119,7 +119,7 @@ class receive_path(gr.hier_block2): normal.add_option("-r", "--bitrate", type="eng_float", default=100e3, help="specify bitrate [default=%default].") normal.add_option("-v", "--verbose", action="store_true", default=False) - expert.add_option("-S", "--samples-per-symbol", type="int", default=2, + expert.add_option("-S", "--samples-per-symbol", type="float", default=None, help="set samples/symbol [default=%default]") expert.add_option("", "--log", action="store_true", default=False, help="Log all parts of flow graph to files (CAUTION: lots of data)") @@ -135,4 +135,4 @@ class receive_path(gr.hier_block2): print "\nReceive Path:" print "modulation: %s" % (self._demod_class.__name__) print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate)) - print "samples/symbol: %3d" % (self._samples_per_symbol) + print "samples/symbol: %.4f" % (self._samples_per_symbol) diff --git a/gnuradio-examples/python/digital/transmit_path.py b/gnuradio-examples/python/digital/transmit_path.py index 9badcdc08..86ebf75c3 100644 --- a/gnuradio-examples/python/digital/transmit_path.py +++ b/gnuradio-examples/python/digital/transmit_path.py @@ -99,7 +99,7 @@ class transmit_path(gr.hier_block2): help="set transmitter digital amplitude: 0 <= AMPL < 1 [default=%default]") normal.add_option("-v", "--verbose", action="store_true", default=False) - expert.add_option("-S", "--samples-per-symbol", type="int", default=2, + expert.add_option("-S", "--samples-per-symbol", type="float", default=None, help="set samples/symbol [default=%default]") expert.add_option("", "--log", action="store_true", default=False, help="Log all parts of flow graph to file (CAUTION: lots of data)") @@ -114,5 +114,5 @@ class transmit_path(gr.hier_block2): print "Tx amplitude %s" % (self._tx_amplitude) print "modulation: %s" % (self._modulator_class.__name__) print "bitrate: %sb/s" % (eng_notation.num_to_str(self._bitrate)) - print "samples/symbol: %3d" % (self._samples_per_symbol) + print "samples/symbol: %.4f" % (self._samples_per_symbol) diff --git a/gnuradio-examples/python/digital/usrp_receive_path.py b/gnuradio-examples/python/digital/usrp_receive_path.py index 517825cc1..a8f16e28a 100644 --- a/gnuradio-examples/python/digital/usrp_receive_path.py +++ b/gnuradio-examples/python/digital/usrp_receive_path.py @@ -59,37 +59,35 @@ class usrp_receive_path(gr.hier_block2): if options.rx_freq is None: sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n") raise SystemExit - rx_path = receive_path.receive_path(demod_class, rx_callback, options) - for attr in dir(rx_path): #forward the methods - if not attr.startswith('_') and not hasattr(self, attr): - setattr(self, attr, getattr(rx_path, attr)) #setup usrp self._demod_class = demod_class self._setup_usrp_source(options) - # Set up resampler based on rate determined by _setup_usrp_source - rs_taps = gr.firdes.low_pass_2(32, 32, 0.45, 0.1, 60) - self.resampler = gr.pfb_arb_resampler_ccf(self.rs_rate, rs_taps) + rx_path = receive_path.receive_path(demod_class, rx_callback, options) + for attr in dir(rx_path): #forward the methods + if not attr.startswith('_') and not hasattr(self, attr): + setattr(self, attr, getattr(rx_path, attr)) #connect - self.connect(self.u, self.resampler, rx_path) + self.connect(self.u, rx_path) def _setup_usrp_source(self, options): self.u = usrp_options.create_usrp_source(options) adc_rate = self.u.adc_rate() self.rs_rate = options.bitrate - if options.verbose: - print 'USRP Source:', self.u + (self._bitrate, self._samples_per_symbol, self._decim) = \ pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \ - options.samples_per_symbol, options.decim, adc_rate, \ - self.u.get_decim_rates()) + options.samples_per_symbol, options.decim, + adc_rate, self.u.get_decim_rates()) - # Calculate resampler rate based on requested and actual rates - self.rs_rate = 1.0 /(self._bitrate / self.rs_rate) - - print "Resampling by %f to get bitrate of %ssps" % ( self.rs_rate, eng_notation.num_to_str(self._bitrate/self.rs_rate)) + if options.verbose: + print 'USRP Source:', self.u + print 'Decimation: ', self._decim + + options.samples_per_symbol = self._samples_per_symbol + options.decim = self._decim self.u.set_decim(self._decim) diff --git a/gnuradio-examples/python/digital/usrp_receive_path2.py b/gnuradio-examples/python/digital/usrp_receive_path2.py new file mode 100644 index 000000000..d20017204 --- /dev/null +++ b/gnuradio-examples/python/digital/usrp_receive_path2.py @@ -0,0 +1,96 @@ +# +# Copyright 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 +from gnuradio import usrp_options +import receive_path +from pick_bitrate2 import pick_rx_bitrate +from gnuradio import eng_notation + +def add_freq_option(parser): + """ + Hackery that has the -f / --freq option set both tx_freq and rx_freq + """ + def freq_callback(option, opt_str, value, parser): + parser.values.rx_freq = value + parser.values.tx_freq = value + + if not parser.has_option('--freq'): + parser.add_option('-f', '--freq', type="eng_float", + action="callback", callback=freq_callback, + help="set Tx and/or Rx frequency to FREQ [default=%default]", + metavar="FREQ") + +def add_options(parser, expert): + add_freq_option(parser) + usrp_options.add_rx_options(parser) + receive_path.receive_path.add_options(parser, expert) + expert.add_option("", "--rx-freq", type="eng_float", default=None, + help="set Rx frequency to FREQ [default=%default]", metavar="FREQ") + parser.add_option("-v", "--verbose", action="store_true", default=False) + +class usrp_receive_path(gr.hier_block2): + + def __init__(self, demod_class, rx_callback, options): + ''' + See below for what options should hold + ''' + gr.hier_block2.__init__(self, "usrp_receive_path", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(0, 0, 0)) # Output signature + if options.rx_freq is None: + sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n") + raise SystemExit + + #setup usrp + self._demod_class = demod_class + self._setup_usrp_source(options) + + rx_path = receive_path.receive_path(demod_class, rx_callback, options) + for attr in dir(rx_path): #forward the methods + if not attr.startswith('_') and not hasattr(self, attr): + setattr(self, attr, getattr(rx_path, attr)) + + #connect + self.connect(self.u, rx_path) + + def _setup_usrp_source(self, options): + self.u = usrp_options.create_usrp_source(options) + adc_rate = self.u.adc_rate() + self.rs_rate = options.bitrate + + (self._bitrate, self._samples_per_symbol, self._decim) = \ + pick_rx_bitrate(options.bitrate, self._demod_class.bits_per_symbol(), \ + options.samples_per_symbol, options.decim, + adc_rate, self.u.get_decim_rates()) + + if options.verbose: + print 'USRP Source:', self.u + print 'Decimation: ', self._decim + + options.samples_per_symbol = self._samples_per_symbol + options.decim = self._decim + + self.u.set_decim(self._decim) + + if not self.u.set_center_freq(options.rx_freq): + print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.rx_freq)) + raise ValueError, eng_notation.num_to_str(options.rx_freq) diff --git a/gnuradio-examples/python/digital/usrp_transmit_path.py b/gnuradio-examples/python/digital/usrp_transmit_path.py index ee63dcd2b..f0f467599 100644 --- a/gnuradio-examples/python/digital/usrp_transmit_path.py +++ b/gnuradio-examples/python/digital/usrp_transmit_path.py @@ -58,21 +58,18 @@ class usrp_transmit_path(gr.hier_block2): if options.tx_freq is None: sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n") raise SystemExit - tx_path = transmit_path.transmit_path(modulator_class, options) - for attr in dir(tx_path): #forward the methods - if not attr.startswith('_') and not hasattr(self, attr): - setattr(self, attr, getattr(tx_path, attr)) #setup usrp self._modulator_class = modulator_class self._setup_usrp_sink(options) - # Set up resampler based on rate determined by _setup_usrp_sink - rs_taps = gr.firdes.low_pass_2(32, 32, 0.45, 0.1, 60) - self.resampler = gr.pfb_arb_resampler_ccf(self.rs_rate, rs_taps) + tx_path = transmit_path.transmit_path(modulator_class, options) + for attr in dir(tx_path): #forward the methods + if not attr.startswith('_') and not hasattr(self, attr): + setattr(self, attr, getattr(tx_path, attr)) #connect - self.connect(tx_path, self.resampler, self.u) + self.connect(tx_path, self.u) def _setup_usrp_sink(self, options): """ @@ -82,17 +79,20 @@ class usrp_transmit_path(gr.hier_block2): self.u = usrp_options.create_usrp_sink(options) dac_rate = self.u.dac_rate() self.rs_rate = options.bitrate # Store requested bit rate - if options.verbose: - print 'USRP Sink:', self.u + (self._bitrate, self._samples_per_symbol, self._interp) = \ - pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(), \ - options.samples_per_symbol, options.interp, dac_rate, \ - self.u.get_interp_rates()) + pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(), + options.samples_per_symbol, options.interp, + dac_rate, self.u.get_interp_rates()) - # Calculate resampler rate based on requested and actual rates - self.rs_rate = self._bitrate / self.rs_rate - print "Resampling by %f to get bitrate of %ssps" % (self.rs_rate, eng_notation.num_to_str(self._bitrate/self.rs_rate)) + options.interp = self._interp + options.samples_per_symbol = self._samples_per_symbol + options.bitrate = self._bitrate + if options.verbose: + print 'USRP Sink:', self.u + print "Interpolation Rate: ", self._interp + self.u.set_interp(self._interp) self.u.set_auto_tr(True) diff --git a/gnuradio-examples/python/digital/usrp_transmit_path2.py b/gnuradio-examples/python/digital/usrp_transmit_path2.py new file mode 100644 index 000000000..54930e5a0 --- /dev/null +++ b/gnuradio-examples/python/digital/usrp_transmit_path2.py @@ -0,0 +1,101 @@ +# +# Copyright 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 +from gnuradio import usrp_options +import transmit_path +from pick_bitrate2 import pick_tx_bitrate +from gnuradio import eng_notation + +def add_freq_option(parser): + """ + Hackery that has the -f / --freq option set both tx_freq and rx_freq + """ + def freq_callback(option, opt_str, value, parser): + parser.values.rx_freq = value + parser.values.tx_freq = value + + if not parser.has_option('--freq'): + parser.add_option('-f', '--freq', type="eng_float", + action="callback", callback=freq_callback, + help="set Tx and/or Rx frequency to FREQ [default=%default]", + metavar="FREQ") + +def add_options(parser, expert): + add_freq_option(parser) + usrp_options.add_tx_options(parser) + transmit_path.transmit_path.add_options(parser, expert) + expert.add_option("", "--tx-freq", type="eng_float", default=None, + help="set transmit frequency to FREQ [default=%default]", metavar="FREQ") + parser.add_option("-v", "--verbose", action="store_true", default=False) + +class usrp_transmit_path(gr.hier_block2): + def __init__(self, modulator_class, options): + ''' + See below for what options should hold + ''' + gr.hier_block2.__init__(self, "usrp_transmit_path", + gr.io_signature(0, 0, 0), # Input signature + gr.io_signature(0, 0, 0)) # Output signature + if options.tx_freq is None: + sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n") + raise SystemExit + + #setup usrp + self._modulator_class = modulator_class + self._setup_usrp_sink(options) + + tx_path = transmit_path.transmit_path(modulator_class, options) + for attr in dir(tx_path): #forward the methods + if not attr.startswith('_') and not hasattr(self, attr): + setattr(self, attr, getattr(tx_path, attr)) + + #connect + self.connect(tx_path, self.u) + + def _setup_usrp_sink(self, options): + """ + Creates a USRP sink, determines the settings for best bitrate, + and attaches to the transmitter's subdevice. + """ + self.u = usrp_options.create_usrp_sink(options) + dac_rate = self.u.dac_rate() + self.rs_rate = options.bitrate # Store requested bit rate + + (self._bitrate, self._samples_per_symbol, self._interp) = \ + pick_tx_bitrate(options.bitrate, self._modulator_class.bits_per_symbol(), + options.samples_per_symbol, options.interp, + dac_rate, self.u.get_interp_rates()) + + options.interp = self._interp + options.samples_per_symbol = self._samples_per_symbol + options.bitrate = self._bitrate + + if options.verbose: + print 'USRP Sink:', self.u + print "Interpolation Rate: ", self._interp + + self.u.set_interp(self._interp) + self.u.set_auto_tr(True) + + if not self.u.set_center_freq(options.tx_freq): + print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(options.tx_freq)) + raise ValueError, eng_notation.num_to_str(options.tx_freq) |