3 # Copyright 2006, 2007 Free Software Foundation, Inc.
5 # This file is part of GNU Radio
7 # GNU Radio is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3, or (at your option)
12 # GNU Radio is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with GNU Radio; see the file COPYING. If not, write to
19 # the Free Software Foundation, Inc., 51 Franklin Street,
20 # Boston, MA 02110-1301, USA.
23 from gnuradio import gr, blks2
24 from gnuradio import usrp
25 from gnuradio import eng_notation
26 from gnuradio.eng_option import eng_option
27 from optparse import OptionParser
32 from receive_path import receive_path
35 class my_top_block(gr.top_block):
36 def __init__(self, callback, options):
37 gr.top_block.__init__(self)
39 self._rx_freq = options.rx_freq # receiver's center frequency
40 self._rx_gain = options.rx_gain # receiver's gain
41 self._rx_subdev_spec = options.rx_subdev_spec # daughterboard to use
42 self._decim = options.decim # Decimating rate for the USRP (prelim)
43 self._fusb_block_size = options.fusb_block_size # usb info for USRP
44 self._fusb_nblocks = options.fusb_nblocks # usb info for USRP
46 if self._rx_freq is None:
47 sys.stderr.write("-f FREQ or --freq FREQ or --rx-freq FREQ must be specified\n")
51 self._setup_usrp_source()
52 ok = self.set_freq(self._rx_freq)
54 print "Failed to set Rx frequency to %s" % (eng_notation.num_to_str(self._rx_freq))
55 raise ValueError, eng_notation.num_to_str(self._rx_freq)
56 g = self.subdev.gain_range()
57 if options.show_rx_gain_range:
58 print "Rx Gain Range: minimum = %g, maximum = %g, step size = %g" \
60 self.set_gain(options.rx_gain)
61 self.set_auto_tr(True) # enable Auto Transmit/Receive switching
64 self.rxpath = receive_path(callback, options)
66 self.connect(self.u, self.rxpath)
68 def _setup_usrp_source(self):
69 self.u = usrp.source_c (fusb_block_size=self._fusb_block_size,
70 fusb_nblocks=self._fusb_nblocks)
71 adc_rate = self.u.adc_rate()
73 self.u.set_decim_rate(self._decim)
75 # determine the daughterboard subdevice we're using
76 if self._rx_subdev_spec is None:
77 self._rx_subdev_spec = usrp.pick_rx_subdevice(self.u)
78 self.subdev = usrp.selected_subdev(self.u, self._rx_subdev_spec)
80 self.u.set_mux(usrp.determine_rx_mux_value(self.u, self._rx_subdev_spec))
82 def set_freq(self, target_freq):
84 Set the center frequency we're interested in.
86 @param target_freq: frequency in Hz
89 Tuning is a two step process. First we ask the front-end to
90 tune as close to the desired frequency as it can. Then we use
91 the result of that operation and our target_frequency to
92 determine the value for the digital up converter.
94 r = self.u.tune(0, self.subdev, target_freq)
100 def set_gain(self, gain):
102 Sets the analog gain in the USRP
105 r = self.subdev.gain_range()
106 gain = (r[0] + r[1])/2 # set gain to midpoint
108 return self.subdev.set_gain(gain)
110 def set_auto_tr(self, enable):
111 return self.subdev.set_auto_tr(enable)
116 def add_options(normal, expert):
118 Adds usrp-specific options to the Options Parser
120 add_freq_option(normal)
121 normal.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
122 help="select USRP Rx side A or B")
123 normal.add_option("", "--rx-gain", type="eng_float", default=None, metavar="GAIN",
124 help="set receiver gain in dB [default=midpoint]. See also --show-rx-gain-range")
125 normal.add_option("", "--show-rx-gain-range", action="store_true", default=False,
126 help="print min and max Rx gain available on selected daughterboard")
127 normal.add_option("-v", "--verbose", action="store_true", default=False)
129 expert.add_option("", "--rx-freq", type="eng_float", default=None,
130 help="set Rx frequency to FREQ [default=%default]", metavar="FREQ")
131 expert.add_option("-d", "--decim", type="intx", default=128,
132 help="set fpga decimation rate to DECIM [default=%default]")
133 expert.add_option("", "--snr", type="eng_float", default=30,
134 help="set the SNR of the channel in dB [default=%default]")
137 # Make a static method to call before instantiation
138 add_options = staticmethod(add_options)
140 def add_freq_option(parser):
142 Hackery that has the -f / --freq option set both tx_freq and rx_freq
144 def freq_callback(option, opt_str, value, parser):
145 parser.values.rx_freq = value
146 parser.values.tx_freq = value
148 if not parser.has_option('--freq'):
149 parser.add_option('-f', '--freq', type="eng_float",
150 action="callback", callback=freq_callback,
151 help="set Tx and/or Rx frequency to FREQ [default=%default]",
154 # /////////////////////////////////////////////////////////////////////////////
156 # /////////////////////////////////////////////////////////////////////////////
160 global n_rcvd, n_right
165 def rx_callback(ok, payload):
166 global n_rcvd, n_right
168 (pktno,) = struct.unpack('!H', payload[0:2])
171 print "ok: %r \t pktno: %d \t n_rcvd: %d \t n_right: %d" % (ok, pktno, n_rcvd, n_right)
175 for x in payload[2:]:
176 t = hex(ord(x)).replace('0x', '')
180 printable = ''.join(printlst)
185 parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
186 expert_grp = parser.add_option_group("Expert")
187 parser.add_option("","--discontinuous", action="store_true", default=False,
188 help="enable discontinuous")
190 my_top_block.add_options(parser, expert_grp)
191 receive_path.add_options(parser, expert_grp)
192 blks2.ofdm_mod.add_options(parser, expert_grp)
193 blks2.ofdm_demod.add_options(parser, expert_grp)
194 fusb_options.add_options(expert_grp)
196 (options, args) = parser.parse_args ()
199 tb = my_top_block(rx_callback, options)
201 r = gr.enable_realtime_scheduling()
203 print "Warning: failed to enable realtime scheduling"
205 tb.start() # start flow graph
206 tb.wait() # wait for it to finish
208 if __name__ == '__main__':
211 except KeyboardInterrupt: