Imported Upstream version 3.2.2
[debian/gnuradio] / gr-pager / src / usrp_flex.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2006,2007,2009 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 3, 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, gru, usrp, optfir, eng_notation, pager
24 from gnuradio.eng_option import eng_option
25 from optparse import OptionParser
26 import time, os, sys
27
28 """
29 This example application demonstrates receiving and demodulating the
30 FLEX pager protocol.
31
32 The following are required command line parameters:
33
34 -f FREQ     USRP receive frequency
35
36 The following are optional command line parameters:
37
38 -R SUBDEV   Daughter board specification, defaults to first found
39 -F FILE     Read samples from a file instead of USRP.
40 -c FREQ     Calibration offset.  Gets added to receive frequency.
41             Defaults to 0.0 Hz.
42 -g GAIN     Daughterboard gain setting. Defaults to mid-range.
43 -l          Log flow graph to files (LOTS of data)
44 -v          Verbose output
45
46 Once the program is running, ctrl-break (Ctrl-C) stops operation.
47 """
48
49 class app_top_block(gr.top_block):
50     def __init__(self, options, queue):
51         gr.top_block.__init__(self, "usrp_flex")
52         self.options = options
53         self.offset = 0.0
54         self.adj_time = time.time()
55         self.verbose = options.verbose
56                         
57         if options.from_file is None:
58             # Set up USRP source with specified RX daughterboard
59             self.src = usrp.source_c()
60             if options.rx_subdev_spec == None:
61                 options.rx_subdev_spec = usrp.pick_rx_subdevice(self.src)
62             self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec)
63             self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec))
64
65             # Grab 250 KHz of spectrum (sample rate becomes 250 ksps complex)
66             self.src.set_decim_rate(256)
67                     
68             # If no gain specified, set to midrange
69             if options.gain is None:
70                 g = self.subdev.gain_range()
71                 options.gain = (g[0]+g[1])/2.0
72             self.subdev.set_gain(options.gain)
73
74             # Tune daughterboard
75             actual_frequency = options.frequency+options.calibration
76             tune_result = usrp.tune(self.src, 0, self.subdev, actual_frequency)
77             if not tune_result:
78                 sys.stderr.write("Failed to set center frequency to "+`actual_frequency`+"\n")
79                 sys.exit(1)
80
81             if options.verbose:
82                 print "Using RX daughterboard", self.subdev.side_and_name()
83                 print "USRP gain is", options.gain
84                 print "USRP tuned to", actual_frequency
85             
86         else:
87             # Use supplied file as source of samples
88             self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file)
89             if options.verbose:
90                 print "Reading samples from", options.from_file
91             
92         if options.log and not options.from_file:
93             usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat')
94             self.connect(self.src, usrp_sink)
95
96         # Set up 22KHz-wide bandpass about center frequency. Decimate by 10
97         # to get channel rate of 25Ksps
98         taps = optfir.low_pass(1.0,   # Filter gain
99                                250e3, # Sample rate
100                                11000, # One-sided modulation bandwidth
101                                12500, # One-sided channel bandwidth
102                                0.1,   # Passband ripple
103                                60)    # Stopband attenuation
104         
105         if options.verbose:
106             print "Channel filter has", len(taps), "taps."
107
108         self.chan = gr.freq_xlating_fir_filter_ccf(10,    # Decimation rate
109                                                    taps,  # Filter taps
110                                                    0.0,   # Offset frequency
111                                                    250e3) # Sample rate
112
113         if options.log:
114             chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat')
115             self.connect(self.chan, chan_sink)
116
117         # FLEX protocol demodulator
118         self.flex = pager.flex_demod(queue, options.frequency, options.verbose, options.log)
119
120         self.connect(self.src, self.chan, self.flex)
121
122     def freq_offset(self):
123         return self.flex.dc_offset()*1600
124
125     def adjust_freq(self):
126         if time.time() - self.adj_time > 1.6:   # Only do it once per FLEX frame
127             self.adj_time = time.time()
128             self.offset -= self.freq_offset()
129             self.chan.set_center_freq(self.offset)
130             if self.verbose:
131                 print "Channel frequency offset (Hz):", int(self.offset)
132                         
133 def main():
134     parser = OptionParser(option_class=eng_option)
135     parser.add_option("-f", "--frequency", type="eng_float", default=None,
136                       help="set receive frequency to Hz", metavar="Hz")
137     parser.add_option("-R", "--rx-subdev-spec", type="subdev",
138                       help="select USRP Rx side A or B", metavar="SUBDEV")
139     parser.add_option("-c",   "--calibration", type="eng_float", default=0.0,
140                       help="set frequency offset to Hz", metavar="Hz")
141     parser.add_option("-g", "--gain", type="int", default=None,
142                       help="set RF gain", metavar="dB")
143     parser.add_option("-l", "--log", action="store_true", default=False,
144                       help="log flowgraph to files (LOTS of data)")
145     parser.add_option("-v", "--verbose", action="store_true", default=False,
146                       help="display debug output")
147     parser.add_option("-F", "--from-file", default=None,
148                       help="read samples from file instead of USRP")
149     (options, args) = parser.parse_args()
150
151     if len(args) > 0 or (options.frequency == None and options.from_file == None):
152         print "Run 'usrp_flex.py -h' for options."
153         sys.exit(1)
154
155     if options.frequency == None:
156         options.frequency = 0.0
157
158     # Flow graph emits pages into message queue
159     queue = gr.msg_queue()
160     tb = app_top_block(options, queue)
161     runner = pager.queue_runner(queue)
162     
163     try:
164         tb.run()
165     except KeyboardInterrupt:
166         pass
167
168     runner.end()
169
170
171 if __name__ == "__main__":
172     main()