Merged r5033:5116 from developer branch jcorgan/snd, with minor edits. Trunk passes...
[debian/gnuradio] / gr-sounder / src / python / usrp_sounder.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2007 Free Software Foundation, Inc.
4
5 # This file is part of GNU Radio
6
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)
10 # any later version.
11
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.
16
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.
21
22
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
27 import sys, time
28
29 n2s = eng_notation.num_to_str
30
31 # Set to 0 for 32 MHz tx clock, 1 for 64 MHz tx clock
32 # Must match config.vh in FPGA code
33 TX_RATE_MAX = 0
34 _tx_freq_divisor = 32e6*(TX_RATE_MAX+1)
35
36 class sounder_tx:
37     def __init__(self, frequency, degree, loopback):
38         self.trans = usrp.sink_s(fpga_filename='usrp_sounder.rbf')
39         self.subdev_spec = usrp.pick_tx_subdevice(self.trans)
40         self.subdev = usrp.selected_subdev(self.trans, self.subdev_spec)
41         self.trans.tune(0, self.subdev, frequency)
42         self.set_degree(degree);
43         self.set_loopback(loopback)
44             
45     def turn_on(self):
46         self.trans.start()
47         
48     def turn_off(self):
49         self.trans.stop()
50
51     def set_degree(self, value):
52         return self.trans._write_fpga_reg(usrp.FR_USER_0, value);
53
54     def set_loopback(self, value):
55         return self.trans._write_fpga_reg(usrp.FR_USER_1, value==True);
56
57 class sounder_rx:
58     def __init__(self, frequency, degree, samples):
59         self.fg = gr.flow_graph()
60         self.rcvr = usrp.source_s(fpga_filename='usrp_sounder.rbf', decim_rate=8)
61         self.subdev_spec = usrp.pick_rx_subdevice(self.rcvr)
62         self.subdev = usrp.selected_subdev(self.rcvr, self.subdev_spec)
63         self.rcvr.tune(0, self.subdev, frequency)
64         self.set_degree(degree);
65         self.sink = gr.file_sink(gr.sizeof_short, "output.dat")
66
67         if samples >= 0:
68             self.head = gr.head(gr.sizeof_short, 2*samples*gr.sizeof_short)
69             self.fg.connect(self.rcvr, self.head, self.sink)
70         else:
71             self.fg.connect(self.rcvr, self.sink)
72
73     def receive(self):
74         self.fg.run()
75         
76     def set_degree(self, value):
77         return self.rcvr._write_fpga_reg(usrp.FR_USER_0, value);
78
79 def main():
80     parser = OptionParser(option_class=eng_option)
81     parser.add_option("-f", "--frequency", type="eng_float", default=0.0,
82                       help="set frequency to FREQ in Hz, default is %default", metavar="FREQ")
83
84     parser.add_option("-t", "--transmit", action="store_true", default=False,
85                       help="enable sounding transmitter")
86
87     parser.add_option("-r", "--receive", action="store_true", default=False,
88                       help="enable sounding receiver")
89
90     parser.add_option("-d", "--degree", type="int", default=16,
91                       help="set souding sequence degree (len=2^degree-1), default is %default")
92
93     parser.add_option("-n", "--samples", type="int", default=-1,
94                       help="number of samples to capture on receive, default is infinite")
95
96     parser.add_option("-l", "--loopback", action="store_true", default=False,
97                       help="enable digital loopback, default is disabled")
98
99     (options, args) = parser.parse_args()
100
101     if len(args) != 0 or not (options.transmit | options.receive):
102         parser.print_help()
103         sys.exit(1)
104
105     print "Using PN code degree of", options.degree, "length", 2**options.degree-1
106     print "Sounding frequency range is", n2s(options.frequency-16e6), "to", n2s(options.frequency+16e6)
107     
108     if (options.transmit):
109         print "Enabling sounder transmitter."
110         if (options.loopback):
111             print "Enabling digital loopback."
112         tx = sounder_tx(options.frequency, options.degree, options.loopback)
113         tx.turn_on()
114         
115     try:
116         if (options.receive):
117             print "Enabling sounder receiver."
118             rx = sounder_rx(options.frequency, options.degree, options.samples)
119             rx.receive()
120         else:
121             if (options.transmit):
122                 while (True): time.sleep(1.0)
123
124     except KeyboardInterrupt:
125         if (options.transmit):
126             tx.turn_off()
127
128         
129 if __name__ == "__main__":
130     main()