Fix reference message and tweak DC removal constant.
[debian/gnuradio] / gr-pager / src / usrp_flex.py
1 #!/usr/bin/env python
2
3 #
4 # Copyright 2006,2007 Free Software Foundation, Inc.
5
6 # This file is part of GNU Radio
7
8 # GNU Radio is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2, or (at your option)
11 # any later version.
12
13 # GNU Radio is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17
18 # You should have received a copy of the GNU General Public License
19 # along with GNU Radio; see the file COPYING.  If not, write to
20 # the Free Software Foundation, Inc., 51 Franklin Street,
21 # Boston, MA 02110-1301, USA.
22
23
24 from gnuradio import gr, gru, usrp, optfir, eng_notation, blks, pager
25 from gnuradio.eng_option import eng_option
26 from optparse import OptionParser
27 import time, os, sys
28 from string import split, join
29
30 """
31 This example application demonstrates receiving and demodulating the
32 FLEX pager protocol.
33
34 The following are required command line parameters:
35
36 -f FREQ     USRP receive frequency
37
38 The following are optional command line parameters:
39
40 -R SUBDEV   Daughter board specification, defaults to first found
41 -F FILE     Read samples from a file instead of USRP.
42 -c FREQ     Calibration offset.  Gets added to receive frequency.
43             Defaults to 0.0 Hz.
44 -g GAIN     Daughterboard gain setting. Defaults to mid-range.
45 -l          Log flow graph to files (LOTS of data)
46 -v          Verbose output
47
48 Once the program is running, ctrl-break (Ctrl-C) stops operation.
49 """
50
51 class app_top_block(gr.top_block):
52     def __init__(self, options, queue):
53         gr.top_block.__init__(self, "usrp_flex")
54         self.options = options
55
56         if options.from_file is None:
57             # Set up USRP source with specified RX daughterboard
58             self.src = usrp.source_c()
59             if options.rx_subdev_spec == None:
60                 options.rx_subdev_spec = usrp.pick_rx_subdevice(self.src)
61             self.subdev = usrp.selected_subdev(self.src, options.rx_subdev_spec)
62             self.src.set_mux(usrp.determine_rx_mux_value(self.src, options.rx_subdev_spec))
63
64             # Grab 250 KHz of spectrum (sample rate becomes 250 ksps complex)
65             self.src.set_decim_rate(256)
66                     
67             # If no gain specified, set to midrange
68             if options.gain is None:
69                 g = self.subdev.gain_range()
70                 options.gain = (g[0]+g[1])/2.0
71             self.subdev.set_gain(options.gain)
72
73             # Tune daughterboard
74             actual_frequency = options.frequency+options.calibration
75             tune_result = usrp.tune(self.src, 0, self.subdev, actual_frequency)
76             if not tune_result:
77                 sys.stderr.write("Failed to set center frequency to "+`actual_frequency`+"\n")
78                 sys.exit(1)
79
80             if options.verbose:
81                 print "Using RX daughterboard", self.subdev.side_and_name()
82                 print "USRP gain is", options.gain
83                 print "USRP tuned to", actual_frequency
84             
85         else:
86             # Use supplied file as source of samples
87             self.src = gr.file_source(gr.sizeof_gr_complex, options.from_file)
88             if options.verbose:
89                 print "Reading samples from", options.from_file
90             
91         if options.log and not options.from_file:
92             usrp_sink = gr.file_sink(gr.sizeof_gr_complex, 'usrp.dat')
93             self.connect(self.src, usrp_sink)
94
95         # Set up 22KHz-wide bandpass about center frequency. Decimate by 10
96         # to get channel rate of 25Ksps
97         taps = optfir.low_pass(1.0,   # Filter gain
98                                250e3, # Sample rate
99                                11000, # One-sided modulation bandwidth
100                                12500, # One-sided channel bandwidth
101                                0.1,   # Passband ripple
102                                60)    # Stopband attenuation
103         
104         if options.verbose:
105             print "Channel filter has", len(taps), "taps."
106
107         chan = gr.freq_xlating_fir_filter_ccf(10,    # Decimation rate
108                                               taps,  # Filter taps
109                                               0.0,   # Offset frequency
110                                               250e3) # Sample rate
111
112         if options.log:
113             chan_sink = gr.file_sink(gr.sizeof_gr_complex, 'chan.dat')
114             self.connect(chan, chan_sink)
115
116         # FLEX protocol demodulator
117         flex = pager.flex_demod(queue, options.frequency, options.verbose, options.log)
118
119         self.connect(self.src, chan, flex)
120         
121 def main():
122     parser = OptionParser(option_class=eng_option)
123     parser.add_option("-f", "--frequency", type="eng_float", default=None,
124                       help="set receive frequency to Hz", metavar="Hz")
125     parser.add_option("-R", "--rx-subdev-spec", type="subdev",
126                       help="select USRP Rx side A or B", metavar="SUBDEV")
127     parser.add_option("-c",   "--calibration", type="eng_float", default=0.0,
128                       help="set frequency offset to Hz", metavar="Hz")
129     parser.add_option("-g", "--gain", type="int", default=None,
130                       help="set RF gain", metavar="dB")
131     parser.add_option("-l", "--log", action="store_true", default=False,
132                       help="log flowgraph to files (LOTS of data)")
133     parser.add_option("-v", "--verbose", action="store_true", default=False,
134                       help="display debug output")
135     parser.add_option("-F", "--from-file", default=None,
136                       help="read samples from file instead of USRP")
137     (options, args) = parser.parse_args()
138
139     if len(args) > 0 or (options.frequency == None and options.from_file == None):
140         print "Run 'usrp_flex.py -h' for options."
141         sys.exit(1)
142
143     if options.frequency == None:
144         options.frequency = 0.0
145
146     # Flow graph emits pages into message queue
147     queue = gr.msg_queue()
148     tb = app_top_block(options, queue)
149     r = gr.runtime(tb)
150     
151     try:
152         r.start()
153         while 1:
154             if not queue.empty_p():
155                 msg = queue.delete_head() # Blocking read
156                 page = join(split(msg.to_string(), chr(128)), '|')
157                 disp = []
158                 for n in range(len(page)):
159                     if ord(page[n]) < 32:
160                         disp.append('.')
161                     else:
162                         disp.append(page[n])
163                 print join(disp, '')
164                                                 
165             else:
166                 time.sleep(1)
167
168     except KeyboardInterrupt:
169         r.stop()
170
171 if __name__ == "__main__":
172     main()