Imported Upstream version 3.2.2
[debian/gnuradio] / gr-usrp / src / usrp_source_base.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2004,2008 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <usrp_source_base.h>
28 #include <gr_io_signature.h>
29 #include <usrp_standard.h>
30 #include <assert.h>
31 #include <cstdio>
32
33 static const int OUTPUT_MULTIPLE_BYTES = 4 * 1024;
34
35 usrp_source_base::usrp_source_base (const std::string &name,
36                                       gr_io_signature_sptr output_signature,
37                                       int which_board,
38                                       unsigned int decim_rate,
39                                       int nchan,
40                                       int mux,
41                                       int mode,
42                                       int fusb_block_size,
43                                       int fusb_nblocks,
44                                       const std::string fpga_filename,
45                                       const std::string firmware_filename
46                                       ) throw (std::runtime_error)
47   : usrp_base(name,
48               gr_make_io_signature (0, 0, 0),
49               output_signature),
50     d_noverruns (0)
51 {
52   d_usrp = usrp_standard_rx::make (which_board, decim_rate,
53                                    nchan, mux, mode,
54                                    fusb_block_size,
55                                    fusb_nblocks,
56                                    fpga_filename,
57                                    firmware_filename);
58   if (d_usrp == 0)
59     throw std::runtime_error ("can't open usrp");
60
61   set_usrp_basic(d_usrp);
62
63   // All calls to d_usrp->read must be multiples of 512 bytes.
64   // We jack this up to 4k to reduce overhead.
65
66   set_output_multiple (OUTPUT_MULTIPLE_BYTES / output_signature->sizeof_stream_item (0));
67 }
68
69 usrp_source_base::~usrp_source_base ()
70 {
71 }
72
73 unsigned int
74 usrp_source_base::sizeof_basic_sample() const
75 {
76   return usrp_standard_rx::format_width(d_usrp->format()) / 8;
77 }
78
79 int
80 usrp_source_base::work (int noutput_items,
81                          gr_vector_const_void_star &input_items,
82                          gr_vector_void_star &output_items)
83 {
84   static const int BUFSIZE = 4 * OUTPUT_MULTIPLE_BYTES;
85   unsigned char buf[BUFSIZE];
86   int output_index = 0;
87   int output_items_produced;
88   int bytes_read;
89   bool overrun;
90
91   while (output_index < noutput_items){
92     int nbytes = ninput_bytes_reqd_for_noutput_items (noutput_items - output_index);
93     nbytes = std::min (nbytes, BUFSIZE);
94
95     int result_nbytes = d_usrp->read (buf, nbytes, &overrun);
96     if (overrun){
97       // fprintf (stderr, "usrp_source: overrun\n");
98       fputs ("uO", stderr);
99       d_noverruns++;
100     }
101
102     if (result_nbytes < 0)      // We've got a problem.  Usually board unplugged or powered down.
103       return -1;                // Indicate we're done.
104
105     if (result_nbytes != nbytes){       // not really an error, but unexpected
106       fprintf (stderr, "usrp_source: short read.  Expected %d, got %d\n",
107                nbytes, result_nbytes);
108     }
109
110     copy_from_usrp_buffer (output_items,
111                            output_index,
112                            noutput_items - output_index,   // output_items_available
113                            output_items_produced,          // [out]
114                            buf,                            // usrp_buffer
115                            result_nbytes,                  // usrp_buffer_length
116                            bytes_read);                    // [out]
117
118     assert (output_index + output_items_produced <= noutput_items);
119     assert (bytes_read == result_nbytes);
120
121     output_index += output_items_produced;
122   }
123
124   return noutput_items;
125 }
126
127
128 bool
129 usrp_source_base::set_decim_rate (unsigned int rate)
130 {
131   return d_usrp->set_decim_rate (rate);
132 }
133
134 bool
135 usrp_source_base::set_nchannels (int nchan)
136 {
137   return d_usrp->set_nchannels (nchan);
138 }
139
140 bool
141 usrp_source_base::set_mux (int mux)
142 {
143   return d_usrp->set_mux (mux);
144 }
145
146 int
147 usrp_source_base::determine_rx_mux_value(usrp_subdev_spec ss)
148 {
149   return d_usrp->determine_rx_mux_value(ss);
150 }
151
152 int
153 usrp_source_base::determine_rx_mux_value(usrp_subdev_spec ss_a, usrp_subdev_spec ss_b)
154 {
155   return d_usrp->determine_rx_mux_value(ss_a, ss_b);
156 }
157
158 bool
159 usrp_source_base::set_rx_freq (int channel, double freq)
160 {
161   return d_usrp->set_rx_freq (channel, freq);
162 }
163
164 unsigned int
165 usrp_source_base::decim_rate () const
166 {
167   return d_usrp->decim_rate ();
168 }
169
170 int
171 usrp_source_base::nchannels () const
172 {
173   return d_usrp->nchannels ();
174 }
175
176 int
177 usrp_source_base::mux () const
178 {
179   return d_usrp->mux ();
180 }
181
182 double
183 usrp_source_base::rx_freq (int channel) const
184 {
185   return d_usrp->rx_freq (channel);
186 }
187
188 bool
189 usrp_source_base::set_fpga_mode (int mode)
190 {
191   return d_usrp->set_fpga_mode (mode);
192 }
193
194 bool
195 usrp_source_base::set_ddc_phase (int channel, int phase)
196 {
197   return d_usrp->set_ddc_phase(channel, phase);
198 }
199
200
201 bool
202 usrp_source_base::set_format(unsigned int format)
203 {
204   return d_usrp->set_format(format);
205 }
206
207 unsigned int
208 usrp_source_base::format() const
209 {
210   return d_usrp->format();
211 }
212
213 unsigned int
214 usrp_source_base::make_format(int width, int shift, bool want_q, bool bypass_halfband)
215 {
216   return usrp_standard_rx::make_format(width, shift, want_q, bypass_halfband);
217 }
218
219 int
220 usrp_source_base::format_width(unsigned int format)
221 {
222   return usrp_standard_rx::format_width(format);
223 }
224
225 int
226 usrp_source_base::format_shift(unsigned int format)
227 {
228   return usrp_standard_rx::format_shift(format);
229 }
230
231 bool
232 usrp_source_base::format_want_q(unsigned int format)
233 {
234   return usrp_standard_rx::format_want_q(format);
235 }
236
237 bool
238 usrp_source_base::format_bypass_halfband(unsigned int format)
239 {
240   return usrp_standard_rx::format_bypass_halfband(format);
241 }
242
243 bool
244 usrp_source_base::has_rx_halfband()
245 {
246   return d_usrp->has_rx_halfband();
247 }
248  
249 bool
250 usrp_source_base::has_tx_halfband()
251 {
252   return d_usrp->has_tx_halfband();
253 }
254
255 int
256 usrp_source_base::nddcs()
257 {
258   return d_usrp->nddcs();
259 }
260
261 int
262 usrp_source_base::nducs()
263 {
264   return d_usrp->nducs();
265 }
266
267 bool
268 usrp_source_base::start()
269 {
270   return d_usrp->start();
271 }
272
273 bool
274 usrp_source_base::stop()
275 {
276   return d_usrp->stop();
277 }
278
279 bool
280 usrp_source_base::tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result)
281 {
282   return d_usrp->tune(chan, db, target_freq, result);
283 }
284
285 usrp_subdev_spec
286 usrp_source_base::pick_rx_subdevice()
287 {
288   int dbids[] = {
289     USRP_DBID_FLEX_400_RX,
290     USRP_DBID_FLEX_900_RX,
291     USRP_DBID_FLEX_1200_RX,
292     USRP_DBID_FLEX_2400_RX,
293     USRP_DBID_TV_RX,
294     USRP_DBID_TV_RX_REV_2,
295     USRP_DBID_DBS_RX,
296     USRP_DBID_BASIC_RX
297   };
298
299   std::vector<int> candidates(dbids, dbids+(sizeof(dbids)/sizeof(int)));
300   return pick_subdev(candidates);
301 }