Imported Upstream version 3.2.2
[debian/gnuradio] / gr-utils / src / python / usrp2_siggen_gui.py
1 #!/usr/bin/env python
2 #
3 # Copyright 2009 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 import wx
24 from gnuradio.wxgui import form, slider, gui
25 import usrp2_siggen
26 import sys, math
27
28 class app_gui(object):
29     def __init__(self, frame, panel, vbox, top_block, options, args):
30         self.frame = frame      # Use for top-level application window frame
31         self.panel = panel      # Use as parent class for created windows
32         self.vbox = vbox        # Use as sizer for created windows
33         self.tb = top_block     # GUI-unaware flowgraph class
34         self.options = options  # Supplied command-line options
35         self.args = args        # Supplied command-line arguments
36
37         freq_range = self.tb.freq_range()
38         self.min_freq = freq_range[0]
39         self.max_freq = freq_range[1]
40         self.freq_step = (self.max_freq-self.min_freq)/100.0
41         self._types = dict([v, k] for k, v in usrp2_siggen.waveforms.items())
42
43         self.build_gui()
44
45         # TODO: turn these into listeners
46         self.myform['ifc'].set_value(self.tb.interface_name())
47         self.myform['mac'].set_value(self.tb.mac_addr())
48         dbid = self.tb.daughterboard_id()
49         self.myform['dbid'].set_value("%04x" % (dbid,))
50
51         w = usrp2_siggen.waveforms[self.tb.waveform_type()]
52         self.myform['type'].set_value(w)
53         self.myform['w1freq'].set_value(self.tb.waveform_freq())
54         self.myform['w2freq'].set_value(self.tb.waveform2_freq())
55
56         freq = self.tb.freq()
57         if freq is None:
58             self.evt_set_status_msg("Failed to set initial frequency")
59         else:
60             self.myform['freq'].set_value(freq)
61             self.myform['freq_slider'].set_value(self.tb.freq())
62
63         amp = self.tb.amplitude()
64         if (amp > 0.0):
65             db = 20*math.log10(amp)
66         else:
67             db = -100.0
68         self.myform['amp'].set_value(amp)
69         self.myform['amp_slider'].set_value(db)
70         self.myform['eth'].set_value(self.tb.eth_rate())
71         self.myform['gbe'].set_value(self.tb.eth_rate()*32)
72         self.myform['interp'].set_value(self.tb.interp_rate())
73         self.myform['DDC'].set_value(self.tb.ddc_freq())
74         self.myform['analog'].set_value(self.tb.baseband_freq())
75
76     # Event response handlers
77     def evt_set_status_msg(self, msg):
78         self.frame.SetStatusText(msg, 0)
79
80     def evt_set_freq1(self, kv):
81         return self.tb.set_waveform_freq(kv['w1freq'])
82
83     def evt_set_freq2(self, kv):
84         return self.tb.set_waveform2_freq(kv['w2freq'])
85
86     def evt_set_freq(self, kv):
87         if type(kv) == type(0.0):              # Set from slider
88             tr = self.tb.set_freq(kv)
89             if tr is not None:
90                 self.myform['freq'].set_value(kv)
91         else:                                  # Set from edit box
92             f = kv['freq']
93             tr = self.tb.set_freq(f)
94             if tr is not None:
95                 self.myform['freq_slider'].set_value(f)
96
97         if tr is not None:
98             self.myform['DDC'].set_value(tr.dxc_freq)
99             self.myform['analog'].set_value(tr.baseband_freq)
100
101         return (tr is not None)
102
103     def evt_set_amplitude(self, kv):
104         if type(kv) == type(0.0):              # Set from slider
105             amp = math.pow(10, kv/20.0)
106             self.myform['amp'].set_value(amp)
107             return self.tb.set_amplitude(amp)
108         else:                                  # Set from edit box
109             amp = kv['amp']
110             if amp < 0.0 or amp > 1.0:
111                 return False
112             if amp == 0.0:
113                 db = -100.0
114             else:
115                 db = 20*math.log10(amp)
116             self.myform['amp_slider'].set_value(db)
117             return self.tb.set_amplitude(amp)
118
119     def evt_set_interp(self):
120         interp = self.myform['interp'].get_value()
121         if self.tb.set_interp(interp):
122             eth_rate = self.tb.eth_rate()
123             self.myform['eth'].set_value(eth_rate)
124             self.myform['gbe'].set_value(eth_rate*32)
125             return True
126         return False
127
128     def evt_set_waveform_type(self, type):
129         # TODO: update frequency labels
130         return self.tb.set_waveform(self._types[type])
131
132     # GUI construction
133     def build_gui(self):
134         self.myform = myform = form.form()
135
136         # Baseband controls
137         bb_sbox = wx.StaticBox(parent=self.panel, label="Baseband Modulation")
138         bb_vbox = wx.StaticBoxSizer(bb_sbox, wx.VERTICAL) # Holds all baseband controls as unit
139
140         # First row of baseband controls (modulation type)
141         mod_hbox = wx.BoxSizer(wx.HORIZONTAL)
142         mod_hbox.Add((10,0), 0, 0)
143         myform['type'] = form.radiobox_field(
144             parent=self.panel, label="Type", sizer=mod_hbox, value=None,
145             callback=self.evt_set_waveform_type, weight=1, major_dimension=0,
146             choices=usrp2_siggen.waveforms.values() )
147         bb_vbox.Add((0,10), 0, 0)
148         bb_vbox.Add(mod_hbox, 0, wx.EXPAND)
149
150         # Second row of baseband controls (frequencies)
151         bbf_hbox = wx.BoxSizer(wx.HORIZONTAL)
152         bbf_hbox.Add((10,0), 0, 0)
153         myform['w1freq'] = form.float_field(
154             parent=self.panel, sizer=bbf_hbox, label="Frequency 1 (Hz)", weight=1,
155             callback=myform.check_input_and_call(self.evt_set_freq1, self.evt_set_status_msg) )
156         bbf_hbox.Add((10,0), 0, 0)
157         myform['w2freq'] = form.float_field(
158             parent=self.panel, sizer=bbf_hbox, label="Frequency 2 (Hz)", weight=1,
159             callback=myform.check_input_and_call(self.evt_set_freq2, self.evt_set_status_msg) )
160         bbf_hbox.Add((10,0), 0, 0)
161         
162         bb_vbox.Add((0,10), 0, 0)
163         bb_vbox.Add(bbf_hbox, 0, wx.EXPAND)
164
165         # Add baseband controls to top window sizer
166         self.vbox.Add((0,10), 0, 0)
167         self.vbox.Add(bb_vbox, 0, wx.EXPAND)
168
169         # Frequency controls
170         fc_sbox = wx.StaticBox(parent=self.panel, label="Center Frequency")
171         fc_vbox = wx.StaticBoxSizer(fc_sbox, wx.VERTICAL) # Holds all frequency controls as unit
172
173         # First row of frequency controls (center frequency)
174         freq_hbox = wx.BoxSizer(wx.HORIZONTAL)
175         freq_hbox.Add((10,0), 0, 0)
176         myform['freq'] = form.float_field(
177             parent=self.panel, sizer=freq_hbox, label=None, weight=1,
178             callback=myform.check_input_and_call(self.evt_set_freq, self.evt_set_status_msg) )
179         freq_hbox.Add((10,0), 0, 0)
180         myform['freq_slider'] = form.quantized_slider_field(
181             parent=self.panel, sizer=freq_hbox, label="Min-Max", weight=4,
182             range = (self.min_freq, self.max_freq, self.freq_step),
183             callback=self.evt_set_freq)
184         freq_hbox.Add((10,0), 0, 0)
185
186         fc_vbox.Add((10,0), 0, 0)
187         fc_vbox.Add(freq_hbox, 0, wx.EXPAND)
188
189         # Second row of frequency controls (results)
190         tr_hbox = wx.BoxSizer(wx.HORIZONTAL)
191         tr_hbox.Add((10,0), 0, 0)
192         myform['analog'] = form.static_float_field(
193             parent=self.panel, sizer=tr_hbox, label="Daughterboard: (Hz)", weight=1)
194         tr_hbox.Add((10,0), 0, 0)
195         myform['DDC'] = form.static_float_field(
196             parent=self.panel, sizer=tr_hbox, label="USRP2 DDC (Hz)", weight=1)
197         tr_hbox.Add((10,0), 0, 0)
198         fc_vbox.Add(tr_hbox, 0, wx.EXPAND)
199
200         # Add frequency controls to top window sizer
201         self.vbox.Add((0,10), 0, 0)
202         self.vbox.Add(fc_vbox, 0, wx.EXPAND)
203
204         # Amplitude row
205         amp_sbox = wx.StaticBox(parent=self.panel, label="Amplitude")
206         amp_hbox = wx.StaticBoxSizer(amp_sbox, wx.HORIZONTAL)
207         amp_hbox.Add((10,0), 0, 0)
208         myform['amp'] = form.float_field(
209             parent=self.panel, sizer=amp_hbox, label="Linear\n(0.0-1.0)", weight=1,
210             callback=myform.check_input_and_call(self.evt_set_amplitude, self.evt_set_status_msg) )
211         amp_hbox.Add((10,0), 0, 0)
212         myform['amp_slider'] = form.quantized_slider_field(
213             parent=self.panel, sizer=amp_hbox, label="dB Full Scale\n(-100-0)", weight=4,
214             range=(-100.0, 0.0, 1), callback=self.evt_set_amplitude)
215         amp_hbox.Add((10,0), 0, 0)
216         self.vbox.Add((0,10), 0, 0)
217         self.vbox.Add(amp_hbox, 0, wx.EXPAND)
218
219         # Sample rate row
220         sam_sbox = wx.StaticBox(parent=self.panel, label="Sample Rate")
221         sam_hbox = wx.StaticBoxSizer(sam_sbox, wx.HORIZONTAL)
222         sam_hbox.Add((10,0), 0, 0)
223         myform['interp'] = form.int_field(
224             parent=self.panel, sizer=sam_hbox, label="Interpolation", weight=1,
225             callback=self.evt_set_interp)
226         sam_hbox.Add((10,0), 0, 0)
227         myform['eth'] = form.static_float_field(
228             parent=self.panel, sizer=sam_hbox, label="Sample Rate (sps)", weight=1)
229         sam_hbox.Add((10,0), 0, 0)
230         myform['gbe'] = form.static_float_field(
231             parent=self.panel, sizer=sam_hbox, label="GbE Rate (bits/sec)", weight=1)
232         sam_hbox.Add((10,0), 0, 0)
233         self.vbox.Add((0,10), 0, 0)
234         self.vbox.Add(sam_hbox, 0, wx.EXPAND)
235
236         # USRP2 row
237         u2_sbox = wx.StaticBox(parent=self.panel, label="USRP2 Hardware")
238         u2_hbox = wx.StaticBoxSizer(u2_sbox, wx.HORIZONTAL)
239         u2_hbox.Add((10,0), 0, 0)
240         myform['ifc'] = form.static_text_field(parent=self.panel, sizer=u2_hbox, 
241                                                label="Interface", weight=2)
242         u2_hbox.Add((10,0), 0, 0)
243         myform['mac'] = form.static_text_field(parent=self.panel, sizer=u2_hbox, 
244                                                label="MAC Address", weight=2)
245         u2_hbox.Add((10,0), 0, 0)
246         myform['dbid'] = form.static_text_field(parent=self.panel, sizer=u2_hbox, 
247                                                 label="Daughterboard ID", weight=1)
248         self.vbox.Add((0,10), 0, 0)
249         self.vbox.Add(u2_hbox, 0, wx.EXPAND)
250         self.vbox.Add((0,20), 0, 0)
251
252 if __name__ == "__main__":
253     try:
254         # Get command line parameters
255         (options, args) = usrp2_siggen.get_options()
256
257         # Create the top block using these
258         tb = usrp2_siggen.top_block(options, args)
259
260         # Create the GUI application
261         app = gui.app(top_block=tb,                    # Constructed top block
262                       gui=app_gui,                     # User interface class
263                       options=options,                 # Command line options
264                       args=args,                       # Command line args
265                       title="USRP2 Signal Generator",  # Top window title
266                       nstatus=1,                       # Number of status lines
267                       start=True,                      # Whether to start flowgraph
268                       realtime=True)                   # Whether to set realtime priority
269
270         # And run it
271         app.MainLoop()
272
273     except RuntimeError, e:
274         print e
275         sys.exit(1)