2 # Copyright 2009 Free Software Foundation, Inc.
4 # This file is part of GNU Radio
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)
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.
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.
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)
28 _DUMMY_XRATES = range(4, 512, 2)
29 _DUMMY_CONVERTER_RATE = 100e6
31 class _dummy_freq_result(object):
32 def __init__(self, target_freq):
33 self.baseband_freq = target_freq
35 self.residual_freq = 0
36 from gnuradio import gr, usrp, usrp2
38 ########################################################################
39 # generic usrp common stuff
40 ########################################################################
41 class _generic_usrp_base(object):
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
48 self._subdev_spec = subdev_spec
50 self._interface = interface
51 self._mac_addr = mac_addr
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)
60 try: self._setup_usrpx(USRP2_TYPE)
62 try: self._setup_usrpx(USRP1_TYPE)
63 except: raise Exception, 'Failed to automatically setup a usrp device.'
65 if self._lo_offset is not None:
66 self.set_lo_offset(self._lo_offset)
68 self.set_auto_tr(True)
70 def _setup_usrpx(self, type):
72 Call the appropriate setup method.
73 @param type the usrp type constant
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()
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'
87 def gain(self): return self._gain
89 def set_gain(self, gain=None):
90 #automatic gain calculation
92 if gain is None: gain = (r[0] + r[1])/2 # set gain to midpoint
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
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)
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)
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)
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
121 def set_auto_tr(self, enable):
122 if self._type == USRP1_TYPE: return self._subdev.set_auto_tr(enable)
125 try: # Avoid weak reference error
130 ########################################################################
131 # generic usrp source
132 ########################################################################
133 class generic_usrp_source_c(_generic_usrp_base, gr.hier_block2):
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.
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)
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
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
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
166 ####################################################################
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))
180 def _setup_usrp2(self):
181 self._u = usrp2.source_32fc(self._interface, self._mac_addr)
183 def _setup_dummy(self): self._u = gr.null_source(gr.sizeof_gr_complex)
185 ########################################################################
187 ########################################################################
188 class generic_usrp_sink_c(_generic_usrp_base, gr.hier_block2):
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.
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)
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
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
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
223 ####################################################################
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()
237 def _setup_usrp2(self): self._u = usrp2.sink_32fc(self._interface, self._mac_addr)
239 def _setup_dummy(self): self._u = gr.null_sink(gr.sizeof_gr_complex)