Imported Upstream version 3.0.4
[debian/gnuradio] / usrp / host / lib / usrp_standard.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 #include <usrp_standard.h>
24
25 #include "usrp_prims.h"
26 #include "fpga_regs_common.h"
27 #include "fpga_regs_standard.h"
28 #include <stdexcept>
29 #include <assert.h>
30 #include <math.h>
31 #include <ad9862.h>
32
33
34 static const int OLD_CAPS_VAL = 0xaa55ff77;
35 static const int DEFAULT_CAPS_VAL = ((2 << bmFR_RB_CAPS_NDUC_SHIFT)
36                                      | (2 << bmFR_RB_CAPS_NDDC_SHIFT)
37                                      | bmFR_RB_CAPS_RX_HAS_HALFBAND);
38
39 // #define USE_FPGA_TX_CORDIC
40
41
42 using namespace ad9862;
43
44 #define NELEM(x) (sizeof (x) / sizeof (x[0]))
45
46
47 static unsigned int
48 compute_freq_control_word_fpga (double master_freq, double target_freq,
49                                 double *actual_freq, bool verbose)
50 {
51   static const int NBITS = 14;
52   
53   int   v = (int) rint (target_freq / master_freq * pow (2.0, 32.0));
54
55   if (0)
56     v = (v >> (32 - NBITS)) << (32 - NBITS);    // keep only top NBITS
57
58   *actual_freq = v * master_freq / pow (2.0, 32.0);
59
60   if (verbose)
61     fprintf (stderr,
62              "compute_freq_control_word_fpga: target = %g  actual = %g  delta = %g\n",
63              target_freq, *actual_freq, *actual_freq - target_freq);
64
65   return (unsigned int) v;
66 }
67
68 // The 9862 uses an unsigned 24-bit frequency tuning word and 
69 // a separate register to control the sign.
70
71 static unsigned int
72 compute_freq_control_word_9862 (double master_freq, double target_freq,
73                                 double *actual_freq, bool verbose)
74 {
75   double sign = 1.0;
76
77   if (target_freq < 0)
78     sign = -1.0;
79
80   int   v = (int) rint (fabs (target_freq) / master_freq * pow (2.0, 24.0));
81   *actual_freq = v * master_freq / pow (2.0, 24.0) * sign;
82
83   if (verbose)
84     fprintf (stderr,
85      "compute_freq_control_word_9862: target = %g  actual = %g  delta = %g  v = %8d\n",
86      target_freq, *actual_freq, *actual_freq - target_freq, v);
87
88   return (unsigned int) v;
89 }
90
91 // ----------------------------------------------------------------
92
93 usrp_standard_common::usrp_standard_common(usrp_basic *parent)
94 {
95   // read new FPGA capability register
96   if (!parent->_read_fpga_reg(FR_RB_CAPS, &d_fpga_caps)){
97     fprintf (stderr, "usrp_standard_common: failed to read FPGA cap register.\n");
98     throw std::runtime_error ("usrp_standard_common::ctor");
99   }
100   // If we don't have the cap register, set the value to what it would
101   // have had if we did have one ;)
102   if (d_fpga_caps == OLD_CAPS_VAL)
103     d_fpga_caps = DEFAULT_CAPS_VAL;
104
105   if (0){
106     fprintf(stdout, "has_rx_halfband = %d\n", has_rx_halfband());
107     fprintf(stdout, "nddcs           = %d\n", nddcs());
108     fprintf(stdout, "has_tx_halfband = %d\n", has_tx_halfband());
109     fprintf(stdout, "nducs           = %d\n", nducs());
110   }
111 }
112
113 bool
114 usrp_standard_common::has_rx_halfband() const
115 {
116   return (d_fpga_caps & bmFR_RB_CAPS_RX_HAS_HALFBAND) ? true : false;
117 }
118
119 int
120 usrp_standard_common::nddcs() const
121 {
122   return (d_fpga_caps & bmFR_RB_CAPS_NDDC_MASK) >> bmFR_RB_CAPS_NDDC_SHIFT;
123 }
124
125 bool
126 usrp_standard_common::has_tx_halfband() const
127 {
128   return (d_fpga_caps & bmFR_RB_CAPS_TX_HAS_HALFBAND) ? true : false;
129 }
130
131 int
132 usrp_standard_common::nducs() const
133 {
134   return (d_fpga_caps & bmFR_RB_CAPS_NDUC_MASK) >> bmFR_RB_CAPS_NDUC_SHIFT;
135 }
136
137 // ----------------------------------------------------------------
138
139 static int 
140 real_rx_mux_value (int mux, int nchan)
141 {
142   if (mux != -1)
143     return mux;
144
145   return 0x32103210;
146 }
147
148 usrp_standard_rx::usrp_standard_rx (int which_board,
149                                     unsigned int decim_rate,
150                                     int nchan, int mux, int mode,
151                                     int fusb_block_size, int fusb_nblocks,
152                                     const std::string fpga_filename,
153                                     const std::string firmware_filename
154                                     )
155   : usrp_basic_rx (which_board, fusb_block_size, fusb_nblocks,
156                    fpga_filename, firmware_filename),
157     usrp_standard_common(this),
158     d_nchan (1), d_sw_mux (0x0), d_hw_mux (0x0)
159 {
160   if (!set_format(make_format())){
161     fprintf (stderr, "usrp_standard_rx: set_format failed\n");
162     throw std::runtime_error ("usrp_standard_rx::ctor");
163   }
164   if (!set_nchannels (nchan)){
165     fprintf (stderr, "usrp_standard_rx: set_nchannels failed\n");
166     throw std::runtime_error ("usrp_standard_rx::ctor");
167   }
168   if (!set_decim_rate (decim_rate)){
169     fprintf (stderr, "usrp_standard_rx: set_decim_rate failed\n");
170     throw std::runtime_error ("usrp_standard_rx::ctor");
171   }
172   if (!set_mux (real_rx_mux_value (mux, nchan))){
173     fprintf (stderr, "usrp_standard_rx: set_mux failed\n");
174     throw std::runtime_error ("usrp_standard_rx::ctor");
175   }
176   if (!set_fpga_mode (mode)){
177     fprintf (stderr, "usrp_standard_rx: set_fpga_mode failed\n");
178     throw std::runtime_error ("usrp_standard_rx::ctor");
179   }
180
181   for (int i = 0; i < MAX_CHAN; i++){
182     set_rx_freq(i, 0);
183     set_ddc_phase(i, 0);
184   }
185 }
186
187 usrp_standard_rx::~usrp_standard_rx ()
188 {
189   // fprintf(stderr, "\nusrp_standard_rx: dtor\n");
190 }
191
192 bool
193 usrp_standard_rx::start ()
194 {
195   if (!usrp_basic_rx::start ())
196     return false;
197
198   // add our code here
199
200   return true;
201 }
202
203 bool
204 usrp_standard_rx::stop ()
205 {
206   bool ok = usrp_basic_rx::stop ();
207
208   // add our code here
209
210   return ok;
211 }
212
213 usrp_standard_rx *
214 usrp_standard_rx::make (int which_board,
215                         unsigned int decim_rate,
216                         int nchan, int mux, int mode,
217                         int fusb_block_size, int fusb_nblocks,
218                         const std::string fpga_filename,
219                         const std::string firmware_filename
220                         )
221 {
222   usrp_standard_rx *u = 0;
223   
224   try {
225     u = new usrp_standard_rx (which_board, decim_rate,
226                               nchan, mux, mode,
227                               fusb_block_size, fusb_nblocks,
228                               fpga_filename, firmware_filename);
229     return u;
230   }
231   catch (...){
232     delete u;
233     return 0;
234   }
235
236   return u;
237 }
238
239 bool
240 usrp_standard_rx::set_decim_rate(unsigned int rate)
241 {
242   if ((rate & 0x1) || rate < 4 || rate > 256){
243     fprintf (stderr, "usrp_standard_rx::set_decim_rate: rate must be EVEN and in [4, 256]\n");
244     return false;
245   }
246
247   d_decim_rate = rate;
248   set_usb_data_rate ((adc_rate () / rate * nchannels ())
249                      * (2 * sizeof (short)));
250
251   bool s = disable_rx ();
252   int v = has_rx_halfband() ? d_decim_rate/2 - 1 : d_decim_rate - 1;
253   bool ok = _write_fpga_reg (FR_DECIM_RATE, v);
254   restore_rx (s);
255   return ok;
256 }
257
258 bool usrp_standard_rx::set_nchannels (int nchan)
259 {
260   if (!(nchan == 1 || nchan == 2 || nchan == 4))
261     return false;
262
263   if (nchan > nddcs())
264     return false;
265
266   d_nchan = nchan;
267
268   return write_hw_mux_reg ();
269 }
270
271
272 // map software mux value to hw mux value
273 //
274 // Software mux value:
275 //
276 //    3                   2                   1                       
277 //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
278 // +-------+-------+-------+-------+-------+-------+-------+-------+
279 // |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
280 // +-------+-------+-------+-------+-------+-------+-------+-------+
281 //
282 // Each 4-bit I field is either 0,1,2,3
283 // Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
284 // All Q's must be 0xf or none of them may be 0xf
285 //
286 //
287 // Hardware mux value:
288 //
289 //    3                   2                   1                       
290 //  1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
291 // +-----------------------+-------+-------+-------+-------+-+-----+
292 // |      must be zero     | Q3| I3| Q2| I2| Q1| I1| Q0| I0|Z| NCH |
293 // +-----------------------+-------+-------+-------+-------+-+-----+
294
295
296 static bool
297 map_sw_mux_to_hw_mux (int sw_mux, int *hw_mux_ptr)
298 {
299   // confirm that all I's are either 0,1,2,3 
300
301   for (int i = 0; i < 8; i += 2){
302     int t = (sw_mux >> (4 * i)) & 0xf;
303     if (!(0 <= t && t <= 3))
304       return false;
305   }
306
307   // confirm that all Q's are either 0,1,2,3 or 0xf
308
309   for (int i = 1; i < 8; i += 2){
310     int t = (sw_mux >> (4 * i)) & 0xf;
311     if (!(t == 0xf || (0 <= t && t <= 3)))
312       return false;
313   }
314
315   // confirm that all Q inputs are 0xf (const zero input),
316   // or none of them are 0xf
317
318   int q_and = 1;
319   int q_or =  0;
320
321   for (int i = 0; i < 4; i++){
322     int qx_is_0xf = ((sw_mux >> (8 * i + 4)) & 0xf) == 0xf;
323     q_and &= qx_is_0xf;
324     q_or  |= qx_is_0xf;
325   }
326
327   if (q_and || !q_or){          // OK
328     int hw_mux_value = 0;
329
330     for (int i = 0; i < 8; i++){
331       int t = (sw_mux >> (4 * i)) & 0x3;
332       hw_mux_value |= t << (2 * i + 4);
333     }
334
335     if (q_and)
336       hw_mux_value |= 0x8;      // all Q's zero
337
338     *hw_mux_ptr = hw_mux_value;
339     return true;
340   }
341   else
342     return false;
343 }
344
345 bool
346 usrp_standard_rx::set_mux (int mux)
347 {
348   if (!map_sw_mux_to_hw_mux (mux, &d_hw_mux))
349     return false;
350
351   // fprintf (stderr, "sw_mux = 0x%08x  hw_mux = 0x%08x\n", mux, d_hw_mux);
352
353   d_sw_mux = mux;
354   return write_hw_mux_reg ();
355 }
356
357 bool
358 usrp_standard_rx::write_hw_mux_reg ()
359 {
360   bool s = disable_rx ();
361   bool ok = _write_fpga_reg (FR_RX_MUX, d_hw_mux | d_nchan);
362   restore_rx (s);
363   return ok;
364 }
365
366
367 bool
368 usrp_standard_rx::set_rx_freq (int channel, double freq)
369 {
370   if (channel < 0 || channel > MAX_CHAN)
371     return false;
372
373   unsigned int v =
374     compute_freq_control_word_fpga (adc_freq(),
375                                     freq, &d_rx_freq[channel],
376                                     d_verbose);
377
378   return _write_fpga_reg (FR_RX_FREQ_0 + channel, v);
379 }
380
381 unsigned int
382 usrp_standard_rx::decim_rate () const { return d_decim_rate; }
383
384 int
385 usrp_standard_rx::nchannels () const { return d_nchan; }
386
387 int
388 usrp_standard_rx::mux () const { return d_sw_mux; }
389
390 double 
391 usrp_standard_rx::rx_freq (int channel) const
392 {
393   if (channel < 0 || channel >= MAX_CHAN)
394     return 0;
395
396   return d_rx_freq[channel];
397 }
398
399 bool
400 usrp_standard_rx::set_fpga_mode (int mode)
401 {
402   return _write_fpga_reg (FR_MODE, mode);
403 }
404
405 bool
406 usrp_standard_rx::set_ddc_phase(int channel, int phase)
407 {
408   if (channel < 0 || channel >= MAX_CHAN)
409     return false;
410
411   return _write_fpga_reg(FR_RX_PHASE_0 + channel, phase);
412 }
413
414
415 // To avoid quiet failures, check for things that our code cares about.
416
417 static bool
418 rx_format_is_valid(unsigned int format)
419 {
420   int width =  usrp_standard_rx::format_width(format);
421   int want_q = usrp_standard_rx::format_want_q(format);
422
423   if (!(width == 8 || width == 16))     // FIXME add other widths when valid
424     return false;
425
426   if (!want_q)          // FIXME remove check when the rest of the code can handle I only
427     return false;
428
429   return true;
430 }
431
432 bool
433 usrp_standard_rx::set_format(unsigned int format)
434 {
435   if (!rx_format_is_valid(format))
436     return false;
437
438   return _write_fpga_reg(FR_RX_FORMAT, format);
439 }
440
441 unsigned int
442 usrp_standard_rx::format() const
443 {
444   return d_fpga_shadows[FR_RX_FORMAT];
445 }
446
447 // ----------------------------------------------------------------
448
449 unsigned int 
450 usrp_standard_rx::make_format(int width, int shift, bool want_q, bool bypass_halfband)
451 {
452   unsigned int format = 
453     (((width << bmFR_RX_FORMAT_WIDTH_SHIFT) & bmFR_RX_FORMAT_WIDTH_MASK)
454      | (shift << bmFR_RX_FORMAT_SHIFT_SHIFT) & bmFR_RX_FORMAT_SHIFT_MASK);
455
456   if (want_q)
457     format |= bmFR_RX_FORMAT_WANT_Q;
458   if (bypass_halfband)
459     format |= bmFR_RX_FORMAT_BYPASS_HB;
460
461   return format;
462 }
463
464 int
465 usrp_standard_rx::format_width(unsigned int format)
466 {
467   return (format & bmFR_RX_FORMAT_WIDTH_MASK) >> bmFR_RX_FORMAT_WIDTH_SHIFT;
468 }
469
470 int
471 usrp_standard_rx::format_shift(unsigned int format)
472 {
473   return (format & bmFR_RX_FORMAT_SHIFT_MASK) >> bmFR_RX_FORMAT_SHIFT_SHIFT;
474 }
475
476 bool
477 usrp_standard_rx::format_want_q(unsigned int format)
478 {
479   return (format & bmFR_RX_FORMAT_WANT_Q) != 0;
480 }
481
482 bool
483 usrp_standard_rx::format_bypass_halfband(unsigned int format)
484 {
485   return (format & bmFR_RX_FORMAT_BYPASS_HB) != 0;
486 }
487
488 //////////////////////////////////////////////////////////////////
489
490
491 // tx data is timed to CLKOUT1 (64 MHz)
492 // interpolate 4x
493 // fine modulator enabled
494
495
496 static unsigned char tx_regs_use_nco[] = {
497   REG_TX_IF,            (TX_IF_USE_CLKOUT1
498                          | TX_IF_I_FIRST
499                          | TX_IF_2S_COMP
500                          | TX_IF_INTERLEAVED),
501   REG_TX_DIGITAL,       (TX_DIGITAL_2_DATA_PATHS
502                          | TX_DIGITAL_INTERPOLATE_4X)
503 };
504
505
506 static int
507 real_tx_mux_value (int mux, int nchan)
508 {
509   if (mux != -1)
510     return mux;
511
512   switch (nchan){
513   case 1:
514     return 0x0098;
515   case 2:
516     return 0xba98;
517   default:
518     assert (0);
519   }
520 }
521
522 usrp_standard_tx::usrp_standard_tx (int which_board,
523                                     unsigned int interp_rate,
524                                     int nchan, int mux,
525                                     int fusb_block_size, int fusb_nblocks,
526                                     const std::string fpga_filename,
527                                     const std::string firmware_filename
528                                     )
529   : usrp_basic_tx (which_board, fusb_block_size, fusb_nblocks, fpga_filename, firmware_filename),
530     usrp_standard_common(this),
531     d_sw_mux (0x8), d_hw_mux (0x81)
532 {
533   if (!usrp_9862_write_many_all (d_udh, tx_regs_use_nco, sizeof (tx_regs_use_nco))){
534     fprintf (stderr, "usrp_standard_tx: failed to init AD9862 TX regs\n");
535     throw std::runtime_error ("usrp_standard_tx::ctor");
536   }
537   if (!set_nchannels (nchan)){
538     fprintf (stderr, "usrp_standard_tx: set_nchannels failed\n");
539     throw std::runtime_error ("usrp_standard_tx::ctor");
540   }
541   if (!set_interp_rate (interp_rate)){
542     fprintf (stderr, "usrp_standard_tx: set_interp_rate failed\n");
543     throw std::runtime_error ("usrp_standard_tx::ctor");
544   }
545   if (!set_mux (real_tx_mux_value (mux, nchan))){
546     fprintf (stderr, "usrp_standard_tx: set_mux failed\n");
547     throw std::runtime_error ("usrp_standard_tx::ctor");
548   }
549
550   for (int i = 0; i < MAX_CHAN; i++){
551     d_tx_modulator_shadow[i] = (TX_MODULATOR_DISABLE_NCO
552                                 | TX_MODULATOR_COARSE_MODULATION_NONE);
553     d_coarse_mod[i] = CM_OFF;
554     set_tx_freq (i, 0);
555   }
556 }
557
558 usrp_standard_tx::~usrp_standard_tx ()
559 {
560   // fprintf(stderr, "\nusrp_standard_tx: dtor\n");
561 }
562
563 bool
564 usrp_standard_tx::start ()
565 {
566   if (!usrp_basic_tx::start ())
567     return false;
568
569   // add our code here
570
571   return true;
572 }
573
574 bool
575 usrp_standard_tx::stop ()
576 {
577   bool ok = usrp_basic_tx::stop ();
578
579   // add our code here
580
581   return ok;
582 }
583
584 usrp_standard_tx *
585 usrp_standard_tx::make (int which_board,
586                         unsigned int interp_rate,
587                         int nchan, int mux,
588                         int fusb_block_size, int fusb_nblocks,
589                         const std::string fpga_filename,
590                         const std::string firmware_filename
591                         )
592 {
593   usrp_standard_tx *u = 0;
594   
595   try {
596     u = new usrp_standard_tx (which_board, interp_rate, nchan, mux,
597                               fusb_block_size, fusb_nblocks,
598                               fpga_filename, firmware_filename);
599     return u;
600   }
601   catch (...){
602     delete u;
603     return 0;
604   }
605
606   return u;
607 }
608
609 bool
610 usrp_standard_tx::set_interp_rate (unsigned int rate)
611 {
612   // fprintf (stderr, "usrp_standard_tx::set_interp_rate\n");
613
614   if ((rate & 0x3) || rate < 4 || rate > 512){
615     fprintf (stderr, "usrp_standard_tx::set_interp_rate: rate must be in [4, 512] and a multiple of 4.\n");
616     return false;
617   }
618
619   d_interp_rate = rate;
620   set_usb_data_rate ((dac_rate () / rate * nchannels ())
621                      * (2 * sizeof (short)));
622
623   // We're using the interp by 4 feature of the 9862 so that we can
624   // use its fine modulator.  Thus, we reduce the FPGA's interpolation rate
625   // by a factor of 4.
626
627   bool s = disable_tx ();
628   bool ok = _write_fpga_reg (FR_INTERP_RATE, d_interp_rate/4 - 1);
629   restore_tx (s);
630   return ok;
631 }
632
633 bool
634 usrp_standard_tx::set_nchannels (int nchan)
635 {
636   if (!(nchan == 1 || nchan == 2))
637     return false;
638
639   if (nchan > nducs())
640     return false;
641
642   d_nchan = nchan;
643   return write_hw_mux_reg ();
644 }
645
646 bool
647 usrp_standard_tx::set_mux (int mux)
648 {
649   d_sw_mux = mux;
650   d_hw_mux = mux << 4;
651   return write_hw_mux_reg ();
652 }
653
654 bool
655 usrp_standard_tx::write_hw_mux_reg ()
656 {
657   bool s = disable_tx ();
658   bool ok = _write_fpga_reg (FR_TX_MUX, d_hw_mux | d_nchan);
659   restore_tx (s);
660   return ok;
661 }
662
663 #ifdef USE_FPGA_TX_CORDIC
664
665 bool
666 usrp_standard_tx::set_tx_freq (int channel, double freq)
667 {
668   if (channel < 0 || channel >= MAX_CHAN)
669     return false;
670
671   // This assumes we're running the 4x on-chip interpolator.
672
673   unsigned int v =
674     compute_freq_control_word_fpga (dac_freq () / 4,
675                                     freq, &d_tx_freq[channel],
676                                     d_verbose);
677
678   return _write_fpga_reg (FR_TX_FREQ_0 + channel, v);
679 }
680
681
682 #else
683
684 bool
685 usrp_standard_tx::set_tx_freq (int channel, double freq)
686 {
687   if (channel < 0 || channel >= MAX_CHAN)
688     return false;
689
690   // split freq into fine and coarse components
691
692   coarse_mod_t  cm;
693   double        coarse;
694
695   assert (dac_freq () == 128000000);
696
697   if (freq < -44e6)             // too low
698     return false;
699   else if (freq < -24e6){       // [-44, -24)
700     cm = CM_NEG_FDAC_OVER_4;
701     coarse = -dac_freq () / 4;
702   }
703   else if (freq < -8e6){        // [-24, -8)
704     cm = CM_NEG_FDAC_OVER_8;
705     coarse = -dac_freq () / 8;
706   }
707   else if (freq < 8e6){         // [-8, 8)
708     cm = CM_OFF;
709     coarse = 0;
710   }
711   else if (freq < 24e6){        // [8, 24)
712     cm = CM_POS_FDAC_OVER_8;
713     coarse = dac_freq () / 8;
714   }
715   else if (freq <= 44e6){       // [24, 44]
716     cm = CM_POS_FDAC_OVER_4;
717     coarse = dac_freq () / 4;
718   }
719   else                          // too high
720     return false;
721
722
723   set_coarse_modulator (channel, cm);   // set bits in d_tx_modulator_shadow
724
725   double fine = freq - coarse;
726
727
728   // Compute fine tuning word...
729   // This assumes we're running the 4x on-chip interpolator.
730   // (This is required to use the fine modulator.)
731
732   unsigned int v =
733     compute_freq_control_word_9862 (dac_freq () / 4,
734                                     fine, &d_tx_freq[channel], d_verbose);
735
736   d_tx_freq[channel] += coarse;         // adjust actual
737   
738   unsigned char high, mid, low;
739
740   high = (v >> 16) & 0xff;
741   mid =  (v >>  8) & 0xff;
742   low =  (v >>  0) & 0xff;
743
744   bool ok = true;
745
746   // write the fine tuning word
747   ok &= _write_9862 (channel, REG_TX_NCO_FTW_23_16, high);
748   ok &= _write_9862 (channel, REG_TX_NCO_FTW_15_8,  mid);
749   ok &= _write_9862 (channel, REG_TX_NCO_FTW_7_0,   low);
750
751
752   d_tx_modulator_shadow[channel] |= TX_MODULATOR_ENABLE_NCO;
753
754   if (fine < 0)
755     d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_FINE_TUNE;
756   else
757     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_NEG_FINE_TUNE;
758
759   ok &=_write_9862 (channel, REG_TX_MODULATOR, d_tx_modulator_shadow[channel]);
760
761   return ok;
762 }
763 #endif
764
765 bool
766 usrp_standard_tx::set_coarse_modulator (int channel, coarse_mod_t cm)
767 {
768   if (channel < 0 || channel >= MAX_CHAN)
769     return false;
770
771   switch (cm){
772   case CM_NEG_FDAC_OVER_4:
773     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
774     d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4;
775     d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE;
776     break;
777
778   case CM_NEG_FDAC_OVER_8:
779     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
780     d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8;
781     d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE;
782     break;
783
784   case CM_OFF:
785     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
786     break;
787
788   case CM_POS_FDAC_OVER_8:
789     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
790     d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8;
791     break;
792
793   case CM_POS_FDAC_OVER_4:
794     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
795     d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4;
796     break;
797
798   default:
799     return false;
800   }
801
802   d_coarse_mod[channel] = cm;
803   return true;
804 }
805
806 unsigned int
807 usrp_standard_tx::interp_rate () const { return d_interp_rate; }
808
809 int
810 usrp_standard_tx::nchannels () const { return d_nchan; }
811
812 int
813 usrp_standard_tx::mux () const { return d_sw_mux; }
814
815 double
816 usrp_standard_tx::tx_freq (int channel) const
817 {
818   if (channel < 0 || channel >= MAX_CHAN)
819     return 0;
820
821   return d_tx_freq[channel];
822 }
823
824 usrp_standard_tx::coarse_mod_t
825 usrp_standard_tx::coarse_modulator (int channel) const
826 {
827   if (channel < 0 || channel >= MAX_CHAN)
828     return CM_OFF;
829
830   return d_coarse_mod[channel];
831 }