switch source package format to 3.0 quilt
[debian/gnuradio] / gr-msdd6000 / src / python-examples / msdd_fft.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2004,2005,2007 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
24 from gnuradio import msdd
25 from gnuradio import eng_notation
26 from gnuradio.eng_option import eng_option
27 from gnuradio.wxgui import stdgui2, fftsink2, waterfallsink2, scopesink2, form, slider
28 from optparse import OptionParser
29 import wx
30 import sys
31
32
33 def pick_subdevice(u):
34     """
35     The user didn't specify a subdevice on the command line.
36     If there's a daughterboard on A, select A.
37     If there's a daughterboard on B, select B.
38     Otherwise, select A.
39     """
40     if u.db[0][0].dbid() >= 0:       # dbid is < 0 if there's no d'board or a problem
41         return (0, 0)
42     if u.db[1][0].dbid() >= 0:
43         return (1, 0)
44     return (0, 0)
45
46
47 class app_top_block(stdgui2.std_top_block):
48     def __init__(self, frame, panel, vbox, argv):
49         stdgui2.std_top_block.__init__(self, frame, panel, vbox, argv)
50
51         self.frame = frame
52         self.panel = panel
53         
54         parser = OptionParser(option_class=eng_option)
55         parser.add_option("-w", "--which", type="int", default=0,
56                           help="select which MSDD (0, 1, ...) default is %default",
57                           metavar="NUM")
58         parser.add_option("-R", "--rx-subdev-spec", type="subdev", default=None,
59                           help="select MSDD Rx side A or B (default=first one with a daughterboard)")
60         parser.add_option("-A", "--antenna", default=None,
61                           help="select Rx Antenna (only on RFX-series boards)")
62         parser.add_option("-d", "--decim", type="int", default=16,
63                           help="set fgpa decimation rate to DECIM [default=%default]")
64         parser.add_option("-f", "--freq", type="eng_float", default=None,
65                           help="set frequency to FREQ", metavar="FREQ")
66         parser.add_option("-g", "--gain", type="eng_float", default=None,
67                           help="set gain in dB (default is midpoint)")
68         parser.add_option("-W", "--waterfall", action="store_true", default=False,
69                           help="Enable waterfall display")
70         parser.add_option("-8", "--width-8", action="store_true", default=False,
71                           help="Enable 8-bit samples across USB")
72         parser.add_option("-S", "--oscilloscope", action="store_true", default=False,
73                           help="Enable oscilloscope display")
74         (options, args) = parser.parse_args()
75         if len(args) != 0:
76             parser.print_help()
77             sys.exit(1)
78
79         self.show_debug_info = True
80         
81         # build the graph
82
83         #self.u = MSDD.source_simo(which=options.which, decim_rate=options.decim)
84         self.u = msdd.source_simple("192.168.1.200", 0)
85         self.u.set_decim_rate(options.decim) #(16)
86
87 #        msdd_src = gr.file_source(gr.sizeof_gr_complex, 'msdd.dat')
88 #        thr = gr.throttle(gr.sizeof_gr_complex, 200000)
89 #        self.connect(msdd_src, thr)
90
91 #        if options.rx_subdev_spec is None:
92 #           options.rx_subdev_spec = pick_subdevice(self.u)
93 #        self.u.set_mux(MSDD.determine_rx_mux_value(self.u, options.rx_subdev_spec))
94
95 #        if options.width_8:
96 #            width = 8
97 #            shift = 8
98 #            format = self.u.make_format(width, shift)
99 #            print "format =", hex(format)
100 #            r = self.u.set_format(format)
101 #            print "set_format =", r
102             
103         # determine the daughterboard subdevice we're using
104 #        self.subdev = MSDD.selected_subdev(self.u, options.rx_subdev_spec)
105
106 #        print "Initial Freq", self.u.rx_freq(0), "deci: ", self.u.decim_rate()
107 #        input_rate = 50e6 / self.u.decim_rate()
108         input_rate = 50e6 / options.decim;
109
110         if options.waterfall:
111             self.scope = \
112               waterfallsink2.waterfall_sink_c (panel, fft_size=1024, sample_rate=input_rate)
113         elif options.oscilloscope:
114             self.scope = scopesink2.scope_sink_c(panel, sample_rate=input_rate)
115         else:
116             self.scope = fftsink2.fft_sink_c (panel, fft_size=1024, sample_rate=input_rate)
117
118 #        self.connect(self.u, self.scope)
119                
120         msdd_sink = gr.file_sink(gr.sizeof_gr_complex, 'schmen1.dat')
121         
122         self.conv = gr.interleaved_short_to_complex();
123         self.connect(self.u, self.conv,  msdd_sink)
124         self._build_gui(vbox)
125
126         # set initial values
127
128         if options.gain is None:
129             # if no gain was specified, use the mid-point in dB
130             #g = self.subdev.gain_range()
131             self.gain_range = (20,70,.5);
132             options.gain = float(self.gain_range[0]+self.gain_range[1])/2
133
134         if options.freq is None:
135             # if no freq was specified, use the mid-point
136             #r = self.subdev.freq_range()
137             r = (30e6,6e9,1e6)
138             options.freq = float(r[0]+r[1])/2
139
140         self.set_gain(options.gain)
141 #
142 #       if options.antenna is not None:
143 #            print "Selecting antenna %s" % (options.antenna,)
144 #            self.subdev.select_rx_antenna(options.antenna)
145
146         if self.show_debug_info:
147             #self.myform['decim'].set_value(self.u.decim_rate())
148             self.myform['decim'].set_value(options.decim)
149  #           self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
150  #           self.myform['dbname'].set_value(self.subdev.name())
151             self.myform['baseband'].set_value(0)
152             self.myform['ddc'].set_value(0)
153
154         if not(self.set_freq(options.freq)):
155             self._set_status_msg("Failed to set initial frequency")
156
157     def _set_status_msg(self, msg):
158         self.frame.GetStatusBar().SetStatusText(msg, 0)
159
160     def _build_gui(self, vbox):
161
162         def _form_set_freq(kv):
163             return self.set_freq(kv['freq'])
164             
165         vbox.Add(self.scope.win, 10, wx.EXPAND)
166         
167         # add control area at the bottom
168         self.myform = myform = form.form()
169         hbox = wx.BoxSizer(wx.HORIZONTAL)
170         hbox.Add((5,0), 0, 0)
171         myform['freq'] = form.float_field(
172             parent=self.panel, sizer=hbox, label="Center freq", weight=1,
173             callback=myform.check_input_and_call(_form_set_freq, self._set_status_msg))
174
175         hbox.Add((5,0), 0, 0)
176         g = self.gain_range = (20,50,.5);
177         myform['gain'] = form.slider_field(parent=self.panel, sizer=hbox, label="Gain",
178                                            weight=3,
179                                            min=int(g[0]), max=int(g[1]),
180                                            callback=self.set_gain)
181
182         hbox.Add((5,0), 0, 0)
183         vbox.Add(hbox, 0, wx.EXPAND)
184
185         self._build_subpanel(vbox)
186
187     def _build_subpanel(self, vbox_arg):
188         # build a secondary information panel (sometimes hidden)
189
190         # FIXME figure out how to have this be a subpanel that is always
191         # created, but has its visibility controlled by foo.Show(True/False)
192         
193         def _form_set_decim(kv):
194             return self.set_decim(kv['decim'])
195
196         if not(self.show_debug_info):
197             return
198
199         panel = self.panel
200         vbox = vbox_arg
201         myform = self.myform
202
203         #panel = wx.Panel(self.panel, -1)
204         #vbox = wx.BoxSizer(wx.VERTICAL)
205
206         hbox = wx.BoxSizer(wx.HORIZONTAL)
207         hbox.Add((5,0), 0)
208
209         myform['decim'] = form.int_field(
210             parent=panel, sizer=hbox, label="Decim",
211             callback=myform.check_input_and_call(_form_set_decim, self._set_status_msg))
212
213 #        hbox.Add((5,0), 1)
214 #        myform['fs@usb'] = form.static_float_field(
215 #            parent=panel, sizer=hbox, label="Fs@USB")
216
217         hbox.Add((5,0), 1)
218         myform['dbname'] = form.static_text_field(
219             parent=panel, sizer=hbox)
220
221         hbox.Add((5,0), 1)
222         myform['baseband'] = form.static_float_field(
223             parent=panel, sizer=hbox, label="Analog BB")
224
225         hbox.Add((5,0), 1)
226         myform['ddc'] = form.static_float_field(
227             parent=panel, sizer=hbox, label="DDC")
228
229         hbox.Add((5,0), 0)
230         vbox.Add(hbox, 0, wx.EXPAND)
231
232         
233     def set_freq(self, target_freq):
234         """
235         Set the center frequency we're interested in.
236
237         @param target_freq: frequency in Hz
238         @rypte: bool
239
240         Tuning is a two step process.  First we ask the front-end to
241         tune as close to the desired frequency as it can.  Then we use
242         the result of that operation and our target_frequency to
243         determine the value for the digital down converter.
244         """
245         r = self.u.set_rx_freq  (0, target_freq)
246         #r = self.u.tune(0, self.subdev, target_freq)
247         if r:
248             self.myform['freq'].set_value(target_freq)     # update displayed value
249 #            if self.show_debug_info:
250 #                self.myform['baseband'].set_value(r.baseband_freq)
251 #                self.myform['ddc'].set_value(r.dxc_freq)
252             return True
253
254         return False
255
256     def set_gain(self, gain):
257         self.myform['gain'].set_value(gain)     # update displayed value
258         #self.subdev.set_gain(gain)
259         self.u.set_pga(0, gain)
260
261     def set_decim(self, decim):
262         ok = self.u.set_decim_rate(decim)
263         if not ok:
264             print "set_decim failed"
265         #input_rate = 20e6 / self.u.decim_rate()
266         #self.scope.set_sample_rate(input_rate)
267         if self.show_debug_info:  # update displayed values
268             self.myform['decim'].set_value(decim)
269             #self.myform['fs@usb'].set_value(self.u.adc_freq() / self.u.decim_rate())
270         return ok
271
272 def main ():
273     app = stdgui2.stdapp(app_top_block, "MSDD FFT", nstatus=1)
274     app.MainLoop()
275
276 if __name__ == '__main__':
277     main ()