Imported Upstream version 3.2.2
[debian/gnuradio] / gnuradio-examples / python / digital / generic_usrp.py
1 #
2 # Copyright 2009 Free Software Foundation, Inc.
3 #
4 # This file is part of GNU Radio
5 #
6 # GNU Radio is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3, or (at your option)
9 # any later version.
10 #
11 # GNU Radio is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with GNU Radio; see the file COPYING.  If not, write to
18 # the Free Software Foundation, Inc., 51 Franklin Street,
19 # Boston, MA 02110-1301, USA.
20 #
21
22 USRP1_TYPE = 'usrp1'
23 USRP2_TYPE = 'usrp2'
24 DUMMY_TYPE = 'dummy'
25 #usrp2 rates common for decim and interp
26 _USRP2_RATES = range(4, 128+1, 1) + range(130, 256+1, 2) + range(260, 512+1, 4)
27 #dummy common rates
28 _DUMMY_XRATES = range(4, 512, 2)
29 _DUMMY_CONVERTER_RATE = 100e6
30 #dummy freq result
31 class _dummy_freq_result(object):
32     def __init__(self, target_freq):
33         self.baseband_freq = target_freq
34         self.dxc_freq = 0
35         self.residual_freq = 0
36 from gnuradio import gr, usrp, usrp2
37
38 ########################################################################
39 # generic usrp common stuff
40 ########################################################################
41 class _generic_usrp_base(object):
42
43     def __init__(self, which=0, subdev_spec=None, interface="", mac_addr="",
44         fusb_block_size=0, fusb_nblocks=0, usrpx=None, lo_offset=None, gain=None):
45         self._lo_offset = lo_offset
46         #usrp options
47         self._which = which
48         self._subdev_spec = subdev_spec
49         #usrp2 options
50         self._interface = interface
51         self._mac_addr = mac_addr
52         #fusb options
53         self._fusb_block_size = fusb_block_size
54         self._fusb_nblocks = fusb_nblocks
55         #pick which usrp model
56         if usrpx == '0': self._setup_usrpx(DUMMY_TYPE)
57         elif usrpx == '1' or self._subdev_spec: self._setup_usrpx(USRP1_TYPE)
58         elif usrpx == '2' or self._mac_addr: self._setup_usrpx(USRP2_TYPE)
59         else: #automatic
60             try: self._setup_usrpx(USRP2_TYPE)
61             except:
62                 try: self._setup_usrpx(USRP1_TYPE)
63                 except: raise Exception, 'Failed to automatically setup a usrp device.'
64         #post usrp setup
65         if self._lo_offset is not None:
66             self.set_lo_offset(self._lo_offset)
67         self.set_gain(gain)
68         self.set_auto_tr(True)
69
70     def _setup_usrpx(self, type):
71         """
72         Call the appropriate setup method.
73         @param type the usrp type constant
74         """
75         self._type = type
76         if self._type == USRP1_TYPE: self._setup_usrp1()
77         elif self._type == USRP2_TYPE: self._setup_usrp2()
78         elif self._type == DUMMY_TYPE: self._setup_dummy()
79
80     def __str__(self):
81         if self._type == USRP1_TYPE: return self._subdev.side_and_name()
82         elif self._type == USRP2_TYPE:
83             return 'Interface: %s    MAC Address: %s    D-Board ID: 0x%.2x'%(
84                 self._u.interface_name(), self._u.mac_addr(), self._u.daughterboard_id())
85         elif self._type == DUMMY_TYPE: return 'Dummy USRP Device'
86
87     def gain(self): return self._gain
88
89     def set_gain(self, gain=None):
90         #automatic gain calculation
91         r = self.gain_range()
92         if gain is None: gain = (r[0] + r[1])/2 # set gain to midpoint
93         #set gain for usrp
94         self._gain = gain
95         if self._type == USRP1_TYPE: return self._subdev.set_gain(gain)
96         elif self._type == USRP2_TYPE: return self._u.set_gain(gain)
97         elif self._type == DUMMY_TYPE: return True
98
99     def gain_range(self):
100         if self._type == USRP1_TYPE: return self._subdev.gain_range()
101         elif self._type == USRP2_TYPE: return self._u.gain_range()
102         elif self._type == DUMMY_TYPE: return (0, 0, 0)
103
104     def set_center_freq(self, target_freq):
105         if self._type == USRP1_TYPE:
106             return self._u.tune(self._dxc, self._subdev, target_freq)
107         elif self._type == USRP2_TYPE:
108             return self._u.set_center_freq(target_freq)
109         elif self._type == DUMMY_TYPE: return _dummy_freq_result(target_freq)
110
111     def freq_range(self):
112         if self._type == USRP1_TYPE: return self._subdev.freq_range()
113         elif self._type == USRP2_TYPE: return self._u.freq_range()
114         elif self._type == DUMMY_TYPE: return (-10e9, 10e9, 100e3)
115
116     def set_lo_offset(self, lo_offset):
117         if self._type == USRP1_TYPE: return self._subdev.set_lo_offset(lo_offset)
118         elif self._type == USRP2_TYPE: return self._u.set_lo_offset(lo_offset)
119         elif self._type == DUMMY_TYPE: return True
120
121     def set_auto_tr(self, enable):
122         if self._type == USRP1_TYPE: return self._subdev.set_auto_tr(enable)
123
124     def __del__(self):
125         try: # Avoid weak reference error
126             del self._u
127             del self._subdev
128         except: pass
129
130 ########################################################################
131 # generic usrp source
132 ########################################################################
133 class generic_usrp_source_c(_generic_usrp_base, gr.hier_block2):
134     """
135     Create a generic usrp source that represents usrp and usrp2.
136     Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
137     Provide generic access methods so the API looks the same for both.
138     """
139
140     def __init__(self, **kwargs):
141         gr.hier_block2.__init__(self, "generic_usrp_source",
142             gr.io_signature(0, 0, 0), # Input signature
143             gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
144         _generic_usrp_base.__init__(self, **kwargs)
145         self.connect(self._u, self)
146
147     ####################################################################
148     # generic access methods
149     ####################################################################
150     def set_decim(self, decim):
151         if decim not in self.get_decim_rates(): return False
152         if self._type == USRP1_TYPE: return self._u.set_decim_rate(decim)
153         elif self._type == USRP2_TYPE: return self._u.set_decim(decim)
154         elif self._type == DUMMY_TYPE: return True
155
156     def get_decim_rates(self):
157         if self._type == USRP1_TYPE: return range(8, 256+1, 2) #default firmware w/ hb filters
158         if self._type == USRP2_TYPE: return _USRP2_RATES
159         elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
160
161     def adc_rate(self):
162         if self._type == USRP1_TYPE: return self._u.adc_rate()
163         if self._type == USRP2_TYPE: return self._u.adc_rate()
164         elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
165
166     ####################################################################
167     # setup usrp methods
168     ####################################################################
169     def _setup_usrp1(self):
170         self._u = usrp.source_c (self._which,
171                                 fusb_block_size=self._fusb_block_size,
172                                 fusb_nblocks=self._fusb_nblocks)
173         # determine the daughterboard subdevice we're using
174         if self._subdev_spec is None:
175             self._subdev_spec = usrp.pick_rx_subdevice(self._u)
176         self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
177         self._u.set_mux(usrp.determine_rx_mux_value(self._u, self._subdev_spec))
178         self._dxc = 0
179
180     def _setup_usrp2(self):
181         self._u = usrp2.source_32fc(self._interface, self._mac_addr)
182
183     def _setup_dummy(self): self._u = gr.null_source(gr.sizeof_gr_complex)
184
185 ########################################################################
186 # generic usrp sink
187 ########################################################################
188 class generic_usrp_sink_c(_generic_usrp_base, gr.hier_block2):
189     """
190     Create a generic usrp sink that represents usrp and usrp2.
191     Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
192     Provide generic access methods so the API looks the same for both.
193     """
194
195     def __init__(self, **kwargs):
196         gr.hier_block2.__init__(self, "generic_usrp_sink",
197             gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
198             gr.io_signature(0, 0, 0)) # Output signature
199         _generic_usrp_base.__init__(self, **kwargs)
200         if self._type == USRP1_TYPE: #scale 0.0 to 1.0 input for usrp1
201             self.connect(self, gr.multiply_const_cc((2**15)-1), self._u)
202         else: self.connect(self, self._u)
203
204     ####################################################################
205     # generic access methods
206     ####################################################################
207     def set_interp(self, interp):
208         if interp not in self.get_interp_rates(): return False
209         if self._type == USRP1_TYPE: return self._u.set_interp_rate(interp)
210         elif self._type == USRP2_TYPE: return self._u.set_interp(interp)
211         elif self._type == DUMMY_TYPE: return True
212
213     def get_interp_rates(self):
214         if self._type == USRP1_TYPE: return range(16, 512+1, 4)
215         if self._type == USRP2_TYPE: return _USRP2_RATES
216         elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
217
218     def dac_rate(self):
219         if self._type == USRP1_TYPE: return self._u.dac_rate()
220         if self._type == USRP2_TYPE: return self._u.dac_rate()
221         elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
222
223     ####################################################################
224     # setup usrp methods
225     ####################################################################
226     def _setup_usrp1(self):
227         self._u = usrp.sink_c (self._which,
228                                 fusb_block_size=self._fusb_block_size,
229                                 fusb_nblocks=self._fusb_nblocks)
230         # determine the daughterboard subdevice we're using
231         if self._subdev_spec is None:
232             self._subdev_spec = usrp.pick_tx_subdevice(self._u)
233         self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
234         self._u.set_mux(usrp.determine_tx_mux_value(self._u, self._subdev_spec))
235         self._dxc = self._subdev.which()
236
237     def _setup_usrp2(self): self._u = usrp2.sink_32fc(self._interface, self._mac_addr)
238
239     def _setup_dummy(self): self._u = gr.null_sink(gr.sizeof_gr_complex)