Merge branch 'dfsg-orig'
[debian/gnuradio] / gnuradio-core / src / python / gnuradio / blks2impl / 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
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 ########################################################################
125 # generic usrp source
126 ########################################################################
127 class generic_usrp_source_c(_generic_usrp_base, gr.hier_block2):
128     """
129     Create a generic usrp source that represents usrp and usrp2.
130     Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
131     Provide generic access methods so the API looks the same for both.
132     """
133
134     def __init__(self, **kwargs):
135         gr.hier_block2.__init__(self, "generic_usrp_source",
136             gr.io_signature(0, 0, 0), # Input signature
137             gr.io_signature(1, 1, gr.sizeof_gr_complex)) # Output signature
138         _generic_usrp_base.__init__(self, **kwargs)
139         self.connect(self._u, self)
140
141     ####################################################################
142     # generic access methods
143     ####################################################################
144     def set_decim(self, decim):
145         if decim not in self.get_decim_rates(): return False
146         if self._type == USRP1_TYPE: return self._u.set_decim_rate(decim)
147         elif self._type == USRP2_TYPE: return self._u.set_decim(decim)
148         elif self._type == DUMMY_TYPE: return True
149
150     def get_decim_rates(self):
151         if self._type == USRP1_TYPE: return range(8, 256+1, 2) #default firmware w/ hb filters
152         if self._type == USRP2_TYPE: return _USRP2_RATES
153         elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
154
155     def adc_rate(self):
156         if self._type == USRP1_TYPE: return self._u.adc_rate()
157         if self._type == USRP2_TYPE: return self._u.adc_rate()
158         elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
159
160     ####################################################################
161     # setup usrp methods
162     ####################################################################
163     def _setup_usrp1(self):
164         from gnuradio import usrp
165         self._u = usrp.source_c (self._which,
166                                 fusb_block_size=self._fusb_block_size,
167                                 fusb_nblocks=self._fusb_nblocks)
168         # determine the daughterboard subdevice we're using
169         if self._subdev_spec is None:
170             self._subdev_spec = usrp.pick_rx_subdevice(self._u)
171         self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
172         self._u.set_mux(usrp.determine_rx_mux_value(self._u, self._subdev_spec))
173         self._dxc = 0
174
175     def _setup_usrp2(self):
176         from gnuradio import usrp2
177         self._u = usrp2.source_32fc(self._interface, self._mac_addr)
178
179     def _setup_dummy(self): self._u = gr.null_source(gr.sizeof_gr_complex)
180
181 ########################################################################
182 # generic usrp sink
183 ########################################################################
184 class generic_usrp_sink_c(_generic_usrp_base, gr.hier_block2):
185     """
186     Create a generic usrp sink that represents usrp and usrp2.
187     Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
188     Provide generic access methods so the API looks the same for both.
189     """
190
191     def __init__(self, **kwargs):
192         gr.hier_block2.__init__(self, "generic_usrp_sink",
193             gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
194             gr.io_signature(0, 0, 0)) # Output signature
195         _generic_usrp_base.__init__(self, **kwargs)
196         if self._type == USRP1_TYPE: #scale 0.0 to 1.0 input for usrp1
197             self.connect(self, gr.multiply_const_cc((2**15)-1), self._u)
198         else: self.connect(self, self._u)
199
200     ####################################################################
201     # generic access methods
202     ####################################################################
203     def set_interp(self, interp):
204         if interp not in self.get_interp_rates(): return False
205         if self._type == USRP1_TYPE: return self._u.set_interp_rate(interp)
206         elif self._type == USRP2_TYPE: return self._u.set_interp(interp)
207         elif self._type == DUMMY_TYPE: return True
208
209     def get_interp_rates(self):
210         if self._type == USRP1_TYPE: return range(16, 512+1, 4)
211         if self._type == USRP2_TYPE: return _USRP2_RATES
212         elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
213
214     def dac_rate(self):
215         if self._type == USRP1_TYPE: return self._u.dac_rate()
216         if self._type == USRP2_TYPE: return self._u.dac_rate()
217         elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
218
219     ####################################################################
220     # setup usrp methods
221     ####################################################################
222     def _setup_usrp1(self):
223         from gnuradio import usrp
224         self._u = usrp.sink_c (self._which,
225                                 fusb_block_size=self._fusb_block_size,
226                                 fusb_nblocks=self._fusb_nblocks)
227         # determine the daughterboard subdevice we're using
228         if self._subdev_spec is None:
229             self._subdev_spec = usrp.pick_tx_subdevice(self._u)
230         self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
231         self._u.set_mux(usrp.determine_tx_mux_value(self._u, self._subdev_spec))
232         self._dxc = self._subdev.which()
233
234     def _setup_usrp2(self):
235         from gnuradio import usrp2
236         self._u = usrp2.sink_32fc(self._interface, self._mac_addr)
237
238     def _setup_dummy(self): self._u = gr.null_sink(gr.sizeof_gr_complex)