3 # Copyright 2005,2006,2007,2009 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, gru, modulation_utils
24 from gnuradio import usrp
25 from gnuradio import eng_notation
26 from gnuradio.eng_option import eng_option
27 from optparse import OptionParser
29 import random, time, struct, sys
32 from transmit_path import transmit_path
33 from pick_bitrate import pick_tx_bitrate
38 #raw_input('Attach and press enter')
40 class my_top_block(gr.top_block):
41 def __init__(self, modulator, options):
42 gr.top_block.__init__(self)
44 self._tx_freq = options.tx_freq # tranmitter's center frequency
45 self._interp = options.interp # interpolating rate for the USRP (prelim)
46 self._bitrate = options.bitrate
47 self._samples_per_symbol = options.samples_per_symbol
48 self._modulator_class = modulator
50 if self._tx_freq is None:
51 sys.stderr.write("-f FREQ or --freq FREQ or --tx-freq FREQ must be specified\n")
54 # Set up USRP sink; also adjusts interp, and bitrate
55 self._setup_usrp_sink(options)
57 # copy the final answers back into options for use by modulator
58 options.samples_per_symbol = self._samples_per_symbol
59 options.bitrate = self._bitrate
60 options.interp = self._interp
62 # Set center frequency of USRP
63 ok = self.set_freq(self._tx_freq)
65 print "Failed to set Tx frequency to %s" % (eng_notation.num_to_str(self._tx_freq),)
68 # Set the USRP for maximum transmit gain
69 # (Note that on the RFX cards this is a nop.)
70 self.set_gain(self.u.gain_range()[1])
72 self.txpath = transmit_path(modulator, options)
74 self.connect(self.txpath, self.u)
76 def _setup_usrp_sink(self, options):
78 Creates a USRP sink, determines the settings for best bitrate,
79 and attaches to the transmitter's subdevice.
81 self.u = usrp_options.create_usrp_sink(options)
82 dac_rate = self.u.dac_rate()
84 (self._bitrate, self._samples_per_symbol, self._interp) = \
85 pick_tx_bitrate(self._bitrate, self._modulator_class.bits_per_symbol(), \
86 self._samples_per_symbol, self._interp, dac_rate, \
87 self.u.get_interp_rates())
89 self.u.set_interp(self._interp)
90 self.set_auto_tr(True) # enable Auto Transmit/Receive switching
92 def set_freq(self, target_freq):
94 Set the center frequency we're interested in.
96 @param target_freq: frequency in Hz
99 Tuning is a two step process. First we ask the front-end to
100 tune as close to the desired frequency as it can. Then we use
101 the result of that operation and our target_frequency to
102 determine the value for the digital up converter.
104 return self.u.set_center_freq(target_freq)
106 def set_gain(self, gain):
108 Sets the analog gain in the USRP
111 self.u.set_gain(gain)
113 def set_auto_tr(self, enable):
115 Turns on auto transmit/receive of USRP daughterboard (if exits; else ignored)
117 return self.u.set_auto_tr(enable)
122 def add_options(normal, expert):
124 Adds usrp-specific options to the Options Parser
126 add_freq_option(normal)
127 normal.add_option("-T", "--tx-subdev-spec", type="subdev", default=None,
128 help="select USRP Tx side A or B")
129 normal.add_option("-v", "--verbose", action="store_true", default=False)
131 expert.add_option("", "--tx-freq", type="eng_float", default=None,
132 help="set transmit frequency to FREQ [default=%default]", metavar="FREQ")
133 expert.add_option("-i", "--interp", type="intx", default=256,
134 help="set fpga interpolation rate to INTERP [default=%default]")
135 # Make a static method to call before instantiation
136 add_options = staticmethod(add_options)
138 def _print_verbage(self):
140 Prints information about the transmit path
142 print "Using TX d'board %s" % (self.subdev.side_and_name(),)
143 print "modulation: %s" % (self._modulator_class.__name__)
144 print "interp: %3d" % (self._interp)
145 print "Tx Frequency: %s" % (eng_notation.num_to_str(self._tx_freq))
148 def add_freq_option(parser):
150 Hackery that has the -f / --freq option set both tx_freq and rx_freq
152 def freq_callback(option, opt_str, value, parser):
153 parser.values.rx_freq = value
154 parser.values.tx_freq = value
156 if not parser.has_option('--freq'):
157 parser.add_option('-f', '--freq', type="eng_float",
158 action="callback", callback=freq_callback,
159 help="set Tx and/or Rx frequency to FREQ [default=%default]",
163 # /////////////////////////////////////////////////////////////////////////////
165 # /////////////////////////////////////////////////////////////////////////////
169 def send_pkt(payload='', eof=False):
170 return tb.txpath.send_pkt(payload, eof)
172 def rx_callback(ok, payload):
173 print "ok = %r, payload = '%s'" % (ok, payload)
175 mods = modulation_utils.type_1_mods()
177 parser = OptionParser(option_class=eng_option, conflict_handler="resolve")
178 expert_grp = parser.add_option_group("Expert")
180 parser.add_option("-m", "--modulation", type="choice", choices=mods.keys(),
182 help="Select modulation from: %s [default=%%default]"
183 % (', '.join(mods.keys()),))
185 parser.add_option("-s", "--size", type="eng_float", default=1500,
186 help="set packet size [default=%default]")
187 parser.add_option("-M", "--megabytes", type="eng_float", default=1.0,
188 help="set megabytes to transmit [default=%default]")
189 parser.add_option("","--discontinuous", action="store_true", default=False,
190 help="enable discontinous transmission (bursts of 5 packets)")
191 parser.add_option("","--from-file", default=None,
192 help="use file for packet contents")
194 my_top_block.add_options(parser, expert_grp)
195 transmit_path.add_options(parser, expert_grp)
196 usrp_options.add_tx_options(parser)
198 for mod in mods.values():
199 mod.add_options(expert_grp)
201 (options, args) = parser.parse_args ()
207 if options.tx_freq is None:
208 sys.stderr.write("You must specify -f FREQ or --freq FREQ\n")
209 parser.print_help(sys.stderr)
212 if options.from_file is not None:
213 source_file = open(options.from_file, 'r')
216 tb = my_top_block(mods[options.modulation], options)
218 r = gr.enable_realtime_scheduling()
220 print "Warning: failed to enable realtime scheduling"
222 tb.start() # start flow graph
224 # generate and send packets
225 nbytes = int(1e6 * options.megabytes)
228 pkt_size = int(options.size)
231 if options.from_file is None:
232 data = (pkt_size - 2) * chr(pktno & 0xff)
234 data = source_file.read(pkt_size - 2)
238 payload = struct.pack('!H', pktno & 0xffff) + data
241 sys.stderr.write('.')
242 if options.discontinuous and pktno % 5 == 4:
248 tb.wait() # wait for it to finish
250 if __name__ == '__main__':
253 except KeyboardInterrupt: