Merge branch 'flattopwindow' of http://gnuradio.org/git/jblum
[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         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         from gnuradio import usrp
171         self._u = usrp.source_c (self._which,
172                                 fusb_block_size=self._fusb_block_size,
173                                 fusb_nblocks=self._fusb_nblocks)
174         # determine the daughterboard subdevice we're using
175         if self._subdev_spec is None:
176             self._subdev_spec = usrp.pick_rx_subdevice(self._u)
177         self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
178         self._u.set_mux(usrp.determine_rx_mux_value(self._u, self._subdev_spec))
179         self._dxc = 0
180
181     def _setup_usrp2(self):
182         from gnuradio import usrp2
183         self._u = usrp2.source_32fc(self._interface, self._mac_addr)
184
185     def _setup_dummy(self): self._u = gr.null_source(gr.sizeof_gr_complex)
186
187 ########################################################################
188 # generic usrp sink
189 ########################################################################
190 class generic_usrp_sink_c(_generic_usrp_base, gr.hier_block2):
191     """
192     Create a generic usrp sink that represents usrp and usrp2.
193     Take usrp and usrp2 constructor arguments and try to figure out usrp or usrp2.
194     Provide generic access methods so the API looks the same for both.
195     """
196
197     def __init__(self, **kwargs):
198         gr.hier_block2.__init__(self, "generic_usrp_sink",
199             gr.io_signature(1, 1, gr.sizeof_gr_complex), # Input signature
200             gr.io_signature(0, 0, 0)) # Output signature
201         _generic_usrp_base.__init__(self, **kwargs)
202         if self._type == USRP1_TYPE: #scale 0.0 to 1.0 input for usrp1
203             self.connect(self, gr.multiply_const_cc((2**15)-1), self._u)
204         else: self.connect(self, self._u)
205
206     ####################################################################
207     # generic access methods
208     ####################################################################
209     def set_interp(self, interp):
210         if interp not in self.get_interp_rates(): return False
211         if self._type == USRP1_TYPE: return self._u.set_interp_rate(interp)
212         elif self._type == USRP2_TYPE: return self._u.set_interp(interp)
213         elif self._type == DUMMY_TYPE: return True
214
215     def get_interp_rates(self):
216         if self._type == USRP1_TYPE: return range(16, 512+1, 4)
217         if self._type == USRP2_TYPE: return _USRP2_RATES
218         elif self._type == DUMMY_TYPE: return _DUMMY_XRATES
219
220     def dac_rate(self):
221         if self._type == USRP1_TYPE: return self._u.dac_rate()
222         if self._type == USRP2_TYPE: return self._u.dac_rate()
223         elif self._type == DUMMY_TYPE: return _DUMMY_CONVERTER_RATE
224
225     ####################################################################
226     # setup usrp methods
227     ####################################################################
228     def _setup_usrp1(self):
229         from gnuradio import usrp
230         self._u = usrp.sink_c (self._which,
231                                 fusb_block_size=self._fusb_block_size,
232                                 fusb_nblocks=self._fusb_nblocks)
233         # determine the daughterboard subdevice we're using
234         if self._subdev_spec is None:
235             self._subdev_spec = usrp.pick_tx_subdevice(self._u)
236         self._subdev = usrp.selected_subdev(self._u, self._subdev_spec)
237         self._u.set_mux(usrp.determine_tx_mux_value(self._u, self._subdev_spec))
238         self._dxc = self._subdev.which()
239
240     def _setup_usrp2(self):
241         from gnuradio import usrp2
242         self._u = usrp2.sink_32fc(self._interface, self._mac_addr)
243
244     def _setup_dummy(self): self._u = gr.null_sink(gr.sizeof_gr_complex)