ae70f25c8ce0d3733b2a10ca392207d323d4185f
[debian/gnuradio] / gr-noaa / apps / usrp_rx_hrpt.py
1 #!/usr/bin/env python
2 ##################################################
3 # Gnuradio Python Flow Graph
4 # Title: USRP HRPT Receiver
5 # Generated: Sun Sep 27 13:37:23 2009
6 ##################################################
7
8 from gnuradio import eng_notation
9 from gnuradio import gr
10 from gnuradio import noaa
11 from gnuradio.eng_option import eng_option
12 from gnuradio.gr import firdes
13 from gnuradio.wxgui import fftsink2
14 from gnuradio.wxgui import forms
15 from gnuradio.wxgui import scopesink2
16 from grc_gnuradio import usrp as grc_usrp
17 from grc_gnuradio import wxgui as grc_wxgui
18 from optparse import OptionParser
19 import ConfigParser
20 import math
21 import wx
22
23 class usrp_rx_hrpt(grc_wxgui.top_block_gui):
24
25         def __init__(self):
26                 grc_wxgui.top_block_gui.__init__(self, title="USRP HRPT Receiver")
27
28                 ##################################################
29                 # Variables
30                 ##################################################
31                 self.config_filename = config_filename = 'usrp_rx_hrpt.cfg'
32                 self._decim_config = ConfigParser.ConfigParser()
33                 self._decim_config.read(config_filename)
34                 try: decim = self._decim_config.getfloat('usrp', 'decim')
35                 except: decim = 16
36                 self.decim = decim
37                 self.sym_rate = sym_rate = 600*1109
38                 self.sample_rate = sample_rate = 64e6/decim
39                 self.sps = sps = sample_rate/sym_rate
40                 self._side_config = ConfigParser.ConfigParser()
41                 self._side_config.read(config_filename)
42                 try: side = self._side_config.get('usrp', 'side')
43                 except: side = 'A'
44                 self.side = side
45                 self._saved_sync_alpha_config = ConfigParser.ConfigParser()
46                 self._saved_sync_alpha_config.read(config_filename)
47                 try: saved_sync_alpha = self._saved_sync_alpha_config.getfloat('demod', 'sync_alpha')
48                 except: saved_sync_alpha = 0.05
49                 self.saved_sync_alpha = saved_sync_alpha
50                 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
51                 self._saved_pll_alpha_config.read(config_filename)
52                 try: saved_pll_alpha = self._saved_pll_alpha_config.getfloat('demod', 'pll_alpha')
53                 except: saved_pll_alpha = 0.05
54                 self.saved_pll_alpha = saved_pll_alpha
55                 self._saved_gain_config = ConfigParser.ConfigParser()
56                 self._saved_gain_config.read(config_filename)
57                 try: saved_gain = self._saved_gain_config.getfloat('usrp', 'gain')
58                 except: saved_gain = 35
59                 self.saved_gain = saved_gain
60                 self._saved_freq_config = ConfigParser.ConfigParser()
61                 self._saved_freq_config.read(config_filename)
62                 try: saved_freq = self._saved_freq_config.getfloat('usrp', 'freq')
63                 except: saved_freq = 1698e6
64                 self.saved_freq = saved_freq
65                 self.hs = hs = int(sps/2.0)
66                 self.sync_alpha = sync_alpha = saved_sync_alpha
67                 self.side_text = side_text = side
68                 self.pll_alpha = pll_alpha = saved_pll_alpha
69                 self._output_filename_config = ConfigParser.ConfigParser()
70                 self._output_filename_config.read(config_filename)
71                 try: output_filename = self._output_filename_config.get('output', 'filename')
72                 except: output_filename = 'frames.dat'
73                 self.output_filename = output_filename
74                 self.mf_taps = mf_taps = [-0.5/hs,]*hs+[0.5/hs]*hs
75                 self.max_sync_offset = max_sync_offset = 0.01
76                 self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate
77                 self.gain = gain = saved_gain
78                 self.freq = freq = saved_freq
79                 self.decim_text = decim_text = decim
80
81                 ##################################################
82                 # Notebooks
83                 ##################################################
84                 self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
85                 self.displays.AddPage(grc_wxgui.Panel(self.displays), "RX")
86                 self.displays.AddPage(grc_wxgui.Panel(self.displays), "Demod")
87                 self.GridAdd(self.displays, 2, 0, 1, 4)
88
89                 ##################################################
90                 # Controls
91                 ##################################################
92                 _sync_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
93                 self._sync_alpha_text_box = forms.text_box(
94                         parent=self.GetWin(),
95                         sizer=_sync_alpha_sizer,
96                         value=self.sync_alpha,
97                         callback=self.set_sync_alpha,
98                         label="SYNC Alpha",
99                         converter=forms.float_converter(),
100                         proportion=0,
101                 )
102                 self._sync_alpha_slider = forms.slider(
103                         parent=self.GetWin(),
104                         sizer=_sync_alpha_sizer,
105                         value=self.sync_alpha,
106                         callback=self.set_sync_alpha,
107                         minimum=0.0,
108                         maximum=0.5,
109                         num_steps=100,
110                         style=wx.SL_HORIZONTAL,
111                         cast=float,
112                         proportion=1,
113                 )
114                 self.GridAdd(_sync_alpha_sizer, 0, 3, 1, 1)
115                 self._side_text_static_text = forms.static_text(
116                         parent=self.GetWin(),
117                         value=self.side_text,
118                         callback=self.set_side_text,
119                         label="USRP Side",
120                         converter=forms.str_converter(),
121                 )
122                 self.GridAdd(self._side_text_static_text, 1, 0, 1, 1)
123                 _pll_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
124                 self._pll_alpha_text_box = forms.text_box(
125                         parent=self.GetWin(),
126                         sizer=_pll_alpha_sizer,
127                         value=self.pll_alpha,
128                         callback=self.set_pll_alpha,
129                         label="PLL Alpha",
130                         converter=forms.float_converter(),
131                         proportion=0,
132                 )
133                 self._pll_alpha_slider = forms.slider(
134                         parent=self.GetWin(),
135                         sizer=_pll_alpha_sizer,
136                         value=self.pll_alpha,
137                         callback=self.set_pll_alpha,
138                         minimum=0.0,
139                         maximum=0.5,
140                         num_steps=100,
141                         style=wx.SL_HORIZONTAL,
142                         cast=float,
143                         proportion=1,
144                 )
145                 self.GridAdd(_pll_alpha_sizer, 0, 2, 1, 1)
146                 _gain_sizer = wx.BoxSizer(wx.VERTICAL)
147                 self._gain_text_box = forms.text_box(
148                         parent=self.GetWin(),
149                         sizer=_gain_sizer,
150                         value=self.gain,
151                         callback=self.set_gain,
152                         label="RX Gain",
153                         converter=forms.float_converter(),
154                         proportion=0,
155                 )
156                 self._gain_slider = forms.slider(
157                         parent=self.GetWin(),
158                         sizer=_gain_sizer,
159                         value=self.gain,
160                         callback=self.set_gain,
161                         minimum=0,
162                         maximum=100,
163                         num_steps=100,
164                         style=wx.SL_HORIZONTAL,
165                         cast=float,
166                         proportion=1,
167                 )
168                 self.GridAdd(_gain_sizer, 0, 1, 1, 1)
169                 self._freq_text_box = forms.text_box(
170                         parent=self.GetWin(),
171                         value=self.freq,
172                         callback=self.set_freq,
173                         label="Frequency",
174                         converter=forms.float_converter(),
175                 )
176                 self.GridAdd(self._freq_text_box, 0, 0, 1, 1)
177                 self._decim_text_static_text = forms.static_text(
178                         parent=self.GetWin(),
179                         value=self.decim_text,
180                         callback=self.set_decim_text,
181                         label="Decimation",
182                         converter=forms.float_converter(),
183                 )
184                 self.GridAdd(self._decim_text_static_text, 1, 1, 1, 1)
185
186                 ##################################################
187                 # Blocks
188                 ##################################################
189                 self.agc = gr.agc_cc(1e-6, 1.0, 1.0, 1.0)
190                 self.decoder = noaa.hrpt_decoder()
191                 self.deframer = noaa.hrpt_deframer()
192                 self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename)
193                 self.gr_fir_filter_xxx_0 = gr.fir_filter_ccc(1, (mf_taps))
194                 self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset)
195                 self.pll_scope = scopesink2.scope_sink_f(
196                         self.displays.GetPage(1).GetWin(),
197                         title="Demod Waveform",
198                         sample_rate=sample_rate,
199                         v_scale=0.5,
200                         t_scale=20.0/sample_rate,
201                         ac_couple=False,
202                         xy_mode=False,
203                         num_inputs=1,
204                 )
205                 self.displays.GetPage(1).GridAdd(self.pll_scope.win, 0, 0, 1, 1)
206                 self.rx_fft = fftsink2.fft_sink_c(
207                         self.displays.GetPage(0).GetWin(),
208                         baseband_freq=freq,
209                         y_per_div=5,
210                         y_divs=8,
211                         ref_level=-5,
212                         ref_scale=2.0,
213                         sample_rate=sample_rate,
214                         fft_size=1024,
215                         fft_rate=15,
216                         average=True,
217                         avg_alpha=0.1,
218                         title="RX Spectrum",
219                         peak_hold=False,
220                 )
221                 self.displays.GetPage(0).GridAdd(self.rx_fft.win, 0, 0, 1, 1)
222                 self.rx_scope = scopesink2.scope_sink_c(
223                         self.displays.GetPage(0).GetWin(),
224                         title="RX Waveform",
225                         sample_rate=sample_rate,
226                         v_scale=0,
227                         t_scale=20.0/sample_rate,
228                         ac_couple=False,
229                         xy_mode=False,
230                         num_inputs=1,
231                 )
232                 self.displays.GetPage(0).GridAdd(self.rx_scope.win, 1, 0, 1, 1)
233                 self.sync = noaa.hrpt_sync_fb(sync_alpha, sync_alpha**2/4.0, sps, max_sync_offset)
234                 self.usrp_source = grc_usrp.simple_source_c(which=0, side=side, rx_ant="RXA")
235                 self.usrp_source.set_decim_rate(decim)
236                 self.usrp_source.set_frequency(freq, verbose=True)
237                 self.usrp_source.set_gain(gain)
238
239                 ##################################################
240                 # Connections
241                 ##################################################
242                 self.connect((self.deframer, 0), (self.frame_sink, 0))
243                 self.connect((self.sync, 0), (self.deframer, 0))
244                 self.connect((self.pll, 0), (self.sync, 0))
245                 self.connect((self.pll, 0), (self.pll_scope, 0))
246                 self.connect((self.agc, 0), (self.rx_scope, 0))
247                 self.connect((self.agc, 0), (self.rx_fft, 0))
248                 self.connect((self.deframer, 0), (self.decoder, 0))
249                 self.connect((self.agc, 0), (self.gr_fir_filter_xxx_0, 0))
250                 self.connect((self.gr_fir_filter_xxx_0, 0), (self.pll, 0))
251                 self.connect((self.usrp_source, 0), (self.agc, 0))
252
253         def set_config_filename(self, config_filename):
254                 self.config_filename = config_filename
255                 self._side_config = ConfigParser.ConfigParser()
256                 self._side_config.read(self.config_filename)
257                 if not self._side_config.has_section('usrp'):
258                         self._side_config.add_section('usrp')
259                 self._side_config.set('usrp', 'side', str(self.side))
260                 self._side_config.write(open(self.config_filename, 'w'))
261                 self._decim_config = ConfigParser.ConfigParser()
262                 self._decim_config.read(self.config_filename)
263                 if not self._decim_config.has_section('usrp'):
264                         self._decim_config.add_section('usrp')
265                 self._decim_config.set('usrp', 'decim', str(self.decim))
266                 self._decim_config.write(open(self.config_filename, 'w'))
267                 self._saved_freq_config = ConfigParser.ConfigParser()
268                 self._saved_freq_config.read(self.config_filename)
269                 if not self._saved_freq_config.has_section('usrp'):
270                         self._saved_freq_config.add_section('usrp')
271                 self._saved_freq_config.set('usrp', 'freq', str(self.freq))
272                 self._saved_freq_config.write(open(self.config_filename, 'w'))
273                 self._saved_gain_config = ConfigParser.ConfigParser()
274                 self._saved_gain_config.read(self.config_filename)
275                 if not self._saved_gain_config.has_section('usrp'):
276                         self._saved_gain_config.add_section('usrp')
277                 self._saved_gain_config.set('usrp', 'gain', str(self.gain))
278                 self._saved_gain_config.write(open(self.config_filename, 'w'))
279                 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
280                 self._saved_pll_alpha_config.read(self.config_filename)
281                 if not self._saved_pll_alpha_config.has_section('demod'):
282                         self._saved_pll_alpha_config.add_section('demod')
283                 self._saved_pll_alpha_config.set('demod', 'pll_alpha', str(self.pll_alpha))
284                 self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
285                 self._saved_sync_alpha_config = ConfigParser.ConfigParser()
286                 self._saved_sync_alpha_config.read(self.config_filename)
287                 if not self._saved_sync_alpha_config.has_section('demod'):
288                         self._saved_sync_alpha_config.add_section('demod')
289                 self._saved_sync_alpha_config.set('demod', 'sync_alpha', str(self.sync_alpha))
290                 self._saved_sync_alpha_config.write(open(self.config_filename, 'w'))
291                 self._output_filename_config = ConfigParser.ConfigParser()
292                 self._output_filename_config.read(self.config_filename)
293                 if not self._output_filename_config.has_section('output'):
294                         self._output_filename_config.add_section('output')
295                 self._output_filename_config.set('output', 'filename', str(self.output_filename))
296                 self._output_filename_config.write(open(self.config_filename, 'w'))
297
298         def set_decim(self, decim):
299                 self.decim = decim
300                 self.set_sample_rate(64e6/self.decim)
301                 self._decim_config = ConfigParser.ConfigParser()
302                 self._decim_config.read(self.config_filename)
303                 if not self._decim_config.has_section('usrp'):
304                         self._decim_config.add_section('usrp')
305                 self._decim_config.set('usrp', 'decim', str(self.decim))
306                 self._decim_config.write(open(self.config_filename, 'w'))
307                 self.set_decim_text(self.decim)
308                 self.usrp_source.set_decim_rate(self.decim)
309
310         def set_sym_rate(self, sym_rate):
311                 self.sym_rate = sym_rate
312                 self.set_sps(self.sample_rate/self.sym_rate)
313
314         def set_sample_rate(self, sample_rate):
315                 self.sample_rate = sample_rate
316                 self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate)
317                 self.set_sps(self.sample_rate/self.sym_rate)
318                 self.rx_scope.set_sample_rate(self.sample_rate)
319                 self.rx_fft.set_sample_rate(self.sample_rate)
320                 self.pll_scope.set_sample_rate(self.sample_rate)
321
322         def set_sps(self, sps):
323                 self.sps = sps
324                 self.set_hs(int(self.sps/2.0))
325
326         def set_side(self, side):
327                 self.side = side
328                 self.set_side_text(self.side)
329                 self._side_config = ConfigParser.ConfigParser()
330                 self._side_config.read(self.config_filename)
331                 if not self._side_config.has_section('usrp'):
332                         self._side_config.add_section('usrp')
333                 self._side_config.set('usrp', 'side', str(self.side))
334                 self._side_config.write(open(self.config_filename, 'w'))
335
336         def set_saved_sync_alpha(self, saved_sync_alpha):
337                 self.saved_sync_alpha = saved_sync_alpha
338                 self.set_sync_alpha(self.saved_sync_alpha)
339
340         def set_saved_pll_alpha(self, saved_pll_alpha):
341                 self.saved_pll_alpha = saved_pll_alpha
342                 self.set_pll_alpha(self.saved_pll_alpha)
343
344         def set_saved_gain(self, saved_gain):
345                 self.saved_gain = saved_gain
346                 self.set_gain(self.saved_gain)
347
348         def set_saved_freq(self, saved_freq):
349                 self.saved_freq = saved_freq
350                 self.set_freq(self.saved_freq)
351
352         def set_hs(self, hs):
353                 self.hs = hs
354                 self.set_mf_taps([-0.5/self.hs,]*self.hs+[0.5/self.hs]*self.hs)
355
356         def set_sync_alpha(self, sync_alpha):
357                 self.sync_alpha = sync_alpha
358                 self._sync_alpha_slider.set_value(self.sync_alpha)
359                 self._sync_alpha_text_box.set_value(self.sync_alpha)
360                 self._saved_sync_alpha_config = ConfigParser.ConfigParser()
361                 self._saved_sync_alpha_config.read(self.config_filename)
362                 if not self._saved_sync_alpha_config.has_section('demod'):
363                         self._saved_sync_alpha_config.add_section('demod')
364                 self._saved_sync_alpha_config.set('demod', 'sync_alpha', str(self.sync_alpha))
365                 self._saved_sync_alpha_config.write(open(self.config_filename, 'w'))
366                 self.sync.set_alpha(self.sync_alpha)
367                 self.sync.set_beta(self.sync_alpha**2/4.0)
368
369         def set_side_text(self, side_text):
370                 self.side_text = side_text
371                 self._side_text_static_text.set_value(self.side_text)
372
373         def set_pll_alpha(self, pll_alpha):
374                 self.pll_alpha = pll_alpha
375                 self._pll_alpha_slider.set_value(self.pll_alpha)
376                 self._pll_alpha_text_box.set_value(self.pll_alpha)
377                 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
378                 self._saved_pll_alpha_config.read(self.config_filename)
379                 if not self._saved_pll_alpha_config.has_section('demod'):
380                         self._saved_pll_alpha_config.add_section('demod')
381                 self._saved_pll_alpha_config.set('demod', 'pll_alpha', str(self.pll_alpha))
382                 self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
383                 self.pll.set_alpha(self.pll_alpha)
384                 self.pll.set_beta(self.pll_alpha**2/4.0)
385
386         def set_output_filename(self, output_filename):
387                 self.output_filename = output_filename
388                 self._output_filename_config = ConfigParser.ConfigParser()
389                 self._output_filename_config.read(self.config_filename)
390                 if not self._output_filename_config.has_section('output'):
391                         self._output_filename_config.add_section('output')
392                 self._output_filename_config.set('output', 'filename', str(self.output_filename))
393                 self._output_filename_config.write(open(self.config_filename, 'w'))
394
395         def set_mf_taps(self, mf_taps):
396                 self.mf_taps = mf_taps
397                 self.gr_fir_filter_xxx_0.set_taps((self.mf_taps))
398
399         def set_max_sync_offset(self, max_sync_offset):
400                 self.max_sync_offset = max_sync_offset
401                 self.sync.set_max_offset(self.max_sync_offset)
402
403         def set_max_carrier_offset(self, max_carrier_offset):
404                 self.max_carrier_offset = max_carrier_offset
405                 self.pll.set_max_offset(self.max_carrier_offset)
406
407         def set_gain(self, gain):
408                 self.gain = gain
409                 self._gain_slider.set_value(self.gain)
410                 self._gain_text_box.set_value(self.gain)
411                 self._saved_gain_config = ConfigParser.ConfigParser()
412                 self._saved_gain_config.read(self.config_filename)
413                 if not self._saved_gain_config.has_section('usrp'):
414                         self._saved_gain_config.add_section('usrp')
415                 self._saved_gain_config.set('usrp', 'gain', str(self.gain))
416                 self._saved_gain_config.write(open(self.config_filename, 'w'))
417                 self.usrp_source.set_gain(self.gain)
418
419         def set_freq(self, freq):
420                 self.freq = freq
421                 self._freq_text_box.set_value(self.freq)
422                 self._saved_freq_config = ConfigParser.ConfigParser()
423                 self._saved_freq_config.read(self.config_filename)
424                 if not self._saved_freq_config.has_section('usrp'):
425                         self._saved_freq_config.add_section('usrp')
426                 self._saved_freq_config.set('usrp', 'freq', str(self.freq))
427                 self._saved_freq_config.write(open(self.config_filename, 'w'))
428                 self.usrp_source.set_frequency(self.freq)
429                 self.rx_fft.set_baseband_freq(self.freq)
430
431         def set_decim_text(self, decim_text):
432                 self.decim_text = decim_text
433                 self._decim_text_static_text.set_value(self.decim_text)
434
435 if __name__ == '__main__':
436         parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
437         (options, args) = parser.parse_args()
438         tb = usrp_rx_hrpt()
439         tb.Run(True)
440