2 ##################################################
3 # Gnuradio Python Flow Graph
4 # Title: USRP HRPT Receiver
5 # Generated: Sun Nov 1 19:26:11 2009
6 ##################################################
8 from gnuradio import eng_notation
9 from gnuradio import gr
10 from gnuradio import noaa
11 from gnuradio import window
12 from gnuradio.eng_option import eng_option
13 from gnuradio.gr import firdes
14 from gnuradio.wxgui import fftsink2
15 from gnuradio.wxgui import forms
16 from gnuradio.wxgui import scopesink2
17 from grc_gnuradio import wxgui as grc_wxgui
18 from optparse import OptionParser
23 class file_rx_hrpt(grc_wxgui.top_block_gui):
25 def __init__(self, input_filename='usrp.dat', decim=16):
26 grc_wxgui.top_block_gui.__init__(self, title="USRP HRPT Receiver")
28 ##################################################
30 ##################################################
31 self.input_filename = input_filename
34 ##################################################
36 ##################################################
37 self.sym_rate = sym_rate = 600*1109
38 self.sample_rate = sample_rate = 64e6/decim
39 self.config_filename = config_filename = os.environ['HOME']+'/.gnuradio/config.conf'
40 self.sps = sps = sample_rate/sym_rate
41 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
42 self._saved_pll_alpha_config.read(config_filename)
43 try: saved_pll_alpha = self._saved_pll_alpha_config.getfloat('usrp_rx_hrpt', 'pll_alpha')
44 except: saved_pll_alpha = 0.05
45 self.saved_pll_alpha = saved_pll_alpha
46 self._saved_clock_alpha_config = ConfigParser.ConfigParser()
47 self._saved_clock_alpha_config.read(config_filename)
48 try: saved_clock_alpha = self._saved_clock_alpha_config.getfloat('usrp_rx_hrpt', 'clock_alpha')
49 except: saved_clock_alpha = 0.05
50 self.saved_clock_alpha = saved_clock_alpha
51 self._side_config = ConfigParser.ConfigParser()
52 self._side_config.read(config_filename)
53 try: side = self._side_config.get('usrp_rx_hrpt', 'side')
56 self.pll_alpha = pll_alpha = saved_pll_alpha
57 self._output_filename_config = ConfigParser.ConfigParser()
58 self._output_filename_config.read(config_filename)
59 try: output_filename = self._output_filename_config.get('usrp_rx_hrpt', 'filename')
60 except: output_filename = 'frames.dat'
61 self.output_filename = output_filename
62 self.max_clock_offset = max_clock_offset = 0.1
63 self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate
64 self.hs = hs = int(sps/2.0)
65 self.clock_alpha = clock_alpha = saved_clock_alpha
67 ##################################################
69 ##################################################
70 self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
71 self.displays.AddPage(grc_wxgui.Panel(self.displays), "Spectrum")
72 self.displays.AddPage(grc_wxgui.Panel(self.displays), "Demod")
73 self.GridAdd(self.displays, 1, 0, 1, 2)
75 ##################################################
77 ##################################################
78 _pll_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
79 self._pll_alpha_text_box = forms.text_box(
81 sizer=_pll_alpha_sizer,
83 callback=self.set_pll_alpha,
85 converter=forms.float_converter(),
88 self._pll_alpha_slider = forms.slider(
90 sizer=_pll_alpha_sizer,
92 callback=self.set_pll_alpha,
96 style=wx.SL_HORIZONTAL,
100 self.GridAdd(_pll_alpha_sizer, 0, 0, 1, 1)
101 _clock_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
102 self._clock_alpha_text_box = forms.text_box(
103 parent=self.GetWin(),
104 sizer=_clock_alpha_sizer,
105 value=self.clock_alpha,
106 callback=self.set_clock_alpha,
108 converter=forms.float_converter(),
111 self._clock_alpha_slider = forms.slider(
112 parent=self.GetWin(),
113 sizer=_clock_alpha_sizer,
114 value=self.clock_alpha,
115 callback=self.set_clock_alpha,
119 style=wx.SL_HORIZONTAL,
123 self.GridAdd(_clock_alpha_sizer, 0, 1, 1, 1)
125 ##################################################
127 ##################################################
128 self.agc = gr.agc_cc(1e-6, 1.0, 1.0, 1.0)
129 self.decoder = noaa.hrpt_decoder()
130 self.deframer = noaa.hrpt_deframer()
131 self.demod_scope = scopesink2.scope_sink_f(
132 self.displays.GetPage(1).GetWin(),
134 sample_rate=sym_rate*2.0,
137 t_scale=10.0/sym_rate,
142 self.displays.GetPage(1).GridAdd(self.demod_scope.win, 0, 0, 1, 1)
143 self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename)
144 self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb()
145 self.gr_clock_recovery_mm_xx_0 = gr.clock_recovery_mm_ff(sps/2.0, clock_alpha**2/4.0, 0.5, clock_alpha, max_clock_offset)
146 self.gr_file_source_0 = gr.file_source(gr.sizeof_short*1, input_filename, False)
147 self.gr_interleaved_short_to_complex_0 = gr.interleaved_short_to_complex()
148 self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000)
149 self.noaa_hrpt_bit_sync_0 = noaa.hrpt_bit_sync()
150 self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset)
151 self.rx_fft = fftsink2.fft_sink_c(
152 self.displays.GetPage(0).GetWin(),
158 sample_rate=sample_rate,
167 self.displays.GetPage(0).GridAdd(self.rx_fft.win, 0, 0, 1, 1)
168 self.throttle = gr.throttle(gr.sizeof_short*1, sample_rate)
170 ##################################################
172 ##################################################
173 self.connect((self.noaa_hrpt_bit_sync_0, 0), (self.deframer, 0))
174 self.connect((self.gr_binary_slicer_fb_0, 0), (self.noaa_hrpt_bit_sync_0, 0))
175 self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0))
176 self.connect((self.deframer, 0), (self.frame_sink, 0))
177 self.connect((self.deframer, 0), (self.decoder, 0))
178 self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.demod_scope, 0))
179 self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0))
180 self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0))
181 self.connect((self.agc, 0), (self.pll, 0))
182 self.connect((self.agc, 0), (self.rx_fft, 0))
183 self.connect((self.gr_interleaved_short_to_complex_0, 0), (self.agc, 0))
184 self.connect((self.throttle, 0), (self.gr_interleaved_short_to_complex_0, 0))
185 self.connect((self.gr_file_source_0, 0), (self.throttle, 0))
187 def set_input_filename(self, input_filename):
188 self.input_filename = input_filename
190 def set_decim(self, decim):
192 self.set_sample_rate(64e6/self.decim)
194 def set_sym_rate(self, sym_rate):
195 self.sym_rate = sym_rate
196 self.set_sps(self.sample_rate/self.sym_rate)
197 self.demod_scope.set_sample_rate(self.sym_rate*2.0)
199 def set_sample_rate(self, sample_rate):
200 self.sample_rate = sample_rate
201 self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate)
202 self.set_sps(self.sample_rate/self.sym_rate)
203 self.rx_fft.set_sample_rate(self.sample_rate)
205 def set_config_filename(self, config_filename):
206 self.config_filename = config_filename
207 self._side_config = ConfigParser.ConfigParser()
208 self._side_config.read(self.config_filename)
209 if not self._side_config.has_section('usrp_rx_hrpt'):
210 self._side_config.add_section('usrp_rx_hrpt')
211 self._side_config.set('usrp_rx_hrpt', 'side', str(self.side))
212 self._side_config.write(open(self.config_filename, 'w'))
213 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
214 self._saved_pll_alpha_config.read(self.config_filename)
215 if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'):
216 self._saved_pll_alpha_config.add_section('usrp_rx_hrpt')
217 self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
218 self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
219 self._saved_clock_alpha_config = ConfigParser.ConfigParser()
220 self._saved_clock_alpha_config.read(self.config_filename)
221 if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'):
222 self._saved_clock_alpha_config.add_section('usrp_rx_hrpt')
223 self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
224 self._saved_clock_alpha_config.write(open(self.config_filename, 'w'))
225 self._output_filename_config = ConfigParser.ConfigParser()
226 self._output_filename_config.read(self.config_filename)
227 if not self._output_filename_config.has_section('usrp_rx_hrpt'):
228 self._output_filename_config.add_section('usrp_rx_hrpt')
229 self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
230 self._output_filename_config.write(open(self.config_filename, 'w'))
232 def set_sps(self, sps):
234 self.set_hs(int(self.sps/2.0))
235 self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0)
237 def set_saved_pll_alpha(self, saved_pll_alpha):
238 self.saved_pll_alpha = saved_pll_alpha
239 self.set_pll_alpha(self.saved_pll_alpha)
241 def set_saved_clock_alpha(self, saved_clock_alpha):
242 self.saved_clock_alpha = saved_clock_alpha
243 self.set_clock_alpha(self.saved_clock_alpha)
245 def set_side(self, side):
247 self._side_config = ConfigParser.ConfigParser()
248 self._side_config.read(self.config_filename)
249 if not self._side_config.has_section('usrp_rx_hrpt'):
250 self._side_config.add_section('usrp_rx_hrpt')
251 self._side_config.set('usrp_rx_hrpt', 'side', str(self.side))
252 self._side_config.write(open(self.config_filename, 'w'))
254 def set_pll_alpha(self, pll_alpha):
255 self.pll_alpha = pll_alpha
256 self.pll.set_alpha(self.pll_alpha)
257 self.pll.set_beta(self.pll_alpha**2/4.0)
258 self._pll_alpha_slider.set_value(self.pll_alpha)
259 self._pll_alpha_text_box.set_value(self.pll_alpha)
260 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
261 self._saved_pll_alpha_config.read(self.config_filename)
262 if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'):
263 self._saved_pll_alpha_config.add_section('usrp_rx_hrpt')
264 self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
265 self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
267 def set_output_filename(self, output_filename):
268 self.output_filename = output_filename
269 self._output_filename_config = ConfigParser.ConfigParser()
270 self._output_filename_config.read(self.config_filename)
271 if not self._output_filename_config.has_section('usrp_rx_hrpt'):
272 self._output_filename_config.add_section('usrp_rx_hrpt')
273 self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
274 self._output_filename_config.write(open(self.config_filename, 'w'))
276 def set_max_clock_offset(self, max_clock_offset):
277 self.max_clock_offset = max_clock_offset
279 def set_max_carrier_offset(self, max_carrier_offset):
280 self.max_carrier_offset = max_carrier_offset
281 self.pll.set_max_offset(self.max_carrier_offset)
283 def set_hs(self, hs):
285 self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs)
287 def set_clock_alpha(self, clock_alpha):
288 self.clock_alpha = clock_alpha
289 self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0)
290 self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha)
291 self._clock_alpha_slider.set_value(self.clock_alpha)
292 self._clock_alpha_text_box.set_value(self.clock_alpha)
293 self._saved_clock_alpha_config = ConfigParser.ConfigParser()
294 self._saved_clock_alpha_config.read(self.config_filename)
295 if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'):
296 self._saved_clock_alpha_config.add_section('usrp_rx_hrpt')
297 self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
298 self._saved_clock_alpha_config.write(open(self.config_filename, 'w'))
300 if __name__ == '__main__':
301 parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
302 parser.add_option("-F", "--input-filename", dest="input_filename", type="string", default='usrp.dat',
303 help="Set usrp.dat [default=%default]")
304 parser.add_option("-d", "--decim", dest="decim", type="intx", default=16,
305 help="Set decim [default=%default]")
306 (options, args) = parser.parse_args()
307 tb = file_rx_hrpt(input_filename=options.input_filename, decim=options.decim)