2 ##################################################
3 # Gnuradio Python Flow Graph
4 # Title: USRP HRPT Receiver
5 # Generated: Mon Nov 9 07:47:17 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=32):
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.01
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.01
50 self.saved_clock_alpha = saved_clock_alpha
51 self.pll_alpha = pll_alpha = saved_pll_alpha
52 self._output_filename_config = ConfigParser.ConfigParser()
53 self._output_filename_config.read(config_filename)
54 try: output_filename = self._output_filename_config.get('usrp_rx_hrpt', 'filename')
55 except: output_filename = 'frames.hrpt'
56 self.output_filename = output_filename
57 self.max_clock_offset = max_clock_offset = 100e-6
58 self.max_carrier_offset = max_carrier_offset = 2*math.pi*100e3/sample_rate
59 self.hs = hs = int(sps/2.0)
60 self.clock_alpha = clock_alpha = saved_clock_alpha
62 ##################################################
64 ##################################################
65 self.displays = wx.Notebook(self.GetWin(), style=wx.NB_TOP)
66 self.displays.AddPage(grc_wxgui.Panel(self.displays), "Spectrum")
67 self.displays.AddPage(grc_wxgui.Panel(self.displays), "Demod")
68 self.GridAdd(self.displays, 1, 0, 1, 2)
70 ##################################################
72 ##################################################
73 _pll_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
74 self._pll_alpha_text_box = forms.text_box(
76 sizer=_pll_alpha_sizer,
78 callback=self.set_pll_alpha,
80 converter=forms.float_converter(),
83 self._pll_alpha_slider = forms.slider(
85 sizer=_pll_alpha_sizer,
87 callback=self.set_pll_alpha,
91 style=wx.SL_HORIZONTAL,
95 self.GridAdd(_pll_alpha_sizer, 0, 0, 1, 1)
96 _clock_alpha_sizer = wx.BoxSizer(wx.VERTICAL)
97 self._clock_alpha_text_box = forms.text_box(
99 sizer=_clock_alpha_sizer,
100 value=self.clock_alpha,
101 callback=self.set_clock_alpha,
103 converter=forms.float_converter(),
106 self._clock_alpha_slider = forms.slider(
107 parent=self.GetWin(),
108 sizer=_clock_alpha_sizer,
109 value=self.clock_alpha,
110 callback=self.set_clock_alpha,
114 style=wx.SL_HORIZONTAL,
118 self.GridAdd(_clock_alpha_sizer, 0, 1, 1, 1)
120 ##################################################
122 ##################################################
123 self.agc = gr.agc_cc(1e-6, 1.0, 1.0, 1.0)
124 self.decoder = noaa.hrpt_decoder(True,False)
125 self.deframer = noaa.hrpt_deframer()
126 self.demod_scope = scopesink2.scope_sink_f(
127 self.displays.GetPage(1).GetWin(),
129 sample_rate=sym_rate*2.0,
132 t_scale=10.0/sym_rate,
137 self.displays.GetPage(1).GridAdd(self.demod_scope.win, 0, 0, 1, 1)
138 self.frame_sink = gr.file_sink(gr.sizeof_short*1, output_filename)
139 self.gr_binary_slicer_fb_0 = gr.binary_slicer_fb()
140 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)
141 self.gr_file_source_0 = gr.file_source(gr.sizeof_short*1, input_filename, False)
142 self.gr_interleaved_short_to_complex_0 = gr.interleaved_short_to_complex()
143 self.gr_moving_average_xx_0 = gr.moving_average_ff(hs, 1.0/hs, 4000)
144 self.pll = noaa.hrpt_pll_cf(pll_alpha, pll_alpha**2/4.0, max_carrier_offset)
145 self.rx_fft = fftsink2.fft_sink_c(
146 self.displays.GetPage(0).GetWin(),
152 sample_rate=sample_rate,
161 self.displays.GetPage(0).GridAdd(self.rx_fft.win, 0, 0, 1, 1)
162 self.throttle = gr.throttle(gr.sizeof_short*1, 2*sample_rate)
164 ##################################################
166 ##################################################
167 self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.gr_binary_slicer_fb_0, 0))
168 self.connect((self.deframer, 0), (self.frame_sink, 0))
169 self.connect((self.deframer, 0), (self.decoder, 0))
170 self.connect((self.gr_clock_recovery_mm_xx_0, 0), (self.demod_scope, 0))
171 self.connect((self.gr_moving_average_xx_0, 0), (self.gr_clock_recovery_mm_xx_0, 0))
172 self.connect((self.pll, 0), (self.gr_moving_average_xx_0, 0))
173 self.connect((self.agc, 0), (self.pll, 0))
174 self.connect((self.agc, 0), (self.rx_fft, 0))
175 self.connect((self.gr_interleaved_short_to_complex_0, 0), (self.agc, 0))
176 self.connect((self.throttle, 0), (self.gr_interleaved_short_to_complex_0, 0))
177 self.connect((self.gr_file_source_0, 0), (self.throttle, 0))
178 self.connect((self.gr_binary_slicer_fb_0, 0), (self.deframer, 0))
180 def set_input_filename(self, input_filename):
181 self.input_filename = input_filename
183 def set_decim(self, decim):
185 self.set_sample_rate(64e6/self.decim)
187 def set_sym_rate(self, sym_rate):
188 self.sym_rate = sym_rate
189 self.set_sps(self.sample_rate/self.sym_rate)
190 self.demod_scope.set_sample_rate(self.sym_rate*2.0)
192 def set_sample_rate(self, sample_rate):
193 self.sample_rate = sample_rate
194 self.set_sps(self.sample_rate/self.sym_rate)
195 self.rx_fft.set_sample_rate(self.sample_rate)
196 self.set_max_carrier_offset(2*math.pi*100e3/self.sample_rate)
198 def set_config_filename(self, config_filename):
199 self.config_filename = config_filename
200 self._output_filename_config = ConfigParser.ConfigParser()
201 self._output_filename_config.read(self.config_filename)
202 if not self._output_filename_config.has_section('usrp_rx_hrpt'):
203 self._output_filename_config.add_section('usrp_rx_hrpt')
204 self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
205 self._output_filename_config.write(open(self.config_filename, 'w'))
206 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
207 self._saved_pll_alpha_config.read(self.config_filename)
208 if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'):
209 self._saved_pll_alpha_config.add_section('usrp_rx_hrpt')
210 self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
211 self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
212 self._saved_clock_alpha_config = ConfigParser.ConfigParser()
213 self._saved_clock_alpha_config.read(self.config_filename)
214 if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'):
215 self._saved_clock_alpha_config.add_section('usrp_rx_hrpt')
216 self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
217 self._saved_clock_alpha_config.write(open(self.config_filename, 'w'))
219 def set_sps(self, sps):
221 self.gr_clock_recovery_mm_xx_0.set_omega(self.sps/2.0)
222 self.set_hs(int(self.sps/2.0))
224 def set_saved_pll_alpha(self, saved_pll_alpha):
225 self.saved_pll_alpha = saved_pll_alpha
226 self.set_pll_alpha(self.saved_pll_alpha)
228 def set_saved_clock_alpha(self, saved_clock_alpha):
229 self.saved_clock_alpha = saved_clock_alpha
230 self.set_clock_alpha(self.saved_clock_alpha)
232 def set_pll_alpha(self, pll_alpha):
233 self.pll_alpha = pll_alpha
234 self.pll.set_alpha(self.pll_alpha)
235 self.pll.set_beta(self.pll_alpha**2/4.0)
236 self._pll_alpha_slider.set_value(self.pll_alpha)
237 self._pll_alpha_text_box.set_value(self.pll_alpha)
238 self._saved_pll_alpha_config = ConfigParser.ConfigParser()
239 self._saved_pll_alpha_config.read(self.config_filename)
240 if not self._saved_pll_alpha_config.has_section('usrp_rx_hrpt'):
241 self._saved_pll_alpha_config.add_section('usrp_rx_hrpt')
242 self._saved_pll_alpha_config.set('usrp_rx_hrpt', 'pll_alpha', str(self.pll_alpha))
243 self._saved_pll_alpha_config.write(open(self.config_filename, 'w'))
245 def set_output_filename(self, output_filename):
246 self.output_filename = output_filename
247 self._output_filename_config = ConfigParser.ConfigParser()
248 self._output_filename_config.read(self.config_filename)
249 if not self._output_filename_config.has_section('usrp_rx_hrpt'):
250 self._output_filename_config.add_section('usrp_rx_hrpt')
251 self._output_filename_config.set('usrp_rx_hrpt', 'filename', str(self.output_filename))
252 self._output_filename_config.write(open(self.config_filename, 'w'))
254 def set_max_clock_offset(self, max_clock_offset):
255 self.max_clock_offset = max_clock_offset
257 def set_max_carrier_offset(self, max_carrier_offset):
258 self.max_carrier_offset = max_carrier_offset
259 self.pll.set_max_offset(self.max_carrier_offset)
261 def set_hs(self, hs):
263 self.gr_moving_average_xx_0.set_length_and_scale(self.hs, 1.0/self.hs)
265 def set_clock_alpha(self, clock_alpha):
266 self.clock_alpha = clock_alpha
267 self.gr_clock_recovery_mm_xx_0.set_gain_omega(self.clock_alpha**2/4.0)
268 self.gr_clock_recovery_mm_xx_0.set_gain_mu(self.clock_alpha)
269 self._clock_alpha_slider.set_value(self.clock_alpha)
270 self._clock_alpha_text_box.set_value(self.clock_alpha)
271 self._saved_clock_alpha_config = ConfigParser.ConfigParser()
272 self._saved_clock_alpha_config.read(self.config_filename)
273 if not self._saved_clock_alpha_config.has_section('usrp_rx_hrpt'):
274 self._saved_clock_alpha_config.add_section('usrp_rx_hrpt')
275 self._saved_clock_alpha_config.set('usrp_rx_hrpt', 'clock_alpha', str(self.clock_alpha))
276 self._saved_clock_alpha_config.write(open(self.config_filename, 'w'))
278 if __name__ == '__main__':
279 parser = OptionParser(option_class=eng_option, usage="%prog: [options]")
280 parser.add_option("-F", "--input-filename", dest="input_filename", type="string", default="usrp.dat",
281 help="Set usrp.dat [default=%default]")
282 parser.add_option("-d", "--decim", dest="decim", type="intx", default=32,
283 help="Set decim [default=%default]")
284 (options, args) = parser.parse_args()
285 tb = file_rx_hrpt(input_filename=options.input_filename, decim=options.decim)