Cleanup in preparation for merge
[debian/gnuradio] / usrp / host / lib / usrp_basic_common.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2003,2004,2008,2009 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/usrp_basic.h"
28 #include "usrp/usrp_prims.h"
29 #include "usrp_interfaces.h"
30 #include "fpga_regs_common.h"
31 #include "fpga_regs_standard.h"
32 #include "fusb.h"
33 #include "db_boards.h"
34 #include <stdexcept>
35 #include <assert.h>
36 #include <math.h>
37 #include <ad9862.h>
38 #include <string.h>
39 #include <cstdio>
40
41 using namespace ad9862;
42
43 #define NELEM(x) (sizeof (x) / sizeof (x[0]))
44
45 // These set the buffer size used for each end point using the fast
46 // usb interface.  The kernel ends up locking down this much memory.
47
48 static const int FUSB_BUFFER_SIZE = fusb_sysconfig::default_buffer_size();
49 static const int FUSB_BLOCK_SIZE = fusb_sysconfig::max_block_size();
50 static const int FUSB_NBLOCKS    = FUSB_BUFFER_SIZE / FUSB_BLOCK_SIZE;
51
52
53 static const double POLLING_INTERVAL = 0.1;     // seconds
54
55 ////////////////////////////////////////////////////////////////
56
57 static libusb_device_handle *
58 open_rx_interface (libusb_device *dev)
59 {
60   libusb_device_handle *udh = usrp_open_rx_interface (dev);
61   if (udh == 0){
62     fprintf (stderr, "usrp_basic_rx: can't open rx interface\n");
63   }
64   return udh;
65 }
66
67 static libusb_device_handle *
68 open_tx_interface (libusb_device *dev)
69 {
70   libusb_device_handle *udh = usrp_open_tx_interface (dev);
71   if (udh == 0){
72     fprintf (stderr, "usrp_basic_tx: can't open tx interface\n");
73   }
74   return udh;
75 }
76
77
78 //////////////////////////////////////////////////////////////////
79 //
80 //                      usrp_basic
81 //
82 ////////////////////////////////////////////////////////////////
83
84
85 // Given:
86 //   CLKIN = 64 MHz
87 //   CLKSEL pin = high
88 //
89 // These settings give us:
90 //   CLKOUT1 = CLKIN = 64 MHz
91 //   CLKOUT2 = CLKIN = 64 MHz
92 //   ADC is clocked at  64 MHz
93 //   DAC is clocked at 128 MHz
94
95 static unsigned char common_regs[] = {
96   REG_GENERAL,          0,
97   REG_DLL,              (DLL_DISABLE_INTERNAL_XTAL_OSC
98                          | DLL_MULT_2X
99                          | DLL_FAST),
100   REG_CLKOUT,           CLKOUT2_EQ_DLL_OVER_2,
101   REG_AUX_ADC_CLK,      AUX_ADC_CLK_CLK_OVER_4
102 };
103
104 void
105 usrp_basic::shutdown_daughterboards()
106 {
107   // nuke d'boards before we close down USB in ~usrp_basic
108   // shutdown() will do any board shutdown while the USRP can still
109   // be talked to
110   for(size_t i = 0; i < d_db.size(); i++)
111     for(size_t j = 0; j < d_db[i].size(); j++)
112       d_db[i][j]->shutdown();
113 }
114
115 void
116 usrp_basic::init_db(usrp_basic_sptr u)
117 {
118   if (u.get() != this)
119     throw std::invalid_argument("u is not this");
120
121   d_db[0] = instantiate_dbs(d_dbid[0], u, 0);
122   d_db[1] = instantiate_dbs(d_dbid[1], u, 1);
123 }
124
125 std::vector<db_base_sptr>
126 usrp_basic::db(int which_side)
127 {
128   which_side &= 0x1;    // clamp it to avoid any reporting any errors
129   return d_db[which_side];
130 }
131
132 bool
133 usrp_basic::is_valid(const usrp_subdev_spec &ss)
134 {
135   if (ss.side < 0 || ss.side > 1)
136     return false;
137
138   if (ss.subdev < 0 || ss.subdev >= d_db[ss.side].size())
139     return false;
140
141   return true;
142 }
143
144 db_base_sptr
145 usrp_basic::selected_subdev(const usrp_subdev_spec &ss)
146 {
147   if (!is_valid(ss))
148     throw std::invalid_argument("invalid subdev_spec");
149
150   return d_db[ss.side][ss.subdev];
151 }
152
153 bool
154 usrp_basic::start ()
155 {
156   return true;          // nop
157 }
158
159 bool
160 usrp_basic::stop ()
161 {
162   return true;          // nop
163 }
164
165 void
166 usrp_basic::set_usb_data_rate (int usb_data_rate)
167 {
168   d_usb_data_rate = usb_data_rate;
169   d_bytes_per_poll = (int) (usb_data_rate * POLLING_INTERVAL);
170 }
171
172 bool
173 usrp_basic::_write_aux_dac (int slot, int which_dac, int value)
174 {
175   return usrp_write_aux_dac (d_udh, slot, which_dac, value);
176 }
177
178 bool
179 usrp_basic::_read_aux_adc (int slot, int which_adc, int *value)
180 {
181   return usrp_read_aux_adc (d_udh, slot, which_adc, value);
182 }
183
184 int
185 usrp_basic::_read_aux_adc (int slot, int which_adc)
186 {
187   int   value;
188   if (!_read_aux_adc (slot, which_adc, &value))
189     return READ_FAILED;
190
191   return value;
192 }
193
194 bool
195 usrp_basic::write_eeprom (int i2c_addr, int eeprom_offset, const std::string buf)
196 {
197   return usrp_eeprom_write (d_udh, i2c_addr, eeprom_offset, buf.data (), buf.size ());
198 }
199
200 std::string
201 usrp_basic::read_eeprom (int i2c_addr, int eeprom_offset, int len)
202 {
203   if (len <= 0)
204     return "";
205
206   char buf[len];
207
208   if (!usrp_eeprom_read (d_udh, i2c_addr, eeprom_offset, buf, len))
209     return "";
210
211   return std::string (buf, len);
212 }
213
214 bool
215 usrp_basic::write_i2c (int i2c_addr, const std::string buf)
216 {
217   return usrp_i2c_write (d_udh, i2c_addr, buf.data (), buf.size ());
218 }
219
220 std::string
221 usrp_basic::read_i2c (int i2c_addr, int len)
222 {
223   if (len <= 0)
224     return "";
225
226   char buf[len];
227
228   if (!usrp_i2c_read (d_udh, i2c_addr, buf, len))
229     return "";
230
231   return std::string (buf, len);
232 }
233
234 std::string
235 usrp_basic::serial_number()
236 {
237   return usrp_serial_number(d_udh);
238 }
239
240 // ----------------------------------------------------------------
241
242 bool
243 usrp_basic::set_adc_offset (int which_adc, int offset)
244 {
245   if (which_adc < 0 || which_adc > 3)
246     return false;
247
248   return _write_fpga_reg (FR_ADC_OFFSET_0 + which_adc, offset);
249 }
250
251 bool
252 usrp_basic::set_dac_offset (int which_dac, int offset, int offset_pin)
253 {
254   if (which_dac < 0 || which_dac > 3)
255     return false;
256
257   int which_codec = which_dac >> 1;
258   int tx_a = (which_dac & 0x1) == 0;
259   int lo = ((offset & 0x3) << 6) | (offset_pin & 0x1);
260   int hi = (offset >> 2);
261   bool ok;
262
263   if (tx_a){
264     ok =  _write_9862 (which_codec, REG_TX_A_OFFSET_LO, lo);
265     ok &= _write_9862 (which_codec, REG_TX_A_OFFSET_HI, hi);
266   }
267   else {
268     ok =  _write_9862 (which_codec, REG_TX_B_OFFSET_LO, lo);
269     ok &= _write_9862 (which_codec, REG_TX_B_OFFSET_HI, hi);
270   }
271   return ok;
272 }
273
274 bool
275 usrp_basic::set_adc_buffer_bypass (int which_adc, bool bypass)
276 {
277   if (which_adc < 0 || which_adc > 3)
278     return false;
279
280   int codec = which_adc >> 1;
281   int reg = (which_adc & 1) == 0 ? REG_RX_A : REG_RX_B;
282
283   unsigned char cur_rx;
284   unsigned char cur_pwr_dn;
285
286   // If the input buffer is bypassed, we need to power it down too.
287
288   bool ok = _read_9862 (codec, reg, &cur_rx);
289   ok &= _read_9862 (codec, REG_RX_PWR_DN, &cur_pwr_dn);
290   if (!ok)
291     return false;
292
293   if (bypass){
294     cur_rx |= RX_X_BYPASS_INPUT_BUFFER;
295     cur_pwr_dn |= ((which_adc & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B;
296   }
297   else {
298     cur_rx &= ~RX_X_BYPASS_INPUT_BUFFER;
299     cur_pwr_dn &= ~(((which_adc & 1) == 0) ? RX_PWR_DN_BUF_A : RX_PWR_DN_BUF_B);
300   }
301
302   ok &= _write_9862 (codec, reg, cur_rx);
303   ok &= _write_9862 (codec, REG_RX_PWR_DN, cur_pwr_dn);
304   return ok;
305 }
306
307 bool
308 usrp_basic::set_dc_offset_cl_enable(int bits, int mask)
309 {
310   return _write_fpga_reg(FR_DC_OFFSET_CL_EN,
311                          (d_fpga_shadows[FR_DC_OFFSET_CL_EN] & ~mask) | (bits & mask));
312 }
313
314 // ----------------------------------------------------------------
315
316 bool
317 usrp_basic::_write_fpga_reg (int regno, int value)
318 {
319   if (d_verbose){
320     fprintf (stdout, "_write_fpga_reg(%3d, 0x%08x)\n", regno, value);
321     fflush (stdout);
322   }
323
324   if (regno >= 0 && regno < MAX_REGS)
325     d_fpga_shadows[regno] = value;
326
327   return usrp_write_fpga_reg (d_udh, regno, value);
328 }
329
330 bool
331 usrp_basic::_write_fpga_reg_masked (int regno, int value, int mask)
332 {
333   //Only use this for registers who actually use a mask in the verilog firmware, like FR_RX_MASTER_SLAVE
334   //value is a 16 bits value and mask is a 16 bits mask
335   if (d_verbose){
336     fprintf (stdout, "_write_fpga_reg_masked(%3d, 0x%04x,0x%04x)\n", regno, value, mask);
337     fflush (stdout);
338   }
339
340   if (regno >= 0 && regno < MAX_REGS)
341     d_fpga_shadows[regno] = value;
342
343   return usrp_write_fpga_reg (d_udh, regno, (value & 0xffff) | ((mask & 0xffff)<<16));
344 }
345
346
347 bool
348 usrp_basic::_read_fpga_reg (int regno, int *value)
349 {
350   return usrp_read_fpga_reg (d_udh, regno, value);
351 }
352
353 int
354 usrp_basic::_read_fpga_reg (int regno)
355 {
356   int value;
357   if (!_read_fpga_reg (regno, &value))
358     return READ_FAILED;
359   return value;
360 }
361
362 bool
363 usrp_basic::_write_9862 (int which_codec, int regno, unsigned char value)
364 {
365   if (0 && d_verbose){
366     // FIXME really want to enable logging in usrp_prims:usrp_9862_write
367     fprintf(stdout, "_write_9862(codec = %d, regno = %2d, val = 0x%02x)\n", which_codec, regno, value);
368     fflush(stdout);
369   }
370
371   return usrp_9862_write (d_udh, which_codec, regno, value);
372 }
373
374
375 bool
376 usrp_basic::_read_9862 (int which_codec, int regno, unsigned char *value) const
377 {
378   return usrp_9862_read (d_udh, which_codec, regno, value);
379 }
380
381 int
382 usrp_basic::_read_9862 (int which_codec, int regno) const
383 {
384   unsigned char value;
385   if (!_read_9862 (which_codec, regno, &value))
386     return READ_FAILED;
387   return value;
388 }
389
390 bool
391 usrp_basic::_write_spi (int optional_header, int enables, int format, std::string buf)
392 {
393   return usrp_spi_write (d_udh, optional_header, enables, format,
394                          buf.data(), buf.size());
395 }
396
397 std::string
398 usrp_basic::_read_spi (int optional_header, int enables, int format, int len)
399 {
400   if (len <= 0)
401     return "";
402
403   char buf[len];
404
405   if (!usrp_spi_read (d_udh, optional_header, enables, format, buf, len))
406     return "";
407
408   return std::string (buf, len);
409 }
410
411
412 bool
413 usrp_basic::_set_led (int which_led, bool on)
414 {
415   return usrp_set_led (d_udh, which_led, on);
416 }
417
418 bool
419 usrp_basic::write_atr_tx_delay(int value)
420 {
421   return _write_fpga_reg(FR_ATR_TX_DELAY, value);
422 }
423
424 bool
425 usrp_basic::write_atr_rx_delay(int value)
426 {
427   return _write_fpga_reg(FR_ATR_RX_DELAY, value);
428 }
429
430 /*
431  * ----------------------------------------------------------------
432  * Routines to access and control daughterboard specific i/o
433  * ----------------------------------------------------------------
434  */
435 static int
436 slot_id_to_oe_reg (int slot_id)
437 {
438   static int reg[4]  = { FR_OE_0, FR_OE_1, FR_OE_2, FR_OE_3 };
439   assert (0 <= slot_id && slot_id < 4);
440   return reg[slot_id];
441 }
442
443 static int
444 slot_id_to_io_reg (int slot_id)
445 {
446   static int reg[4]  = { FR_IO_0, FR_IO_1, FR_IO_2, FR_IO_3 };
447   assert (0 <= slot_id && slot_id < 4);
448   return reg[slot_id];
449 }
450
451 static int
452 slot_id_to_refclk_reg(int slot_id)
453 {
454   static int reg[4]  = { FR_TX_A_REFCLK, FR_RX_A_REFCLK, FR_TX_B_REFCLK, FR_RX_B_REFCLK };
455   assert (0 <= slot_id && slot_id < 4);
456   return reg[slot_id];
457 }
458
459 static int
460 slot_id_to_atr_mask_reg(int slot_id)
461 {
462   static int reg[4]  = { FR_ATR_MASK_0, FR_ATR_MASK_1, FR_ATR_MASK_2, FR_ATR_MASK_3 };
463   assert (0 <= slot_id && slot_id < 4);
464   return reg[slot_id];
465 }
466
467 static int
468 slot_id_to_atr_txval_reg(int slot_id)
469 {
470   static int reg[4]  = { FR_ATR_TXVAL_0, FR_ATR_TXVAL_1, FR_ATR_TXVAL_2, FR_ATR_TXVAL_3 };
471   assert (0 <= slot_id && slot_id < 4);
472   return reg[slot_id];
473 }
474
475 static int
476 slot_id_to_atr_rxval_reg(int slot_id)
477 {
478   static int reg[4]  = { FR_ATR_RXVAL_0, FR_ATR_RXVAL_1, FR_ATR_RXVAL_2, FR_ATR_RXVAL_3 };
479   assert (0 <= slot_id && slot_id < 4);
480   return reg[slot_id];
481 }
482
483 static int
484 to_slot(txrx_t txrx, int which_side)
485 {
486   // TX_A = 0
487   // RX_A = 1
488   // TX_B = 2
489   // RX_B = 3
490   return ((which_side & 0x1) << 1) | ((txrx & 0x1) == C_RX);
491 }
492
493 bool
494 usrp_basic::common_set_pga(txrx_t txrx, int which_amp, double gain)
495 {
496   if (which_amp < 0 || which_amp > 3)
497     return false;
498
499   gain = std::min(common_pga_max(txrx),
500                   std::max(common_pga_min(txrx), gain));
501
502   int codec = which_amp >> 1;   
503   int int_gain = (int) rint((gain - common_pga_min(txrx)) / common_pga_db_per_step(txrx));
504
505   if (txrx == C_TX){            // 0 and 1 are same, as are 2 and 3
506     return _write_9862(codec, REG_TX_PGA, int_gain);
507   }
508   else {
509     int reg = (which_amp & 1) == 0 ? REG_RX_A : REG_RX_B;
510
511     // read current value to get input buffer bypass flag.
512     unsigned char cur_rx;
513     if (!_read_9862(codec, reg, &cur_rx))
514       return false;
515
516     cur_rx = (cur_rx & RX_X_BYPASS_INPUT_BUFFER) | (int_gain & 0x7f);
517     return _write_9862(codec, reg, cur_rx);
518   }
519 }
520
521 double
522 usrp_basic::common_pga(txrx_t txrx, int which_amp) const
523 {
524   if (which_amp < 0 || which_amp > 3)
525     return READ_FAILED;
526
527   if (txrx == C_TX){
528     int codec = which_amp >> 1;
529     unsigned char v;
530     bool ok = _read_9862 (codec, REG_TX_PGA, &v);
531     if (!ok)
532       return READ_FAILED;
533
534     return (pga_db_per_step() * v) + pga_min();
535   }
536   else {
537     int codec = which_amp >> 1;
538     int reg = (which_amp & 1) == 0 ? REG_RX_A : REG_RX_B;
539     unsigned char v;
540     bool ok = _read_9862 (codec, reg, &v);
541     if (!ok)
542       return READ_FAILED;
543
544     return (pga_db_per_step() * (v & 0x1f)) + pga_min();
545   }
546 }
547
548 double
549 usrp_basic::common_pga_min(txrx_t txrx) const
550 {
551   if (txrx == C_TX)
552     return -20.0;
553   else
554     return   0.0;
555 }
556
557 double
558 usrp_basic::common_pga_max(txrx_t txrx) const
559 {
560   if (txrx == C_TX)
561     return   0.0;
562   else
563     return  20.0;
564 }
565
566 double
567 usrp_basic::common_pga_db_per_step(txrx_t txrx) const
568 {
569   if (txrx == C_TX)
570     return  20.0 / 255;
571   else
572     return  20.0 / 20;
573 }
574
575 bool
576 usrp_basic::_common_write_oe(txrx_t txrx, int which_side, int value, int mask)
577 {
578   if (! (0 <= which_side && which_side <= 1))
579     return false;
580
581   return _write_fpga_reg(slot_id_to_oe_reg(to_slot(txrx, which_side)),
582                          (mask << 16) | (value & 0xffff));
583 }
584
585 bool
586 usrp_basic::common_write_io(txrx_t txrx, int which_side, int value, int mask)
587 {
588   if (! (0 <= which_side && which_side <= 1))
589     return false;
590
591   return _write_fpga_reg(slot_id_to_io_reg(to_slot(txrx, which_side)),
592                          (mask << 16) | (value & 0xffff));
593 }
594
595 bool
596 usrp_basic::common_read_io(txrx_t txrx, int which_side, int *value)
597 {
598   if (! (0 <= which_side && which_side <= 1))
599     return false;
600
601   int t;
602   int reg = which_side + 1;     // FIXME, *very* magic number (fix in serial_io.v)
603   bool ok = _read_fpga_reg(reg, &t);
604   if (!ok)
605     return false;
606
607   if (txrx == C_TX){
608     *value = t & 0xffff;                // FIXME, more magic
609     return true;
610   }
611   else {
612     *value = (t >> 16) & 0xffff;        // FIXME, more magic
613     return true;
614   }
615 }
616
617 int
618 usrp_basic::common_read_io(txrx_t txrx, int which_side)
619 {
620   int   value;
621   if (!common_read_io(txrx, which_side, &value))
622     return READ_FAILED;
623   return value;
624 }
625
626 bool
627 usrp_basic::common_write_refclk(txrx_t txrx, int which_side, int value)
628 {
629   if (! (0 <= which_side && which_side <= 1))
630     return false;
631
632   return _write_fpga_reg(slot_id_to_refclk_reg(to_slot(txrx, which_side)),
633                          value);
634 }
635
636 bool
637 usrp_basic::common_write_atr_mask(txrx_t txrx, int which_side, int value)
638 {
639   if (! (0 <= which_side && which_side <= 1))
640     return false;
641
642   return _write_fpga_reg(slot_id_to_atr_mask_reg(to_slot(txrx, which_side)),
643                          value);
644 }
645
646 bool
647 usrp_basic::common_write_atr_txval(txrx_t txrx, int which_side, int value)
648 {
649   if (! (0 <= which_side && which_side <= 1))
650     return false;
651
652   return _write_fpga_reg(slot_id_to_atr_txval_reg(to_slot(txrx, which_side)),
653                          value);
654 }
655
656 bool
657 usrp_basic::common_write_atr_rxval(txrx_t txrx, int which_side, int value)
658 {
659   if (! (0 <= which_side && which_side <= 1))
660     return false;
661
662   return _write_fpga_reg(slot_id_to_atr_rxval_reg(to_slot(txrx, which_side)),
663                          value);
664 }
665
666 bool
667 usrp_basic::common_write_aux_dac(txrx_t txrx, int which_side, int which_dac, int value)
668 {
669   return _write_aux_dac(to_slot(txrx, which_side), which_dac, value);
670 }
671
672 bool
673 usrp_basic::common_read_aux_adc(txrx_t txrx, int which_side, int which_adc, int *value)
674 {
675   return _read_aux_adc(to_slot(txrx, which_side), which_adc, value);
676 }
677
678 int
679 usrp_basic::common_read_aux_adc(txrx_t txrx, int which_side, int which_adc)
680 {
681   return _read_aux_adc(to_slot(txrx, which_side), which_adc);
682 }
683
684
685 ////////////////////////////////////////////////////////////////
686 //
687 //                         usrp_basic_rx
688 //
689 ////////////////////////////////////////////////////////////////
690
691 static unsigned char rx_init_regs[] = {
692   REG_RX_PWR_DN,        0,
693   REG_RX_A,             0,      // minimum gain = 0x00 (max gain = 0x14)
694   REG_RX_B,             0,      // minimum gain = 0x00 (max gain = 0x14)
695   REG_RX_MISC,          (RX_MISC_HS_DUTY_CYCLE | RX_MISC_CLK_DUTY),
696   REG_RX_IF,            (RX_IF_USE_CLKOUT1
697                          | RX_IF_2S_COMP),
698   REG_RX_DIGITAL,       (RX_DIGITAL_2_CHAN)
699 };
700
701
702 usrp_basic_rx::usrp_basic_rx (int which_board, int fusb_block_size, int fusb_nblocks,
703                               const std::string fpga_filename,
704                               const std::string firmware_filename
705                               )
706   : usrp_basic (which_board, open_rx_interface, fpga_filename, firmware_filename),
707     d_devhandle (0), d_ephandle (0),
708     d_bytes_seen (0), d_first_read (true),
709     d_rx_enable (false)
710 {
711   // initialize rx specific registers
712
713   if (!usrp_9862_write_many_all (d_udh, rx_init_regs, sizeof (rx_init_regs))){
714     fprintf (stderr, "usrp_basic_rx: failed to init AD9862 RX regs\n");
715     throw std::runtime_error ("usrp_basic_rx/init_9862");
716   }
717
718   if (0){
719     // FIXME power down 2nd codec rx path
720     usrp_9862_write (d_udh, 1, REG_RX_PWR_DN, 0x1);     // power down everything
721   }
722
723   // Reset the rx path and leave it disabled.
724   set_rx_enable (false);
725   usrp_set_fpga_rx_reset (d_udh, true);
726   usrp_set_fpga_rx_reset (d_udh, false);
727
728   set_fpga_rx_sample_rate_divisor (2);  // usually correct
729
730   set_dc_offset_cl_enable(0xf, 0xf);    // enable DC offset removal control loops
731
732   probe_rx_slots (false);
733
734   //d_db[0] = instantiate_dbs(d_dbid[0], this, 0);
735   //d_db[1] = instantiate_dbs(d_dbid[1], this, 1);
736
737   // check fusb buffering parameters
738
739   if (fusb_block_size < 0 || fusb_block_size > FUSB_BLOCK_SIZE)
740     throw std::out_of_range ("usrp_basic_rx: invalid fusb_block_size");
741
742   if (fusb_nblocks < 0)
743     throw std::out_of_range ("usrp_basic_rx: invalid fusb_nblocks");
744
745   if (fusb_block_size == 0)
746     fusb_block_size = fusb_sysconfig::default_block_size();
747
748   if (fusb_nblocks == 0)
749     fusb_nblocks = std::max (1, FUSB_BUFFER_SIZE / fusb_block_size);
750
751   d_devhandle = fusb_sysconfig::make_devhandle (d_udh, d_ctx);
752   d_ephandle = d_devhandle->make_ephandle (USRP_RX_ENDPOINT, true,
753                                            fusb_block_size, fusb_nblocks);
754
755   write_atr_mask(0, 0);         // zero Rx A Auto Transmit/Receive regs
756   write_atr_txval(0, 0);
757   write_atr_rxval(0, 0);
758   write_atr_mask(1, 0);         // zero Rx B Auto Transmit/Receive regs
759   write_atr_txval(1, 0);
760   write_atr_rxval(1, 0);
761 }
762
763 static unsigned char rx_fini_regs[] = {
764   REG_RX_PWR_DN,        0x1                             // power down everything
765 };
766
767 usrp_basic_rx::~usrp_basic_rx ()
768 {
769   if (!set_rx_enable (false)){
770     fprintf (stderr, "usrp_basic_rx: set_fpga_rx_enable failed\n");
771   }
772
773   d_ephandle->stop ();
774   delete d_ephandle;
775   delete d_devhandle;
776
777   if (!usrp_9862_write_many_all (d_udh, rx_fini_regs, sizeof (rx_fini_regs))){
778     fprintf (stderr, "usrp_basic_rx: failed to fini AD9862 RX regs\n");
779   }
780
781   shutdown_daughterboards();
782 }
783
784
785 bool
786 usrp_basic_rx::start ()
787 {
788   if (!usrp_basic::start ())    // invoke parent's method
789     return false;
790
791   // fire off reads before asserting rx_enable
792
793   if (!d_ephandle->start ()){
794     fprintf (stderr, "usrp_basic_rx: failed to start end point streaming");
795     return false;
796   }
797
798   if (!set_rx_enable (true)){
799     fprintf (stderr, "usrp_basic_rx: set_rx_enable failed\n");
800     return false;
801   }
802
803   return true;
804 }
805
806 bool
807 usrp_basic_rx::stop ()
808 {
809   bool ok = usrp_basic::stop();
810
811   if (!set_rx_enable(false)){
812     fprintf (stderr, "usrp_basic_rx: set_rx_enable(false) failed\n");
813     ok = false;
814   }
815
816   if (!d_ephandle->stop()){
817     fprintf (stderr, "usrp_basic_rx: failed to stop end point streaming");
818     ok = false;
819   }
820
821   return ok;
822 }
823
824 usrp_basic_rx *
825 usrp_basic_rx::make (int which_board, int fusb_block_size, int fusb_nblocks,
826                      const std::string fpga_filename,
827                      const std::string firmware_filename)
828 {
829   usrp_basic_rx *u = 0;
830
831   try {
832     u = new usrp_basic_rx (which_board, fusb_block_size, fusb_nblocks,
833                            fpga_filename, firmware_filename);
834     return u;
835   }
836   catch (...){
837     delete u;
838     return 0;
839   }
840
841   return u;
842 }
843
844 bool
845 usrp_basic_rx::set_fpga_rx_sample_rate_divisor (unsigned int div)
846 {
847   return _write_fpga_reg (FR_RX_SAMPLE_RATE_DIV, div - 1);
848 }
849
850
851 /*
852  * \brief read data from the D/A's via the FPGA.
853  * \p len must be a multiple of 512 bytes.
854  *
855  * \returns the number of bytes read, or -1 on error.
856  *
857  * If overrun is non-NULL it will be set true iff an RX overrun is detected.
858  */
859 int
860 usrp_basic_rx::read (void *buf, int len, bool *overrun)
861 {
862   int   r;
863
864   if (overrun)
865     *overrun = false;
866
867   if (len < 0 || (len % 512) != 0){
868     fprintf (stderr, "usrp_basic_rx::read: invalid length = %d\n", len);
869     return -1;
870   }
871
872   r = d_ephandle->read (buf, len);
873   if (r > 0)
874     d_bytes_seen += r;
875
876   /*
877    * In many cases, the FPGA reports an rx overrun right after we
878    * enable the Rx path.  If this is our first read, check for the
879    * overrun to clear the condition, then ignore the result.
880    */
881   if (0 && d_first_read){       // FIXME
882     d_first_read = false;
883     bool bogus_overrun;
884     usrp_check_rx_overrun (d_udh, &bogus_overrun);
885   }
886
887   if (overrun != 0 && d_bytes_seen >= d_bytes_per_poll){
888     d_bytes_seen = 0;
889     if (!usrp_check_rx_overrun (d_udh, overrun)){
890       fprintf (stderr, "usrp_basic_rx: usrp_check_rx_overrun failed\n");
891     }
892   }
893
894   return r;
895 }
896
897 bool
898 usrp_basic_rx::set_rx_enable (bool on)
899 {
900   d_rx_enable = on;
901   return usrp_set_fpga_rx_enable (d_udh, on);
902 }
903
904 // conditional disable, return prev state
905 bool
906 usrp_basic_rx::disable_rx ()
907 {
908   bool enabled = rx_enable ();
909   if (enabled)
910     set_rx_enable (false);
911   return enabled;
912 }
913
914 // conditional set
915 void
916 usrp_basic_rx::restore_rx (bool on)
917 {
918   if (on != rx_enable ())
919     set_rx_enable (on);
920 }
921
922 void
923 usrp_basic_rx::probe_rx_slots (bool verbose)
924 {
925   struct usrp_dboard_eeprom     eeprom;
926   static int slot_id_map[2] = { SLOT_RX_A, SLOT_RX_B };
927   static const char *slot_name[2] = { "RX d'board A", "RX d'board B" };
928
929   for (int i = 0; i < 2; i++){
930     int slot_id = slot_id_map [i];
931     const char *msg = 0;
932     usrp_dbeeprom_status_t s = usrp_read_dboard_eeprom (d_udh, slot_id, &eeprom);
933
934     switch (s){
935     case UDBE_OK:
936       d_dbid[i] = eeprom.id;
937       msg = usrp_dbid_to_string (eeprom.id).c_str ();
938       set_adc_offset (2*i+0, eeprom.offset[0]);
939       set_adc_offset (2*i+1, eeprom.offset[1]);
940       _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | eeprom.oe);
941       _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
942       break;
943
944     case UDBE_NO_EEPROM:
945       d_dbid[i] = -1;
946       msg = "<none>";
947       _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
948       _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
949       break;
950
951     case UDBE_INVALID_EEPROM:
952       d_dbid[i] = -2;
953       msg = "Invalid EEPROM contents";
954       _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
955       _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
956       break;
957
958     case UDBE_BAD_SLOT:
959     default:
960       assert (0);
961     }
962
963     if (verbose){
964       fflush (stdout);
965       fprintf (stderr, "%s: %s\n", slot_name[i], msg);
966     }
967   }
968 }
969
970 bool
971 usrp_basic_rx::set_pga (int which_amp, double gain)
972 {
973   return common_set_pga(C_RX, which_amp, gain);
974 }
975
976 double
977 usrp_basic_rx::pga(int which_amp) const
978 {
979   return common_pga(C_RX, which_amp);
980 }
981
982 double
983 usrp_basic_rx::pga_min() const
984 {
985   return common_pga_min(C_RX);
986 }
987
988 double
989 usrp_basic_rx::pga_max() const
990 {
991   return common_pga_max(C_RX);
992 }
993
994 double
995 usrp_basic_rx::pga_db_per_step() const
996 {
997   return common_pga_db_per_step(C_RX);
998 }
999
1000 bool
1001 usrp_basic_rx::_write_oe (int which_side, int value, int mask)
1002 {
1003   return _common_write_oe(C_RX, which_side, value, mask);
1004 }
1005
1006 bool
1007 usrp_basic_rx::write_io (int which_side, int value, int mask)
1008 {
1009   return common_write_io(C_RX, which_side, value, mask);
1010 }
1011
1012 bool
1013 usrp_basic_rx::read_io (int which_side, int *value)
1014 {
1015   return common_read_io(C_RX, which_side, value);
1016 }
1017
1018 int
1019 usrp_basic_rx::read_io (int which_side)
1020 {
1021   return common_read_io(C_RX, which_side);
1022 }
1023
1024 bool
1025 usrp_basic_rx::write_refclk(int which_side, int value)
1026 {
1027   return common_write_refclk(C_RX, which_side, value);
1028 }
1029
1030 bool
1031 usrp_basic_rx::write_atr_mask(int which_side, int value)
1032 {
1033   return common_write_atr_mask(C_RX, which_side, value);
1034 }
1035
1036 bool
1037 usrp_basic_rx::write_atr_txval(int which_side, int value)
1038 {
1039   return common_write_atr_txval(C_RX, which_side, value);
1040 }
1041
1042 bool
1043 usrp_basic_rx::write_atr_rxval(int which_side, int value)
1044 {
1045   return common_write_atr_rxval(C_RX, which_side, value);
1046 }
1047
1048 bool
1049 usrp_basic_rx::write_aux_dac (int which_side, int which_dac, int value)
1050 {
1051   return common_write_aux_dac(C_RX, which_side, which_dac, value);
1052 }
1053
1054 bool
1055 usrp_basic_rx::read_aux_adc (int which_side, int which_adc, int *value)
1056 {
1057   return common_read_aux_adc(C_RX, which_side, which_adc, value);
1058 }
1059
1060 int
1061 usrp_basic_rx::read_aux_adc (int which_side, int which_adc)
1062 {
1063   return common_read_aux_adc(C_RX, which_side, which_adc);
1064 }
1065
1066 int
1067 usrp_basic_rx::block_size () const { return d_ephandle->block_size(); }
1068
1069 ////////////////////////////////////////////////////////////////
1070 //
1071 //                         usrp_basic_tx
1072 //
1073 ////////////////////////////////////////////////////////////////
1074
1075
1076 //
1077 // DAC input rate 64 MHz interleaved for a total input rate of 128 MHz
1078 // DAC input is latched on rising edge of CLKOUT2
1079 // NCO is disabled
1080 // interpolate 2x
1081 // coarse modulator disabled
1082 //
1083
1084 static unsigned char tx_init_regs[] = {
1085   REG_TX_PWR_DN,        0,
1086   REG_TX_A_OFFSET_LO,   0,
1087   REG_TX_A_OFFSET_HI,   0,
1088   REG_TX_B_OFFSET_LO,   0,
1089   REG_TX_B_OFFSET_HI,   0,
1090   REG_TX_A_GAIN,        (TX_X_GAIN_COARSE_FULL | 0),
1091   REG_TX_B_GAIN,        (TX_X_GAIN_COARSE_FULL | 0),
1092   REG_TX_PGA,           0xff,                   // maximum gain (0 dB)
1093   REG_TX_MISC,          0,
1094   REG_TX_IF,            (TX_IF_USE_CLKOUT1
1095                          | TX_IF_I_FIRST
1096                          | TX_IF_INV_TX_SYNC
1097                          | TX_IF_2S_COMP
1098                          | TX_IF_INTERLEAVED),
1099   REG_TX_DIGITAL,       (TX_DIGITAL_2_DATA_PATHS
1100                          | TX_DIGITAL_INTERPOLATE_4X),
1101   REG_TX_MODULATOR,     (TX_MODULATOR_DISABLE_NCO
1102                          | TX_MODULATOR_COARSE_MODULATION_NONE),
1103   REG_TX_NCO_FTW_7_0,   0,
1104   REG_TX_NCO_FTW_15_8,  0,
1105   REG_TX_NCO_FTW_23_16, 0
1106 };
1107
1108 usrp_basic_tx::usrp_basic_tx (int which_board, int fusb_block_size, int fusb_nblocks,
1109                               const std::string fpga_filename,
1110                               const std::string firmware_filename)
1111   : usrp_basic (which_board, open_tx_interface, fpga_filename, firmware_filename),
1112     d_devhandle (0), d_ephandle (0),
1113     d_bytes_seen (0), d_first_write (true),
1114     d_tx_enable (false)
1115 {
1116   if (!usrp_9862_write_many_all (d_udh, tx_init_regs, sizeof (tx_init_regs))){
1117     fprintf (stderr, "usrp_basic_tx: failed to init AD9862 TX regs\n");
1118     throw std::runtime_error ("usrp_basic_tx/init_9862");
1119   }
1120
1121   if (0){
1122     // FIXME power down 2nd codec tx path
1123     usrp_9862_write (d_udh, 1, REG_TX_PWR_DN,
1124                      (TX_PWR_DN_TX_DIGITAL
1125                       | TX_PWR_DN_TX_ANALOG_BOTH));
1126   }
1127
1128   // Reset the tx path and leave it disabled.
1129   set_tx_enable (false);
1130   usrp_set_fpga_tx_reset (d_udh, true);
1131   usrp_set_fpga_tx_reset (d_udh, false);
1132
1133   set_fpga_tx_sample_rate_divisor (4);  // we're using interp x4
1134
1135   probe_tx_slots (false);
1136
1137   //d_db[0] = instantiate_dbs(d_dbid[0], this, 0);
1138   //d_db[1] = instantiate_dbs(d_dbid[1], this, 1);
1139
1140   // check fusb buffering parameters
1141
1142   if (fusb_block_size < 0 || fusb_block_size > FUSB_BLOCK_SIZE)
1143     throw std::out_of_range ("usrp_basic_rx: invalid fusb_block_size");
1144
1145   if (fusb_nblocks < 0)
1146     throw std::out_of_range ("usrp_basic_rx: invalid fusb_nblocks");
1147
1148   if (fusb_block_size == 0)
1149     fusb_block_size = FUSB_BLOCK_SIZE;
1150
1151   if (fusb_nblocks == 0)
1152     fusb_nblocks = std::max (1, FUSB_BUFFER_SIZE / fusb_block_size);
1153
1154   d_devhandle = fusb_sysconfig::make_devhandle (d_udh, d_ctx);
1155   d_ephandle = d_devhandle->make_ephandle (USRP_TX_ENDPOINT, false,
1156                                            fusb_block_size, fusb_nblocks);
1157
1158   write_atr_mask(0, 0);         // zero Tx A Auto Transmit/Receive regs
1159   write_atr_txval(0, 0);
1160   write_atr_rxval(0, 0);
1161   write_atr_mask(1, 0);         // zero Tx B Auto Transmit/Receive regs
1162   write_atr_txval(1, 0);
1163   write_atr_rxval(1, 0);
1164 }
1165
1166
1167 static unsigned char tx_fini_regs[] = {
1168   REG_TX_PWR_DN,        (TX_PWR_DN_TX_DIGITAL
1169                          | TX_PWR_DN_TX_ANALOG_BOTH),
1170   REG_TX_MODULATOR,     (TX_MODULATOR_DISABLE_NCO
1171                          | TX_MODULATOR_COARSE_MODULATION_NONE)
1172 };
1173
1174 usrp_basic_tx::~usrp_basic_tx ()
1175 {
1176   d_ephandle->stop ();
1177   delete d_ephandle;
1178   delete d_devhandle;
1179
1180   if (!usrp_9862_write_many_all (d_udh, tx_fini_regs, sizeof (tx_fini_regs))){
1181     fprintf (stderr, "usrp_basic_tx: failed to fini AD9862 TX regs\n");
1182   }
1183
1184   shutdown_daughterboards();
1185 }
1186
1187 bool
1188 usrp_basic_tx::start ()
1189 {
1190   if (!usrp_basic::start ())
1191     return false;
1192
1193   if (!set_tx_enable (true)){
1194     fprintf (stderr, "usrp_basic_tx: set_tx_enable failed\n");
1195     return false;
1196   }
1197
1198   if (!d_ephandle->start ()){
1199     fprintf (stderr, "usrp_basic_tx: failed to start end point streaming");
1200     return false;
1201   }
1202
1203   return true;
1204 }
1205
1206 bool
1207 usrp_basic_tx::stop ()
1208 {
1209   bool ok = usrp_basic::stop ();
1210
1211   if (!d_ephandle->stop ()){
1212     fprintf (stderr, "usrp_basic_tx: failed to stop end point streaming");
1213     ok = false;
1214   }
1215
1216   if (!set_tx_enable (false)){
1217     fprintf (stderr, "usrp_basic_tx: set_tx_enable(false) failed\n");
1218     ok = false;
1219   }
1220
1221   return ok;
1222 }
1223
1224 usrp_basic_tx *
1225 usrp_basic_tx::make (int which_board, int fusb_block_size, int fusb_nblocks,
1226                      const std::string fpga_filename,
1227                      const std::string firmware_filename)
1228 {
1229   usrp_basic_tx *u = 0;
1230
1231   try {
1232     u = new usrp_basic_tx (which_board, fusb_block_size, fusb_nblocks,
1233                            fpga_filename, firmware_filename);
1234     return u;
1235   }
1236   catch (...){
1237     delete u;
1238     return 0;
1239   }
1240
1241   return u;
1242 }
1243
1244 bool
1245 usrp_basic_tx::set_fpga_tx_sample_rate_divisor (unsigned int div)
1246 {
1247   return _write_fpga_reg (FR_TX_SAMPLE_RATE_DIV, div - 1);
1248 }
1249
1250 /*!
1251  * \brief Write data to the A/D's via the FPGA.
1252  *
1253  * \p len must be a multiple of 512 bytes.
1254  * \returns number of bytes written or -1 on error.
1255  *
1256  * if \p underrun is non-NULL, it will be set to true iff
1257  * a transmit underrun condition is detected.
1258  */
1259 int
1260 usrp_basic_tx::write (const void *buf, int len, bool *underrun)
1261 {
1262   int   r;
1263
1264   if (underrun)
1265     *underrun = false;
1266
1267   if (len < 0 || (len % 512) != 0){
1268     fprintf (stderr, "usrp_basic_tx::write: invalid length = %d\n", len);
1269     return -1;
1270   }
1271
1272   r = d_ephandle->write (buf, len);
1273   if (r > 0)
1274     d_bytes_seen += r;
1275
1276   /*
1277    * In many cases, the FPGA reports an tx underrun right after we
1278    * enable the Tx path.  If this is our first write, check for the
1279    * underrun to clear the condition, then ignore the result.
1280    */
1281   if (d_first_write && d_bytes_seen >= 4 * FUSB_BLOCK_SIZE){
1282     d_first_write = false;
1283     bool bogus_underrun;
1284     usrp_check_tx_underrun (d_udh, &bogus_underrun);
1285   }
1286
1287   if (underrun != 0 && d_bytes_seen >= d_bytes_per_poll){
1288     d_bytes_seen = 0;
1289     if (!usrp_check_tx_underrun (d_udh, underrun)){
1290       fprintf (stderr, "usrp_basic_tx: usrp_check_tx_underrun failed\n");
1291     }
1292   }
1293
1294   return r;
1295 }
1296
1297 void
1298 usrp_basic_tx::wait_for_completion ()
1299 {
1300   d_ephandle->wait_for_completion ();
1301 }
1302
1303 bool
1304 usrp_basic_tx::set_tx_enable (bool on)
1305 {
1306   d_tx_enable = on;
1307   // fprintf (stderr, "set_tx_enable %d\n", on);
1308   return usrp_set_fpga_tx_enable (d_udh, on);
1309 }
1310
1311 // conditional disable, return prev state
1312 bool
1313 usrp_basic_tx::disable_tx ()
1314 {
1315   bool enabled = tx_enable ();
1316   if (enabled)
1317     set_tx_enable (false);
1318   return enabled;
1319 }
1320
1321 // conditional set
1322 void
1323 usrp_basic_tx::restore_tx (bool on)
1324 {
1325   if (on != tx_enable ())
1326     set_tx_enable (on);
1327 }
1328
1329 void
1330 usrp_basic_tx::probe_tx_slots (bool verbose)
1331 {
1332   struct usrp_dboard_eeprom     eeprom;
1333   static int slot_id_map[2] = { SLOT_TX_A, SLOT_TX_B };
1334   static const char *slot_name[2] = { "TX d'board A", "TX d'board B" };
1335
1336   for (int i = 0; i < 2; i++){
1337     int slot_id = slot_id_map [i];
1338     const char *msg = 0;
1339     usrp_dbeeprom_status_t s = usrp_read_dboard_eeprom (d_udh, slot_id, &eeprom);
1340
1341     switch (s){
1342     case UDBE_OK:
1343       d_dbid[i] = eeprom.id;
1344       msg = usrp_dbid_to_string (eeprom.id).c_str ();
1345       // FIXME, figure out interpretation of dc offset for TX d'boards
1346       // offset = (eeprom.offset[1] << 16) | (eeprom.offset[0] & 0xffff);
1347       _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | eeprom.oe);
1348       _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
1349       break;
1350
1351     case UDBE_NO_EEPROM:
1352       d_dbid[i] = -1;
1353       msg = "<none>";
1354       _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
1355       _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
1356       break;
1357
1358     case UDBE_INVALID_EEPROM:
1359       d_dbid[i] = -2;
1360       msg = "Invalid EEPROM contents";
1361       _write_fpga_reg (slot_id_to_oe_reg(slot_id), (0xffff << 16) | 0x0000);
1362       _write_fpga_reg (slot_id_to_io_reg(slot_id), (0xffff << 16) | 0x0000);
1363       break;
1364
1365     case UDBE_BAD_SLOT:
1366     default:
1367       assert (0);
1368     }
1369
1370     if (verbose){
1371       fflush (stdout);
1372       fprintf (stderr, "%s: %s\n", slot_name[i], msg);
1373     }
1374   }
1375 }
1376
1377 bool
1378 usrp_basic_tx::set_pga (int which_amp, double gain)
1379 {
1380   return common_set_pga(C_TX, which_amp, gain);
1381 }
1382
1383 double
1384 usrp_basic_tx::pga (int which_amp) const
1385 {
1386   return common_pga(C_TX, which_amp);
1387 }
1388
1389 double
1390 usrp_basic_tx::pga_min() const
1391 {
1392   return common_pga_min(C_TX);
1393 }
1394
1395 double
1396 usrp_basic_tx::pga_max() const
1397 {
1398   return common_pga_max(C_TX);
1399 }
1400
1401 double
1402 usrp_basic_tx::pga_db_per_step() const
1403 {
1404   return common_pga_db_per_step(C_TX);
1405 }
1406
1407 bool
1408 usrp_basic_tx::_write_oe (int which_side, int value, int mask)
1409 {
1410   return _common_write_oe(C_TX, which_side, value, mask);
1411 }
1412
1413 bool
1414 usrp_basic_tx::write_io (int which_side, int value, int mask)
1415 {
1416   return common_write_io(C_TX, which_side, value, mask);
1417 }
1418
1419 bool
1420 usrp_basic_tx::read_io (int which_side, int *value)
1421 {
1422   return common_read_io(C_TX, which_side, value);
1423 }
1424
1425 int
1426 usrp_basic_tx::read_io (int which_side)
1427 {
1428   return common_read_io(C_TX, which_side);
1429 }
1430
1431 bool
1432 usrp_basic_tx::write_refclk(int which_side, int value)
1433 {
1434   return common_write_refclk(C_TX, which_side, value);
1435 }
1436
1437 bool
1438 usrp_basic_tx::write_atr_mask(int which_side, int value)
1439 {
1440   return common_write_atr_mask(C_TX, which_side, value);
1441 }
1442
1443 bool
1444 usrp_basic_tx::write_atr_txval(int which_side, int value)
1445 {
1446   return common_write_atr_txval(C_TX, which_side, value);
1447 }
1448
1449 bool
1450 usrp_basic_tx::write_atr_rxval(int which_side, int value)
1451 {
1452   return common_write_atr_rxval(C_TX, which_side, value);
1453 }
1454
1455 bool
1456 usrp_basic_tx::write_aux_dac (int which_side, int which_dac, int value)
1457 {
1458   return common_write_aux_dac(C_TX, which_side, which_dac, value);
1459 }
1460
1461 bool
1462 usrp_basic_tx::read_aux_adc (int which_side, int which_adc, int *value)
1463 {
1464   return common_read_aux_adc(C_TX, which_side, which_adc, value);
1465 }
1466
1467 int
1468 usrp_basic_tx::read_aux_adc (int which_side, int which_adc)
1469 {
1470   return common_read_aux_adc(C_TX, which_side, which_adc);
1471 }
1472
1473 int
1474 usrp_basic_tx::block_size () const { return d_ephandle->block_size(); }
1475