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