3 # Copyright 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 2, 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, usrp
24 from gnuradio import eng_notation
25 from gnuradio.eng_option import eng_option
26 from optparse import OptionParser
29 n2s = eng_notation.num_to_str
31 FR_MODE = usrp.FR_USER_0
32 bmFR_MODE_RESET = 1 << 0 # bit 0: active high reset
33 bmFR_MODE_TX = 1 << 1 # bit 1: enable transmitter
34 bmFR_MODE_RX = 1 << 2 # bit 2: enable receiver
35 bmFR_MODE_LP = 1 << 3 # bit 3: enable digital loopback
37 FR_DEGREE = usrp.FR_USER_1
40 def __init__(self, options):
41 self._options = options
47 self._transmitting = False
48 self._receiving = False
51 print "Creating sounder transmitter."
52 self._trans = usrp.sink_s(fpga_filename='usrp_sounder.rbf')
53 self._trans_subdev_spec = usrp.pick_tx_subdevice(self._trans)
54 self._trans_subdev = usrp.selected_subdev(self._trans, self._trans_subdev_spec)
59 print "Creating sounder receiver."
60 self._fg = gr.flow_graph()
61 self._rcvr = usrp.source_s(fpga_filename='usrp_sounder.rbf', decim_rate=128)
62 self._rcvr_subdev_spec = usrp.pick_rx_subdevice(self._rcvr)
63 self._rcvr_subdev = usrp.selected_subdev(self._rcvr, self._rcvr_subdev_spec)
64 self._sink = gr.file_sink(gr.sizeof_short, "output.dat")
66 if options.samples >= 0:
67 self._head = gr.head(gr.sizeof_short, options.samples*gr.sizeof_short)
68 self._fg.connect(self._rcvr, self._head, self._sink)
70 self._fg.connect(self._rcvr, self._sink)
71 self._u = self._rcvr # either receiver or transmitter object will do
74 self.set_freq(options.frequency)
75 self.set_degree(options.degree)
76 self.set_loopback(options.loopback)
79 def set_freq(self, frequency):
80 print "Setting center frequency to", n2s(frequency)
82 self._rcvr.tune(0, self._rcvr_subdev, frequency)
85 self._trans.tune(0, self._trans_subdev, frequency)
87 def set_degree(self, degree):
88 print "Setting PN code degree to", degree
89 self._u._write_fpga_reg(FR_DEGREE, degree);
91 def _write_mode(self):
92 print "Writing mode register with:", hex(self._mode)
93 self._u._write_fpga_reg(FR_MODE, self._mode)
95 def enable_tx(self, value):
97 print "Enabling transmitter."
98 self._mode |= bmFR_MODE_TX
99 self._transmitting = True
101 print "Disabling transmitter."
102 self._mode &= ~bmFR_MODE_TX
105 def enable_rx(self, value):
107 print "Starting receiver flow graph."
108 self._mode |= bmFR_MODE_RX
111 self._receiving = True
112 if self._options.samples >= 0:
115 print "Stopping receiver flow graph."
116 if self._options.samples < 0:
118 print "Waiting for threads..."
120 print "Receiver flow graph stopped."
121 self._mode &= ~bmFR_MODE_RX
123 self._receiving = False
125 def set_loopback(self, value):
127 print "Enabling digital loopback."
128 self._mode |= bmFR_MODE_LP
130 print "Disabling digital loopback."
131 self._mode &= ~bmFR_MODE_LP
134 def set_reset(self, value):
136 print "Asserting reset."
137 self._mode |= bmFR_MODE_RESET
139 print "De-asserting reset."
140 self._mode &= ~bmFR_MODE_RESET
144 if self._transmitting:
145 self.enable_tx(False)
148 self.enable_rx(False)
150 # ------------------------------------------------------------------------------
153 parser = OptionParser(option_class=eng_option)
154 parser.add_option("-f", "--frequency", type="eng_float", default=0.0,
155 help="set frequency to FREQ in Hz, default is %default", metavar="FREQ")
157 parser.add_option("-d", "--degree", type="int", default=16,
158 help="set souding sequence degree (len=2^degree-1), default is %default")
160 parser.add_option("-t", "--transmit", action="store_true", default=False,
161 help="enable sounding transmitter")
163 parser.add_option("-r", "--receive", action="store_true", default=False,
164 help="enable sounding receiver")
166 parser.add_option("-n", "--samples", type="int", default=-1,
167 help="number of samples to capture on receive, default is infinite")
169 parser.add_option("-l", "--loopback", action="store_true", default=False,
170 help="enable digital loopback, default is disabled")
172 (options, args) = parser.parse_args()
174 if len(args) != 0 or not (options.transmit | options.receive):
178 print "Using PN code degree of", options.degree, "length", 2**options.degree-1
179 print "Sounding frequency range is", n2s(options.frequency-16e6), "to", n2s(options.frequency+16e6)
189 if options.samples < 0:
190 raw_input("Press enter to exit.")
192 if __name__ == "__main__":