Merged r10071:10164 from features/cppdb-test into trunk. Implements the fully native...
[debian/gnuradio] / grc / src / grc_gnuradio / usrp / simple_usrp.py
1 # Copyright 2008 Free Software Foundation, Inc.
2 #
3 # This file is part of GNU Radio
4 #
5 # GNU Radio is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3, or (at your option)
8 # any later version.
9 #
10 # GNU Radio is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with GNU Radio; see the file COPYING.  If not, write to
17 # the Free Software Foundation, Inc., 51 Franklin Street,
18 # Boston, MA 02110-1301, USA.
19 #
20
21 import sys
22 from gnuradio import usrp, gr
23
24 ####################################################################
25 # Helper Functions
26 ####################################################################
27
28 def _set_frequency(u, which, subdev, frequency, verbose=False):
29         """
30         Set the carrier frequency for the given subdevice.
31         @param u the usrp source/sink
32         @param which specifies the DDC/DUC number
33         @param frequency the carrier frequency in Hz
34         @param verbose if true, print usrp tuning information
35         """
36         r = u.tune(which, subdev, frequency)
37         if not verbose: return
38         print subdev.side_and_name()
39         if r:
40                 print "  r.baseband_frequency =", r.baseband_freq
41                 print "  r.dxc_frequency      =", r.dxc_freq
42                 print "  r.residual_frequency =", r.residual_freq
43                 print "  r.inverted      =", r.inverted
44         else: print >> sys.stderr, 'Error calling tune on subdevice.'
45
46 def _setup_rx_subdev(u, subdev_spec, ddc, gain, frequency, auto_tr=None, rx_ant=None):
47         """
48         Setup a usrp receive subdevice by setting gain and frequency.
49         Add the gain and frequency callbacks to the flow graph.
50         FlexRF: Handle auto transmit/receive and set the receive antenna.
51         @param u the usrp object
52         @param subdev_spec the sub-device specification
53         @param ddc which ddc to use: 0 or 1
54         @param gain the gain to set
55         @param frequency the frequency to tune
56         @param auto_tr auto transmit/receive True, False, or None
57         @param rx_ant the receive antenna: 'TX/RX', 'RX2', or None
58         @return the subdevice
59         """
60         subdev = usrp.selected_subdev(u, subdev_spec)#get the subdev
61         subdev.set_gain(gain)
62         _set_frequency(u, ddc, subdev, frequency, verbose=True)
63         if auto_tr is not None: subdev.set_auto_tr(auto_tr)
64         if rx_ant is not None: subdev.select_rx_antenna(rx_ant)
65         return subdev
66
67 def _setup_tx_subdev(u, subdev_spec, gain, frequency, auto_tr=None, tx_enb=None):
68         """
69         Setup a usrp receive subdevice by setting gain and frequency.
70         Add the gain and frequency callbacks to the flow graph.
71         FlexRF: Handle auto transmit/receive and enable the transmitter.
72         @param u the usrp object
73         @param subdev_spec the sub-device specification
74         @param gain the gain to set
75         @param frequency the frequency to tune
76         @param auto_tr auto transmit/receive True, False, or None
77         @param tx_enb the transmit enable: True, False, or None
78         @return the subdevice
79         """
80         subdev = usrp.selected_subdev(u, subdev_spec)#get the subdev
81         subdev.set_gain(gain)
82         _set_frequency(u, subdev.which(), subdev, frequency, verbose=True)
83         if auto_tr is not None: subdev.set_auto_tr(auto_tr)
84         if tx_enb is not None: subdev.set_enable(tx_enb)
85         return subdev
86
87 ##map the usrp contructors to IO sizes
88 constructor_to_size = {
89         usrp.source_c: gr.sizeof_gr_complex,
90         usrp.sink_c: gr.sizeof_gr_complex,
91         usrp.source_s: gr.sizeof_short,
92         usrp.sink_s: gr.sizeof_short,
93 }
94
95 ####################################################################
96 ####################################################################
97 # Simple USRP Base Classes
98 ####################################################################
99 ####################################################################
100
101 class _simple_usrp(object):
102         """A single usrp source/sink base class."""
103
104         def __init__(self, u, subdev, which):
105                 """
106                 Create a simple usrp base class.
107                 @param u the usrp object
108                 @param subdev the subdevice object
109                 @param which specifies the DDC/DUC number when tuning
110                 """
111                 self._u = u
112                 self._subdev = subdev
113                 self._which = which
114
115         def get_u(self):
116                 """
117                 Get the underlying usrp object.
118                 @return the usrp source/sink object.
119                 """
120                 return self._u
121
122         def get_subdev(self):
123                 """
124                 Get the underlying subdevice.
125                 @return the subdev object.
126                 """
127                 return self._subdev
128
129         def set_frequency(self, frequency):
130                 """
131                 Set the frequency of the subdevice.
132                 @param frequency the frequency to tune
133                 """
134                 _set_frequency(self.get_u(), self._which, self.get_subdev(), frequency)
135
136         def set_gain(self, gain):
137                 """
138                 Set the gain of the subdevice.
139                 @param gain the gain to set
140                 """
141                 self.get_subdev().set_gain(gain)
142
143 ####################################################################
144 # Simple USRP Source
145 ####################################################################
146 class _simple_source(gr.hier_block2, _simple_usrp):
147         """A single usrp source of IO type short or complex."""
148
149         def __init__(self, number, subdev_spec, frequency, decimation, gain, mux=None, auto_tr=None, rx_ant=None):
150                 """
151                 USRP simple source contructor.
152                 @param number the unit number
153                 @param subdev_spec the sub-device specification tuple
154                 @param frequency the frequency to tune
155                 @param decimation the device decimation
156                 @param gain the gain to set
157                 @param mux the mux in hex or None
158                 @param auto_tr auto transmit/receive True, False, or None
159                 @param rx_ant the receive antenna: 'TX/RX', 'RX2', or None
160                 """
161                 #initialize hier2 block
162                 gr.hier_block2.__init__(
163                         self, 'usrp_simple_source',
164                         gr.io_signature(0, 0, 0),
165                         gr.io_signature(1, 1, constructor_to_size[self.constructor[0]]),
166                 )
167                 #create usrp object
168                 u = self.constructor[0](number, nchan=1)
169                 if subdev_spec is None: subdev_spec = usrp.pick_rx_subdevice(u)
170                 u.set_decim_rate(decimation)
171                 if mux is None: mux = usrp.determine_rx_mux_value(u, subdev_spec)
172                 u.set_mux(mux)
173                 subdev = _setup_rx_subdev(u, subdev_spec, 0, gain, frequency, auto_tr, rx_ant)
174                 _simple_usrp.__init__(self, u, subdev, 0)
175                 #connect
176                 self.connect(u, self)
177
178         def set_decim_rate(self, decim): self.get_u().set_decim_rate(int(decim))
179
180 class simple_source_c(_simple_source): constructor = (usrp.source_c, )
181 class simple_source_s(_simple_source): constructor = (usrp.source_s, )
182
183 ####################################################################
184 # Simple USRP Sink
185 ####################################################################
186 class _simple_sink(gr.hier_block2, _simple_usrp):
187         """A single usrp sink of IO type short or complex."""
188
189         def __init__(self, number, subdev_spec, frequency, interpolation, gain, mux=None, auto_tr=None, tx_enb=None):
190                 """
191                 USRP simple sink contructor.
192                 @param number the unit number
193                 @param subdev_spec the sub-device specification tuple
194                 @param frequency the frequency to tune
195                 @param interpolation the device interpolation
196                 @param gain the gain to set
197                 @param mux the mux in hex or None
198                 @param auto_tr auto transmit/receive True, False, or None
199                 @param tx_enb the transmit enable: True, False, or None
200                 """
201                 #initialize hier2 block
202                 gr.hier_block2.__init__(
203                         self, 'usrp_simple_sink',
204                         gr.io_signature(1, 1, constructor_to_size[self.constructor[0]]),
205                         gr.io_signature(0, 0, 0),
206                 )
207                 #create usrp object
208                 u = self.constructor[0](number, nchan=1)
209                 if subdev_spec is None: subdev_spec = usrp.pick_tx_subdevice(u)
210                 u.set_interp_rate(interpolation)
211                 if mux is None: mux = usrp.determine_tx_mux_value(u, subdev_spec)
212                 u.set_mux(mux)
213                 subdev = _setup_tx_subdev(u, subdev_spec, gain, frequency, auto_tr, tx_enb)
214                 _simple_usrp.__init__(self, u, subdev, subdev.which())
215                 #connect
216                 self.connect(self, u)
217
218         def set_interp_rate(self, interp): self.get_u().set_interp_rate(int(interp))
219
220 class simple_sink_c(_simple_sink): constructor = (usrp.sink_c, )
221 class simple_sink_s(_simple_sink): constructor = (usrp.sink_s, )
222
223 ####################################################################
224 ####################################################################
225 # Dual USRP Base Classes
226 ####################################################################
227 ####################################################################
228
229 class _dual_usrp(object):
230         """A dual usrp source/sink base class."""
231
232         def __init__(self, u, subdev_a, subdev_b, which_a, which_b):
233                 """
234                 Create a dual usrp base class.
235                 @param u the usrp object
236                 @param subdev_a the subdevice object side a
237                 @param subdev_b the subdevice object side b
238                 @param which_a specifies the DDC/DUC number when tuning side a
239                 @param which_b specifies the DDC/DUC number when tuning side b
240                 """
241                 self._u = u
242                 self._subdev_a = subdev_a
243                 self._subdev_b = subdev_b
244                 self._which_a = which_a
245                 self._which_b = which_b
246
247         def get_u(self):
248                 """
249                 Get the underlying usrp object.
250                 @return the usrp source/sink object.
251                 """
252                 return self._u
253
254         def get_subdev_a(self):
255                 """
256                 Get the underlying subdevice.
257                 @return the subdev object.
258                 """
259                 return self._subdev_a
260
261         def get_subdev_b(self):
262                 """
263                 Get the underlying subdevice.
264                 @return the subdev object.
265                 """
266                 return self._subdev_b
267
268         def set_frequency_a(self, frequency):
269                 """
270                 Set the frequency of the subdevice.
271                 @param frequency the frequency to tune
272                 """
273                 _set_frequency(self.get_u(), self._which_a, self.get_subdev_a(), frequency)
274
275         def set_frequency_b(self, frequency):
276                 """
277                 Set the frequency of the subdevice.
278                 @param frequency the frequency to tune
279                 """
280                 _set_frequency(self.get_u(), self._which_b, self.get_subdev_b(), frequency)
281
282         def set_gain_a(self, gain):
283                 """
284                 Set the gain of the subdevice.
285                 @param gain the gain to set
286                 """
287                 self.get_subdev_a().set_gain(gain)
288
289         def set_gain_b(self, gain):
290                 """
291                 Set the gain of the subdevice.
292                 @param gain the gain to set
293                 """
294                 self.get_subdev_b().set_gain(gain)
295
296 ####################################################################
297 # Dual USRP Source
298 ####################################################################
299 class _dual_source(gr.hier_block2, _dual_usrp):
300         """A dual usrp source of IO type short or complex."""
301
302         def __init__(self, number, frequency_a, frequency_b, decimation, gain_a, gain_b, mux=0x3210, auto_tr=None, rx_ant_a=None, rx_ant_b=None):
303                 """
304                 USRP dual source contructor.
305                 @param number the unit number
306                 @param frequency_a the frequency to tune side a
307                 @param frequency_b the frequency to tune side b
308                 @param decimation the device decimation
309                 @param gain_a the gain to set side a
310                 @param gain_b the gain to set side b
311                 @param mux the mux in hex
312                 @param auto_tr auto transmit/receive True, False, or None
313                 @param rx_ant_a the receive antenna side a: 'TX/RX', 'RX2', or None
314                 @param rx_ant_b the receive antenna side b: 'TX/RX', 'RX2', or None
315                 """
316                 #initialize hier2 block
317                 gr.hier_block2.__init__(
318                         self, 'usrp_dual_source',
319                         gr.io_signature(0, 0, 0),
320                         gr.io_signature(2, 2, constructor_to_size[self.constructor[0]]),
321                 )
322                 #create usrp object
323                 u = self.constructor[0](number, nchan=2)
324                 u.set_decim_rate(decimation)
325                 u.set_mux(mux)
326                 subdev_a = _setup_rx_subdev(u, (0, 0), 0, gain_a, frequency_a, auto_tr, rx_ant_a)
327                 subdev_b = _setup_rx_subdev(u, (1, 0), 1, gain_b, frequency_b, auto_tr, rx_ant_b)
328                 _dual_usrp.__init__(self, u, subdev_a, subdev_b, 0, 1)
329                 #connect
330                 deinter = gr.deinterleave(constructor_to_size[self.constructor[0]])
331                 self.connect(u, deinter)
332                 for i in range(2): self.connect((deinter, i), (self, i))
333
334         def set_decim_rate(self, decim): self.get_u().set_decim_rate(int(decim))
335
336 class dual_source_c(_dual_source): constructor = usrp.source_c
337 class dual_source_s(_dual_source): constructor = usrp.source_s
338
339 ####################################################################
340 # Dual USRP Sink
341 ####################################################################
342 class _dual_sink(gr.hier_block2, _dual_usrp):
343         """A dual usrp sink of IO type short or complex."""
344
345         def __init__(self, number, frequency_a, frequency_b, interpolation, gain_a, gain_b, mux=0xba98, auto_tr=None, tx_enb_a=None, tx_enb_b=None):
346                 """
347                 USRP dual sink contructor.
348                 @param number the unit number
349                 @param subdev_spec the sub-device specification tuple
350                 @param frequency the frequency to tune
351                 @param interpolation the device interpolation
352                 @param gain the gain to set
353                 @param mux the mux in hex or None
354                 @param auto_tr auto transmit/receive True, False, or None
355                 @param tx_enb the transmit enable: True, False, or None
356                 """
357                 #initialize hier2 block
358                 gr.hier_block2.__init__(
359                         self, 'usrp_dual_sink',
360                         gr.io_signature(2, 2, constructor_to_size[self.constructor[0]]),
361                         gr.io_signature(0, 0, 0),
362                 )
363                 #create usrp object
364                 u = self.constructor[0](number, nchan=2)
365                 u.set_interp_rate(interpolation)
366                 u.set_mux(mux)
367                 subdev_a = _setup_tx_subdev(u, (0, 0), gain_a, frequency_a, auto_tr, tx_enb_a)
368                 subdev_b = _setup_tx_subdev(u, (1, 0), gain_b, frequency_b, auto_tr, tx_enb_b)
369                 _dual_usrp.__init__(self, u, subdev_a, subdev_b, subdev_a.which(), subdev_b.which())
370                 #connect
371                 inter = gr.interleave(constructor_to_size[self.constructor[0]])
372                 self.connect(inter, u)
373                 for i in range(2): self.connect((self, i), (inter, i))
374
375         def set_interp_rate(self, interp): self.get_u().set_interp_rate(int(interp))
376
377 class dual_sink_c(_dual_sink): constructor = usrp.sink_c
378 class dual_sink_s(_dual_sink): constructor = usrp.sink_s