3 # Copyright 2009 Free Software Foundation, Inc.
5 # This file is part of GNU Radio
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)
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.
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.
24 from gnuradio.wxgui import form, slider, gui
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
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())
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,))
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())
58 self.evt_set_status_msg("Failed to set initial frequency")
60 self.myform['freq'].set_value(freq)
61 self.myform['freq_slider'].set_value(self.tb.freq())
63 amp = self.tb.amplitude()
65 db = 20*math.log10(amp)
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())
76 # Event response handlers
77 def evt_set_status_msg(self, msg):
78 self.frame.SetStatusText(msg, 0)
80 def evt_set_freq1(self, kv):
81 return self.tb.set_waveform_freq(kv['w1freq'])
83 def evt_set_freq2(self, kv):
84 return self.tb.set_waveform2_freq(kv['w2freq'])
86 def evt_set_freq(self, kv):
87 if type(kv) == type(0.0): # Set from slider
88 tr = self.tb.set_freq(kv)
90 self.myform['freq'].set_value(kv)
91 else: # Set from edit box
93 tr = self.tb.set_freq(f)
95 self.myform['freq_slider'].set_value(f)
98 self.myform['DDC'].set_value(tr.dxc_freq)
99 self.myform['analog'].set_value(tr.baseband_freq)
101 return (tr is not None)
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
110 if amp < 0.0 or amp > 1.0:
115 db = 20*math.log10(amp)
116 self.myform['amp_slider'].set_value(db)
117 return self.tb.set_amplitude(amp)
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)
128 def evt_set_waveform_type(self, type):
129 # TODO: update frequency labels
130 return self.tb.set_waveform(self._types[type])
134 self.myform = myform = form.form()
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
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)
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)
162 bb_vbox.Add((0,10), 0, 0)
163 bb_vbox.Add(bbf_hbox, 0, wx.EXPAND)
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)
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
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)
186 fc_vbox.Add((10,0), 0, 0)
187 fc_vbox.Add(freq_hbox, 0, wx.EXPAND)
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)
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)
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)
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)
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)
252 if __name__ == "__main__":
254 # Get command line parameters
255 (options, args) = usrp2_siggen.get_options()
257 # Create the top block using these
258 tb = usrp2_siggen.top_block(options, args)
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
273 except RuntimeError, e: