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: