Imported Upstream version 3.0.4
[debian/gnuradio] / gr-usrp / src / usrp1_sink_base.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2004 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 <usrp1_sink_base.h>
28 #include <gr_io_signature.h>
29 #include <usrp_standard.h>
30 #include <assert.h>
31
32 static const int OUTPUT_MULTIPLE_SAMPLES = 128;         // DON'T CHANGE THIS VALUE!
33
34 usrp1_sink_base::usrp1_sink_base (const std::string &name,
35                                   gr_io_signature_sptr input_signature,
36                                   int which_board,
37                                   unsigned int interp_rate,
38                                   int nchan,
39                                   int mux,
40                                   int fusb_block_size,
41                                   int fusb_nblocks,
42                                   const std::string fpga_filename,
43                                   const std::string firmware_filename
44                                   ) throw (std::runtime_error)
45   : gr_sync_block (name,
46                    input_signature,
47                    gr_make_io_signature (0, 0, 0)),
48     d_nunderruns (0)
49 {
50   d_usrp = usrp_standard_tx::make (which_board,
51                                    interp_rate,
52                                    nchan, mux,
53                                    fusb_block_size,
54                                    fusb_nblocks,
55                                    fpga_filename,
56                                    firmware_filename
57                                    );
58   if (d_usrp == 0)
59     throw std::runtime_error ("can't open usrp1");
60
61   // All calls to d_usrp->write must be multiples of 512 bytes.
62
63   set_output_multiple (OUTPUT_MULTIPLE_SAMPLES);
64 }
65
66 usrp1_sink_base::~usrp1_sink_base ()
67 {
68   delete d_usrp;
69 }
70
71 bool 
72 usrp1_sink_base::start()
73 {
74   return d_usrp->start();
75 }
76
77 bool 
78 usrp1_sink_base::stop()
79 {
80   return d_usrp->stop();
81 }
82
83 int
84 usrp1_sink_base::work (int noutput_items,
85                        gr_vector_const_void_star &input_items,
86                        gr_vector_void_star &output_items)
87 {
88   static const int BUFSIZE = 16 * (1L << 10);   // 16kB
89   unsigned char outbuf[BUFSIZE];
90   int           obi = 0;
91   int           input_index = 0;
92   int           input_items_consumed;
93   int           bytes_written;
94   bool          underrun;
95   
96
97   while (input_index < noutput_items){
98   
99     copy_to_usrp_buffer (input_items,
100                          input_index,
101                          noutput_items - input_index,   // input_items_available
102                          input_items_consumed,          // [out]
103                          &outbuf[obi],                  // [out] usrp_buffer
104                          BUFSIZE - obi,                 // usrp_buffer_length
105                          bytes_written);                // [out]
106
107     assert (input_index + input_items_consumed <= noutput_items);
108     assert (obi + bytes_written <= BUFSIZE);
109     
110     input_index += input_items_consumed;
111     obi += bytes_written;
112
113     if (obi >= BUFSIZE){        // flush
114       if (d_usrp->write (outbuf, obi, &underrun) != obi)
115         return -1;              // indicate we're done
116
117       if (underrun){
118         d_nunderruns++;
119         // fprintf (stderr, "usrp1_sink: underrun\n");
120         fputs ("uU", stderr);
121       }
122       obi = 0;
123     }
124   }
125
126   if (obi != 0){
127     assert (obi % 512 == 0);
128     if (d_usrp->write (outbuf, obi, &underrun) != obi)
129       return -1;        // indicate we're done
130
131     if (underrun){
132       d_nunderruns++;
133       // fprintf (stderr, "usrp1_sink: underrun\n");
134       fputs ("uU", stderr);
135     }
136   }
137
138   return noutput_items;
139 }
140
141 bool
142 usrp1_sink_base::set_interp_rate (unsigned int rate)
143 {
144   return d_usrp->set_interp_rate (rate);
145 }
146
147 bool
148 usrp1_sink_base::set_nchannels (int nchan)
149 {
150   return d_usrp->set_nchannels (nchan);
151 }
152
153 bool
154 usrp1_sink_base::set_mux (int mux)
155 {
156   return d_usrp->set_mux (mux);
157 }
158
159 bool
160 usrp1_sink_base::set_tx_freq (int channel, double freq)
161 {
162   return d_usrp->set_tx_freq (channel, freq);
163 }
164
165 long
166 usrp1_sink_base::fpga_master_clock_freq() const
167 {
168   return d_usrp->fpga_master_clock_freq();
169 }
170
171 long
172 usrp1_sink_base::converter_rate () const
173 {
174   return d_usrp->converter_rate ();
175 }
176
177 unsigned int
178 usrp1_sink_base::interp_rate () const
179 {
180   return d_usrp->interp_rate ();
181 }
182
183 int
184 usrp1_sink_base::nchannels () const
185 {
186   return d_usrp->nchannels ();
187 }
188
189 int
190 usrp1_sink_base::mux () const
191 {
192   return d_usrp->mux ();
193 }
194
195
196 double
197 usrp1_sink_base::tx_freq (int channel) const
198 {
199   return d_usrp->tx_freq (channel);
200 }
201
202 void
203 usrp1_sink_base::set_verbose (bool verbose)
204 {  
205   d_usrp->set_verbose (verbose);
206 }
207
208 bool
209 usrp1_sink_base::write_aux_dac (int which_dboard, int which_dac, int value)
210 {
211   return d_usrp->write_aux_dac (which_dboard, which_dac, value);
212 }
213
214 int
215 usrp1_sink_base::read_aux_adc (int which_dboard, int which_adc)
216 {
217   return d_usrp->read_aux_adc (which_dboard, which_adc);
218 }
219
220 bool
221 usrp1_sink_base::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
222 {
223   return d_usrp->write_eeprom (i2c_addr, eeprom_offset, buf);
224 }
225
226 std::string
227 usrp1_sink_base::read_eeprom (int i2c_addr, int eeprom_offset, int len)
228 {
229   return d_usrp->read_eeprom (i2c_addr, eeprom_offset, len);
230 }
231
232 bool
233 usrp1_sink_base::write_i2c (int i2c_addr, const std::string buf)
234 {
235   return d_usrp->write_i2c (i2c_addr, buf);
236 }
237
238 std::string
239 usrp1_sink_base::read_i2c (int i2c_addr, int len)
240 {
241   return d_usrp->read_i2c (i2c_addr, len);
242 }
243
244 bool
245 usrp1_sink_base::set_pga (int which, double gain)
246 {
247   return d_usrp->set_pga (which, gain);
248 }
249
250 double
251 usrp1_sink_base::pga (int which) const
252 {
253   return d_usrp->pga (which);
254 }
255
256 double
257 usrp1_sink_base::pga_min () const
258 {
259   return d_usrp->pga_min ();
260 }
261
262 double
263 usrp1_sink_base::pga_max () const
264 {
265   return d_usrp->pga_max ();
266 }
267
268 double
269 usrp1_sink_base::pga_db_per_step () const
270 {
271   return d_usrp->pga_db_per_step ();
272 }
273
274 int
275 usrp1_sink_base::daughterboard_id (int which) const
276 {
277   return d_usrp->daughterboard_id (which);
278 }
279
280 bool
281 usrp1_sink_base::set_adc_offset (int which, int offset)
282 {
283   return d_usrp->set_adc_offset (which, offset);
284 }
285
286 bool
287 usrp1_sink_base::set_dac_offset (int which, int offset, int offset_pin)
288 {
289   return d_usrp->set_dac_offset (which, offset, offset_pin);
290 }
291
292 bool
293 usrp1_sink_base::set_adc_buffer_bypass (int which, bool bypass)
294 {
295   return d_usrp->set_adc_buffer_bypass (which, bypass);
296 }
297
298 std::string
299 usrp1_sink_base::serial_number()
300 {
301   return d_usrp->serial_number();
302 }
303
304 bool
305 usrp1_sink_base::_write_oe (int which_dboard, int value, int mask)
306 {
307   return d_usrp->_write_oe (which_dboard, value, mask);
308 }
309
310 bool
311 usrp1_sink_base::write_io (int which_dboard, int value, int mask)
312 {
313   return d_usrp->write_io (which_dboard, value, mask);
314 }
315
316 int
317 usrp1_sink_base::read_io (int which_dboard)
318 {
319   return d_usrp->read_io (which_dboard);
320 }
321
322 // internal routines...
323
324 bool
325 usrp1_sink_base::_write_fpga_reg (int regno, int value)
326 {
327   return d_usrp->_write_fpga_reg (regno, value);
328 }
329
330 int
331 usrp1_sink_base::_read_fpga_reg (int regno)
332 {
333   return d_usrp->_read_fpga_reg (regno);
334 }
335
336 bool
337 usrp1_sink_base::_write_9862 (int which_codec, int regno, unsigned char value)
338 {
339   return d_usrp->_write_9862 (which_codec, regno, value);
340 }
341
342 int
343 usrp1_sink_base::_read_9862 (int which_codec, int regno) const
344 {
345   return d_usrp->_read_9862 (which_codec, regno);
346 }
347
348 bool
349 usrp1_sink_base::_write_spi (int optional_header, int enables,
350                              int format, std::string buf)
351 {
352   return d_usrp->_write_spi (optional_header, enables, format, buf);
353 }
354
355 std::string
356 usrp1_sink_base::_read_spi (int optional_header, int enables, int format, int len)
357 {
358   return d_usrp->_read_spi (optional_header, enables, format, len);
359 }