Merge branch 'dfsg-orig'
[debian/gnuradio] / usrp / host / lib / usrp_standard.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 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_standard.h>
28
29 #include "usrp/usrp_prims.h"
30 #include "fpga_regs_common.h"
31 #include "fpga_regs_standard.h"
32 #include <stdexcept>
33 #include <assert.h>
34 #include <math.h>
35 #include <ad9862.h>
36 #include <cstdio>
37
38
39 static const int OLD_CAPS_VAL = 0xaa55ff77;
40 static const int DEFAULT_CAPS_VAL = ((2 << bmFR_RB_CAPS_NDUC_SHIFT)
41                                      | (2 << bmFR_RB_CAPS_NDDC_SHIFT)
42                                      | bmFR_RB_CAPS_RX_HAS_HALFBAND);
43
44 // #define USE_FPGA_TX_CORDIC
45
46
47 using namespace ad9862;
48
49 #define NELEM(x) (sizeof (x) / sizeof (x[0]))
50
51
52 void
53 usrp_standard_common::calc_dxc_freq(double target_freq, double baseband_freq, double fs,
54                                     double *dxc_freq, bool *inverted)
55 {
56   /*
57     Calculate the frequency to use for setting the digital up or down converter.
58     
59     @param target_freq: desired RF frequency (Hz)
60     @param baseband_freq: the RF frequency that corresponds to DC in the IF.
61     @param fs: converter sample rate
62     
63     @returns: 2-tuple (ddc_freq, inverted) where ddc_freq is the value
64       for the ddc and inverted is True if we're operating in an inverted
65       Nyquist zone.
66   */
67
68 #if 0
69     printf("calc_dxc_freq:\n");
70     printf("  target   = %f\n", target_freq);
71     printf("  baseband = %f\n", baseband_freq);
72     printf("  fs       = %f\n", fs);
73 #endif
74
75   double delta = target_freq - baseband_freq;
76     
77   if(delta >= 0) {
78     while(delta > fs) {
79       delta -= fs;
80     }
81     if(delta <= fs/2) {         // non-inverted region
82       *dxc_freq = -delta;       
83       *inverted = false;
84     }
85     else {                      // inverted region
86       *dxc_freq = delta - fs;
87       *inverted = true;
88     }
89   }
90   else {
91     while(delta < -fs) {
92       delta += fs;
93     }
94     if(delta >= -fs/2) {
95       *dxc_freq = -delta;       // non-inverted region
96       *inverted = false;
97     }
98     else {                      // inverted region
99       *dxc_freq = delta + fs;
100       *inverted = true;
101     }
102   }
103
104 #if 0
105     printf("  dxc_freq  = %f\n", *dxc_freq);
106     printf("  inverted  = %s\n", *inverted ? "true" : "false");
107 #endif
108 }
109
110
111 /* 
112  * Real lambda expressions would be _so_ much easier...
113  */
114 class dxc_control {
115 public:
116   virtual bool is_tx() = 0;
117   virtual bool set_dxc_freq(double dxc_freq) = 0;
118   virtual double dxc_freq() = 0;
119 };
120
121 class ddc_control : public dxc_control {
122   usrp_standard_rx     *d_u;
123   int                   d_chan;
124
125 public:
126   ddc_control(usrp_standard_rx *u, int chan)
127     : d_u(u), d_chan(chan) {}
128   
129   bool is_tx(){ return false; }
130   bool set_dxc_freq(double dxc_freq){ return d_u->set_rx_freq(d_chan, dxc_freq); }
131   double dxc_freq(){ return d_u->rx_freq(d_chan); }
132 };
133
134 class duc_control : public dxc_control {
135   usrp_standard_tx     *d_u;
136   int                   d_chan;
137
138 public:
139   duc_control(usrp_standard_tx *u, int chan)
140     : d_u(u), d_chan(chan) {}
141   
142   bool is_tx(){ return true; }
143   bool set_dxc_freq(double dxc_freq){ return d_u->set_tx_freq(d_chan, dxc_freq); }
144   double dxc_freq() { return d_u->tx_freq(d_chan); }
145 };
146
147
148 /*!
149  * \brief Tune such that target_frequency ends up at DC in the complex baseband
150  *
151  * \param db            the daughterboard to use
152  * \param target_freq   the center frequency we want at baseband (DC)
153  * \param fs            the sample rate
154  * \param dxc           DDC or DUC access and control object
155  * \param[out] result   details of what we did
156  *
157  * \returns true iff operation was successful
158  *
159  * Tuning is a two step process.  First we ask the front-end to
160  * tune as close to the desired frequency as it can.  Then we use
161  * the result of that operation and our target_frequency to
162  * determine the value for the digital down converter.
163  */
164 static bool
165 tune_a_helper(db_base_sptr db, double target_freq, double fs,
166               dxc_control &dxc, usrp_tune_result *result)
167 {
168   bool inverted = false;
169   double dxc_freq;
170   double actual_dxc_freq;
171
172   // Ask the d'board to tune as closely as it can to target_freq
173 #if 0
174   bool ok = db->set_freq(target_freq, &result->baseband_freq);
175 #else
176   bool ok;
177   {
178     freq_result_t fr = db->set_freq(target_freq);
179     ok = fr.ok;
180     result->baseband_freq = fr.baseband_freq;
181   }
182 #endif
183
184   // Calculate the DDC setting that will downconvert the baseband from the
185   // daughterboard to our target frequency.
186   usrp_standard_common::calc_dxc_freq(target_freq, result->baseband_freq, fs,
187                                       &dxc_freq, &inverted);
188
189   // If the spectrum is inverted, and the daughterboard doesn't do
190   // quadrature downconversion, we can fix the inversion by flipping the
191   // sign of the dxc_freq...  (This only happens using the basic_rx board)
192   
193   if(db->spectrum_inverted())
194     inverted = !inverted;
195   
196   if(inverted && !db->is_quadrature()){
197     dxc_freq = -dxc_freq;
198     inverted = !inverted;
199   }
200   
201   if (dxc.is_tx() && !db->i_and_q_swapped())            // down conversion versus up conversion
202     dxc_freq = -dxc_freq;
203
204   ok &= dxc.set_dxc_freq(dxc_freq);
205   actual_dxc_freq = dxc.dxc_freq();
206   
207   result->dxc_freq = dxc_freq;
208   result->residual_freq = dxc_freq - actual_dxc_freq;
209   result->inverted = inverted;
210   return ok;
211 }
212
213
214 static unsigned int
215 compute_freq_control_word_fpga (double master_freq, double target_freq,
216                                 double *actual_freq, bool verbose)
217 {
218   static const int NBITS = 14;
219   
220   int   v = (int) rint (target_freq / master_freq * pow (2.0, 32.0));
221
222   if (0)
223     v = (v >> (32 - NBITS)) << (32 - NBITS);    // keep only top NBITS
224
225   *actual_freq = v * master_freq / pow (2.0, 32.0);
226
227   if (verbose)
228     fprintf (stderr,
229              "compute_freq_control_word_fpga: target = %g  actual = %g  delta = %g\n",
230              target_freq, *actual_freq, *actual_freq - target_freq);
231
232   return (unsigned int) v;
233 }
234
235 // The 9862 uses an unsigned 24-bit frequency tuning word and 
236 // a separate register to control the sign.
237
238 static unsigned int
239 compute_freq_control_word_9862 (double master_freq, double target_freq,
240                                 double *actual_freq, bool verbose)
241 {
242   double sign = 1.0;
243
244   if (target_freq < 0)
245     sign = -1.0;
246
247   int   v = (int) rint (fabs (target_freq) / master_freq * pow (2.0, 24.0));
248   *actual_freq = v * master_freq / pow (2.0, 24.0) * sign;
249
250   if (verbose)
251     fprintf (stderr,
252      "compute_freq_control_word_9862: target = %g  actual = %g  delta = %g  v = %8d\n",
253      target_freq, *actual_freq, *actual_freq - target_freq, v);
254
255   return (unsigned int) v;
256 }
257
258 // ----------------------------------------------------------------
259
260 usrp_standard_common::usrp_standard_common(usrp_basic *parent)
261 {
262   // read new FPGA capability register
263   if (!parent->_read_fpga_reg(FR_RB_CAPS, &d_fpga_caps)){
264     fprintf (stderr, "usrp_standard_common: failed to read FPGA cap register.\n");
265     throw std::runtime_error ("usrp_standard_common::ctor");
266   }
267   // If we don't have the cap register, set the value to what it would
268   // have had if we did have one ;)
269   if (d_fpga_caps == OLD_CAPS_VAL)
270     d_fpga_caps = DEFAULT_CAPS_VAL;
271
272   if (0){
273     fprintf(stdout, "has_rx_halfband = %d\n", has_rx_halfband());
274     fprintf(stdout, "nddcs           = %d\n", nddcs());
275     fprintf(stdout, "has_tx_halfband = %d\n", has_tx_halfband());
276     fprintf(stdout, "nducs           = %d\n", nducs());
277   }
278 }
279
280 bool
281 usrp_standard_common::has_rx_halfband() const
282 {
283   return (d_fpga_caps & bmFR_RB_CAPS_RX_HAS_HALFBAND) ? true : false;
284 }
285
286 int
287 usrp_standard_common::nddcs() const
288 {
289   return (d_fpga_caps & bmFR_RB_CAPS_NDDC_MASK) >> bmFR_RB_CAPS_NDDC_SHIFT;
290 }
291
292 bool
293 usrp_standard_common::has_tx_halfband() const
294 {
295   return (d_fpga_caps & bmFR_RB_CAPS_TX_HAS_HALFBAND) ? true : false;
296 }
297
298 int
299 usrp_standard_common::nducs() const
300 {
301   return (d_fpga_caps & bmFR_RB_CAPS_NDUC_MASK) >> bmFR_RB_CAPS_NDUC_SHIFT;
302 }
303
304 // ----------------------------------------------------------------
305
306 static int 
307 real_rx_mux_value (int mux, int nchan)
308 {
309   if (mux != -1)
310     return mux;
311
312   return 0x32103210;
313 }
314
315 usrp_standard_rx::usrp_standard_rx (int which_board,
316                                     unsigned int decim_rate,
317                                     int nchan, int mux, int mode,
318                                     int fusb_block_size, int fusb_nblocks,
319                                     const std::string fpga_filename,
320                                     const std::string firmware_filename
321                                     )
322   : usrp_basic_rx (which_board, fusb_block_size, fusb_nblocks,
323                    fpga_filename, firmware_filename),
324     usrp_standard_common(this),
325     d_nchan (1), d_sw_mux (0x0), d_hw_mux (0x0)
326 {
327   if (!set_format(make_format())){
328     fprintf (stderr, "usrp_standard_rx: set_format failed\n");
329     throw std::runtime_error ("usrp_standard_rx::ctor");
330   }
331   if (!set_nchannels (nchan)){
332     fprintf (stderr, "usrp_standard_rx: set_nchannels failed\n");
333     throw std::runtime_error ("usrp_standard_rx::ctor");
334   }
335   if (!set_decim_rate (decim_rate)){
336     fprintf (stderr, "usrp_standard_rx: set_decim_rate failed\n");
337     throw std::runtime_error ("usrp_standard_rx::ctor");
338   }
339   if (!set_mux (real_rx_mux_value (mux, nchan))){
340     fprintf (stderr, "usrp_standard_rx: set_mux failed\n");
341     throw std::runtime_error ("usrp_standard_rx::ctor");
342   }
343   if (!set_fpga_mode (mode)){
344     fprintf (stderr, "usrp_standard_rx: set_fpga_mode failed\n");
345     throw std::runtime_error ("usrp_standard_rx::ctor");
346   }
347
348   for (int i = 0; i < MAX_CHAN; i++){
349     set_rx_freq(i, 0);
350     set_ddc_phase(i, 0);
351   }
352 }
353
354 usrp_standard_rx::~usrp_standard_rx ()
355 {
356   // fprintf(stderr, "\nusrp_standard_rx: dtor\n");
357 }
358
359 bool
360 usrp_standard_rx::start ()
361 {
362   if (!usrp_basic_rx::start ())
363     return false;
364
365   // add our code here
366
367   return true;
368 }
369
370 bool
371 usrp_standard_rx::stop ()
372 {
373   bool ok = usrp_basic_rx::stop ();
374
375   // add our code here
376
377   return ok;
378 }
379
380 usrp_standard_rx_sptr
381 usrp_standard_rx::make (int which_board,
382                         unsigned int decim_rate,
383                         int nchan, int mux, int mode,
384                         int fusb_block_size, int fusb_nblocks,
385                         const std::string fpga_filename,
386                         const std::string firmware_filename
387                         )
388 {
389   try {
390     usrp_standard_rx_sptr u = 
391       usrp_standard_rx_sptr(new usrp_standard_rx(which_board, decim_rate,
392                                                  nchan, mux, mode,
393                                                  fusb_block_size, fusb_nblocks,
394                                                  fpga_filename, firmware_filename));
395     u->init_db(u);
396     return u;
397   }
398   catch (...){
399     return usrp_standard_rx_sptr();
400   }
401 }
402
403 bool
404 usrp_standard_rx::set_decim_rate(unsigned int rate)
405 {
406   if (has_rx_halfband()){
407     if ((rate & 0x1) || rate < 4 || rate > 256){
408       fprintf (stderr, "usrp_standard_rx::set_decim_rate: rate must be EVEN and in [4, 256]\n");
409       return false;
410     }
411   }
412   else {
413     if (rate < 4 || rate > 128){
414       fprintf (stderr, "usrp_standard_rx::set_decim_rate: rate must be in [4, 128]\n");
415       return false;
416     }
417   }
418
419   d_decim_rate = rate;
420   set_usb_data_rate ((adc_rate () / rate * nchannels ())
421                      * (2 * sizeof (short)));
422
423   bool s = disable_rx ();
424   int v = has_rx_halfband() ? d_decim_rate/2 - 1 : d_decim_rate - 1;
425   bool ok = _write_fpga_reg (FR_DECIM_RATE, v);
426   restore_rx (s);
427   return ok;
428 }
429
430 bool usrp_standard_rx::set_nchannels (int nchan)
431 {
432   if (!(nchan == 1 || nchan == 2 || nchan == 4))
433     return false;
434
435   if (nchan > nddcs())
436     return false;
437
438   d_nchan = nchan;
439
440   return write_hw_mux_reg ();
441 }
442
443
444 // map software mux value to hw mux value
445 //
446 // Software mux value:
447 //
448 //    3                   2                   1                       
449 //  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
450 // +-------+-------+-------+-------+-------+-------+-------+-------+
451 // |   Q3  |   I3  |   Q2  |   I2  |   Q1  |   I1  |   Q0  |   I0  |
452 // +-------+-------+-------+-------+-------+-------+-------+-------+
453 //
454 // Each 4-bit I field is either 0,1,2,3
455 // Each 4-bit Q field is either 0,1,2,3 or 0xf (input is const zero)
456 // All Q's must be 0xf or none of them may be 0xf
457 //
458 //
459 // Hardware mux value:
460 //
461 //    3                   2                   1                       
462 //  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
463 // +-----------------------+-------+-------+-------+-------+-+-----+
464 // |      must be zero     | Q3| I3| Q2| I2| Q1| I1| Q0| I0|Z| NCH |
465 // +-----------------------+-------+-------+-------+-------+-+-----+
466
467
468 static bool
469 map_sw_mux_to_hw_mux (int sw_mux, int *hw_mux_ptr)
470 {
471   // confirm that all I's are either 0,1,2,3 
472
473   for (int i = 0; i < 8; i += 2){
474     int t = (sw_mux >> (4 * i)) & 0xf;
475     if (!(0 <= t && t <= 3))
476       return false;
477   }
478
479   // confirm that all Q's are either 0,1,2,3 or 0xf
480
481   for (int i = 1; i < 8; i += 2){
482     int t = (sw_mux >> (4 * i)) & 0xf;
483     if (!(t == 0xf || (0 <= t && t <= 3)))
484       return false;
485   }
486
487   // confirm that all Q inputs are 0xf (const zero input),
488   // or none of them are 0xf
489
490   int q_and = 1;
491   int q_or =  0;
492
493   for (int i = 0; i < 4; i++){
494     int qx_is_0xf = ((sw_mux >> (8 * i + 4)) & 0xf) == 0xf;
495     q_and &= qx_is_0xf;
496     q_or  |= qx_is_0xf;
497   }
498
499   if (q_and || !q_or){          // OK
500     int hw_mux_value = 0;
501
502     for (int i = 0; i < 8; i++){
503       int t = (sw_mux >> (4 * i)) & 0x3;
504       hw_mux_value |= t << (2 * i + 4);
505     }
506
507     if (q_and)
508       hw_mux_value |= 0x8;      // all Q's zero
509
510     *hw_mux_ptr = hw_mux_value;
511     return true;
512   }
513   else
514     return false;
515 }
516
517 bool
518 usrp_standard_rx::set_mux (int mux)
519 {
520   if (!map_sw_mux_to_hw_mux (mux, &d_hw_mux))
521     return false;
522
523   // fprintf (stderr, "sw_mux = 0x%08x  hw_mux = 0x%08x\n", mux, d_hw_mux);
524
525   d_sw_mux = mux;
526   return write_hw_mux_reg ();
527 }
528
529 bool
530 usrp_standard_rx::write_hw_mux_reg ()
531 {
532   bool s = disable_rx ();
533   bool ok = _write_fpga_reg (FR_RX_MUX, d_hw_mux | d_nchan);
534   restore_rx (s);
535   return ok;
536 }
537
538 int
539 usrp_standard_rx::determine_rx_mux_value(const usrp_subdev_spec &ss)
540 {
541   /*
542     Determine appropriate Rx mux value as a function of the subdevice choosen and the
543     characteristics of the respective daughterboard.
544     
545     @param u:           instance of USRP source
546     @param subdev_spec: return value from subdev option parser.  
547     @type  subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0 or 1
548     @returns:           the Rx mux value
549   
550     Figure out which A/D's to connect to the DDC.
551     
552     Each daughterboard consists of 1 or 2 subdevices.  (At this time,
553     all but the Basic Rx have a single subdevice.  The Basic Rx
554     has two independent channels, treated as separate subdevices).
555     subdevice 0 of a daughterboard may use 1 or 2 A/D's.  We determine this
556     by checking the is_quadrature() method.  If subdevice 0 uses only a single
557     A/D, it's possible that the daughterboard has a second subdevice, subdevice 1,
558     and it uses the second A/D.
559     
560     If the card uses only a single A/D, we wire a zero into the DDC Q input.
561     
562     (side, 0) says connect only the A/D's used by subdevice 0 to the DDC.
563     (side, 1) says connect only the A/D's used by subdevice 1 to the DDC.
564   */
565
566   struct truth_table_element
567   {
568     int          d_side;
569     int          d_uses;
570     bool         d_swap_iq;
571     unsigned int d_mux_val;
572
573     truth_table_element(int side, unsigned int uses, bool swap_iq, unsigned int mux_val=0)
574       : d_side(side), d_uses(uses), d_swap_iq(swap_iq), d_mux_val(mux_val){}
575       
576     bool operator==(const truth_table_element &in)
577     {
578       return (d_side == in.d_side && d_uses == in.d_uses && d_swap_iq == in.d_swap_iq);
579     }
580
581     unsigned int mux_val() { return d_mux_val; }
582   };
583
584
585   if (!is_valid(ss))
586     throw std::invalid_argument("subdev_spec");
587
588
589   // This is a tuple of length 1 or 2 containing the subdevice
590   // classes for the selected side.
591   std::vector<db_base_sptr> db = this->db(ss.side);
592   
593   unsigned int uses;
594
595   // compute bitmasks of used A/D's
596   
597   if(db[ss.subdev]->is_quadrature())
598     uses = 0x3;               // uses A/D 0 and 1
599   else if (ss.subdev == 0)
600     uses = 0x1;               // uses A/D 0 only
601   else if(ss.subdev == 1)
602     uses = 0x2;               // uses A/D 1 only
603   else
604     uses = 0x0;               // uses no A/D (doesn't exist)
605   
606   if(uses == 0){
607     throw std::runtime_error("Determine RX Mux Error");
608   }
609   
610   bool swap_iq = db[ss.subdev]->i_and_q_swapped();
611   
612   truth_table_element truth_table[8] = {
613     // (side, uses, swap_iq) : mux_val
614     truth_table_element(0, 0x1, false, 0xf0f0f0f0),
615     truth_table_element(0, 0x2, false, 0xf0f0f0f1),
616     truth_table_element(0, 0x3, false, 0x00000010),
617     truth_table_element(0, 0x3, true,  0x00000001),
618     truth_table_element(1, 0x1, false, 0xf0f0f0f2),
619     truth_table_element(1, 0x2, false, 0xf0f0f0f3),
620     truth_table_element(1, 0x3, false, 0x00000032),
621     truth_table_element(1, 0x3, true,  0x00000023)
622   };
623   size_t nelements = sizeof(truth_table)/sizeof(truth_table[0]);
624   
625   truth_table_element target(ss.side, uses, swap_iq, 0);
626   
627   size_t i;
628   for(i = 0; i < nelements; i++){
629     if (truth_table[i] == target)
630       return truth_table[i].mux_val();
631   }
632   throw std::runtime_error("internal error");
633 }
634
635 int
636 usrp_standard_rx::determine_rx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b)
637 {
638   std::vector<db_base_sptr> db_a = this->db(ss_a.side);
639   std::vector<db_base_sptr> db_b = this->db(ss_b.side);
640   if (db_a[ss_a.subdev]->is_quadrature() != db_b[ss_b.subdev]->is_quadrature()){
641     throw std::runtime_error("Cannot compute dual mux when mixing quadrature and non-quadrature subdevices");
642   }
643   int mux_a = determine_rx_mux_value(ss_a);
644   int mux_b = determine_rx_mux_value(ss_b);
645   //move the lower byte of the mux b into the second byte of the mux a
646   return ((mux_b & 0xff) << 8) | (mux_a & 0xffff00ff);
647 }
648
649 bool
650 usrp_standard_rx::set_rx_freq (int channel, double freq)
651 {
652   if (channel < 0 || channel > MAX_CHAN)
653     return false;
654
655   unsigned int v =
656     compute_freq_control_word_fpga (adc_rate(),
657                                     freq, &d_rx_freq[channel],
658                                     d_verbose);
659
660   return _write_fpga_reg (FR_RX_FREQ_0 + channel, v);
661 }
662
663 unsigned int
664 usrp_standard_rx::decim_rate () const { return d_decim_rate; }
665
666 int
667 usrp_standard_rx::nchannels () const { return d_nchan; }
668
669 int
670 usrp_standard_rx::mux () const { return d_sw_mux; }
671
672 double 
673 usrp_standard_rx::rx_freq (int channel) const
674 {
675   if (channel < 0 || channel >= MAX_CHAN)
676     return 0;
677
678   return d_rx_freq[channel];
679 }
680
681 bool
682 usrp_standard_rx::set_fpga_mode (int mode)
683 {
684   return _write_fpga_reg (FR_MODE, mode);
685 }
686
687 bool
688 usrp_standard_rx::set_ddc_phase(int channel, int phase)
689 {
690   if (channel < 0 || channel >= MAX_CHAN)
691     return false;
692
693   return _write_fpga_reg(FR_RX_PHASE_0 + channel, phase);
694 }
695
696
697 // To avoid quiet failures, check for things that our code cares about.
698
699 static bool
700 rx_format_is_valid(unsigned int format)
701 {
702   int width =  usrp_standard_rx::format_width(format);
703   int want_q = usrp_standard_rx::format_want_q(format);
704
705   if (!(width == 8 || width == 16))     // FIXME add other widths when valid
706     return false;
707
708   if (!want_q)          // FIXME remove check when the rest of the code can handle I only
709     return false;
710
711   return true;
712 }
713
714 bool
715 usrp_standard_rx::set_format(unsigned int format)
716 {
717   if (!rx_format_is_valid(format))
718     return false;
719
720   return _write_fpga_reg(FR_RX_FORMAT, format);
721 }
722
723 unsigned int
724 usrp_standard_rx::format() const
725 {
726   return d_fpga_shadows[FR_RX_FORMAT];
727 }
728
729 // ----------------------------------------------------------------
730
731 unsigned int 
732 usrp_standard_rx::make_format(int width, int shift, bool want_q, bool bypass_halfband)
733 {
734   unsigned int format = 
735     (((width << bmFR_RX_FORMAT_WIDTH_SHIFT) & bmFR_RX_FORMAT_WIDTH_MASK)
736      | ((shift << bmFR_RX_FORMAT_SHIFT_SHIFT) & bmFR_RX_FORMAT_SHIFT_MASK));
737
738   if (want_q)
739     format |= bmFR_RX_FORMAT_WANT_Q;
740   if (bypass_halfband)
741     format |= bmFR_RX_FORMAT_BYPASS_HB;
742
743   return format;
744 }
745
746 int
747 usrp_standard_rx::format_width(unsigned int format)
748 {
749   return (format & bmFR_RX_FORMAT_WIDTH_MASK) >> bmFR_RX_FORMAT_WIDTH_SHIFT;
750 }
751
752 int
753 usrp_standard_rx::format_shift(unsigned int format)
754 {
755   return (format & bmFR_RX_FORMAT_SHIFT_MASK) >> bmFR_RX_FORMAT_SHIFT_SHIFT;
756 }
757
758 bool
759 usrp_standard_rx::format_want_q(unsigned int format)
760 {
761   return (format & bmFR_RX_FORMAT_WANT_Q) != 0;
762 }
763
764 bool
765 usrp_standard_rx::format_bypass_halfband(unsigned int format)
766 {
767   return (format & bmFR_RX_FORMAT_BYPASS_HB) != 0;
768 }
769
770 bool
771 usrp_standard_rx::tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result)
772 {
773   ddc_control dxc(this, chan);
774   return tune_a_helper(db, target_freq, converter_rate(), dxc, result);
775 }
776
777
778 //////////////////////////////////////////////////////////////////
779
780
781 // tx data is timed to CLKOUT1 (64 MHz)
782 // interpolate 4x
783 // fine modulator enabled
784
785
786 static unsigned char tx_regs_use_nco[] = {
787   REG_TX_IF,            (TX_IF_USE_CLKOUT1
788                          | TX_IF_I_FIRST
789                          | TX_IF_2S_COMP
790                          | TX_IF_INTERLEAVED),
791   REG_TX_DIGITAL,       (TX_DIGITAL_2_DATA_PATHS
792                          | TX_DIGITAL_INTERPOLATE_4X)
793 };
794
795
796 static int
797 real_tx_mux_value (int mux, int nchan)
798 {
799   if (mux != -1)
800     return mux;
801
802   switch (nchan){
803   case 1:
804     return 0x0098;
805   case 2:
806     return 0xba98;
807   default:
808     assert (0);
809   }
810 }
811
812 usrp_standard_tx::usrp_standard_tx (int which_board,
813                                     unsigned int interp_rate,
814                                     int nchan, int mux,
815                                     int fusb_block_size, int fusb_nblocks,
816                                     const std::string fpga_filename,
817                                     const std::string firmware_filename
818                                     )
819   : usrp_basic_tx (which_board, fusb_block_size, fusb_nblocks, fpga_filename, firmware_filename),
820     usrp_standard_common(this),
821     d_sw_mux (0x8), d_hw_mux (0x81)
822 {
823   if (!usrp_9862_write_many_all (d_udh, tx_regs_use_nco, sizeof (tx_regs_use_nco))){
824     fprintf (stderr, "usrp_standard_tx: failed to init AD9862 TX regs\n");
825     throw std::runtime_error ("usrp_standard_tx::ctor");
826   }
827   if (!set_nchannels (nchan)){
828     fprintf (stderr, "usrp_standard_tx: set_nchannels failed\n");
829     throw std::runtime_error ("usrp_standard_tx::ctor");
830   }
831   if (!set_interp_rate (interp_rate)){
832     fprintf (stderr, "usrp_standard_tx: set_interp_rate failed\n");
833     throw std::runtime_error ("usrp_standard_tx::ctor");
834   }
835   if (!set_mux (real_tx_mux_value (mux, nchan))){
836     fprintf (stderr, "usrp_standard_tx: set_mux failed\n");
837     throw std::runtime_error ("usrp_standard_tx::ctor");
838   }
839
840   for (int i = 0; i < MAX_CHAN; i++){
841     d_tx_modulator_shadow[i] = (TX_MODULATOR_DISABLE_NCO
842                                 | TX_MODULATOR_COARSE_MODULATION_NONE);
843     d_coarse_mod[i] = CM_OFF;
844     set_tx_freq (i, 0);
845   }
846 }
847
848 usrp_standard_tx::~usrp_standard_tx ()
849 {
850   // fprintf(stderr, "\nusrp_standard_tx: dtor\n");
851 }
852
853 bool
854 usrp_standard_tx::start ()
855 {
856   if (!usrp_basic_tx::start ())
857     return false;
858
859   // add our code here
860
861   return true;
862 }
863
864 bool
865 usrp_standard_tx::stop ()
866 {
867   bool ok = usrp_basic_tx::stop ();
868
869   // add our code here
870
871   return ok;
872 }
873
874 usrp_standard_tx_sptr
875 usrp_standard_tx::make (int which_board,
876                         unsigned int interp_rate,
877                         int nchan, int mux,
878                         int fusb_block_size, int fusb_nblocks,
879                         const std::string fpga_filename,
880                         const std::string firmware_filename
881                         )
882 {
883   try {
884     usrp_standard_tx_sptr u  = 
885       usrp_standard_tx_sptr(new usrp_standard_tx(which_board, interp_rate, nchan, mux,
886                                                  fusb_block_size, fusb_nblocks,
887                                                  fpga_filename, firmware_filename));
888     u->init_db(u);
889     return u;
890   }
891   catch (...){
892     return usrp_standard_tx_sptr();
893   }
894 }
895
896 bool
897 usrp_standard_tx::set_interp_rate (unsigned int rate)
898 {
899   // fprintf (stderr, "usrp_standard_tx::set_interp_rate\n");
900
901   if ((rate & 0x3) || rate < 4 || rate > 512){
902     fprintf (stderr, "usrp_standard_tx::set_interp_rate: rate must be in [4, 512] and a multiple of 4.\n");
903     return false;
904   }
905
906   d_interp_rate = rate;
907   set_usb_data_rate ((dac_rate () / rate * nchannels ())
908                      * (2 * sizeof (short)));
909
910   // We're using the interp by 4 feature of the 9862 so that we can
911   // use its fine modulator.  Thus, we reduce the FPGA's interpolation rate
912   // by a factor of 4.
913
914   bool s = disable_tx ();
915   bool ok = _write_fpga_reg (FR_INTERP_RATE, d_interp_rate/4 - 1);
916   restore_tx (s);
917   return ok;
918 }
919
920 bool
921 usrp_standard_tx::set_nchannels (int nchan)
922 {
923   if (!(nchan == 1 || nchan == 2))
924     return false;
925
926   if (nchan > nducs())
927     return false;
928
929   d_nchan = nchan;
930   return write_hw_mux_reg ();
931 }
932
933 bool
934 usrp_standard_tx::set_mux (int mux)
935 {
936   d_sw_mux = mux;
937   d_hw_mux = mux << 4;
938   return write_hw_mux_reg ();
939 }
940
941 bool
942 usrp_standard_tx::write_hw_mux_reg ()
943 {
944   bool s = disable_tx ();
945   bool ok = _write_fpga_reg (FR_TX_MUX, d_hw_mux | d_nchan);
946   restore_tx (s);
947   return ok;
948 }
949
950 int
951 usrp_standard_tx::determine_tx_mux_value(const usrp_subdev_spec &ss)
952 {
953   /*
954     Determine appropriate Tx mux value as a function of the subdevice choosen.
955
956     @param u:           instance of USRP source
957     @param subdev_spec: return value from subdev option parser.  
958     @type  subdev_spec: (side, subdev), where side is 0 or 1 and subdev is 0
959     @returns:           the Rx mux value
960   
961     This is simpler than the rx case.  Either you want to talk
962     to side A or side B.  If you want to talk to both sides at once,
963     determine the value manually.
964   */
965
966   if (!is_valid(ss))
967     throw std::invalid_argument("subdev_spec");
968
969   std::vector<db_base_sptr> db = this->db(ss.side);
970   
971   if(db[ss.subdev]->i_and_q_swapped()) {
972     unsigned int mask[2] = {0x0089, 0x8900};
973     return mask[ss.side];
974   }
975   else {
976     unsigned int mask[2] = {0x0098, 0x9800};
977     return mask[ss.side];
978   }
979 }
980
981 int
982 usrp_standard_tx::determine_tx_mux_value(const usrp_subdev_spec &ss_a, const usrp_subdev_spec &ss_b)
983 {
984   if (ss_a.side == ss_b.side && ss_a.subdev == ss_b.subdev){
985     throw std::runtime_error("Cannot compute dual mux, repeated subdevice");
986   }
987   int mux_a = determine_tx_mux_value(ss_a);
988   //Get the mux b:
989   //    DAC0 becomes DAC2
990   //    DAC1 becomes DAC3
991   unsigned int mask[2] = {0x0022, 0x2200};
992   int mux_b = determine_tx_mux_value(ss_b) + mask[ss_b.side];
993   return mux_b | mux_a;
994 }
995
996 #ifdef USE_FPGA_TX_CORDIC
997
998 bool
999 usrp_standard_tx::set_tx_freq (int channel, double freq)
1000 {
1001   if (channel < 0 || channel >= MAX_CHAN)
1002     return false;
1003
1004   // This assumes we're running the 4x on-chip interpolator.
1005
1006   unsigned int v =
1007     compute_freq_control_word_fpga (dac_rate () / 4,
1008                                     freq, &d_tx_freq[channel],
1009                                     d_verbose);
1010
1011   return _write_fpga_reg (FR_TX_FREQ_0 + channel, v);
1012 }
1013
1014
1015 #else
1016
1017 bool
1018 usrp_standard_tx::set_tx_freq (int channel, double freq)
1019 {
1020   if (channel < 0 || channel >= MAX_CHAN)
1021     return false;
1022
1023   // split freq into fine and coarse components
1024
1025   coarse_mod_t  cm;
1026   double        coarse;
1027
1028   double coarse_freq_1 = dac_rate () / 8; // First coarse frequency
1029   double coarse_freq_2 = dac_rate () / 4; // Second coarse frequency
1030   double coarse_limit_1 = coarse_freq_1 / 2; // Midpoint of [0 , freq1] range
1031   double coarse_limit_2 = (coarse_freq_1 + coarse_freq_2) / 2; // Midpoint of [freq1 , freq2] range
1032   double high_limit = (double)44e6/128e6*dac_rate (); // Highest meaningful frequency
1033
1034   if (freq < -high_limit)               // too low
1035     return false;
1036   else if (freq < -coarse_limit_2){     // For 64MHz: [-44, -24)
1037     cm = CM_NEG_FDAC_OVER_4;
1038     coarse = -coarse_freq_2;
1039   }
1040   else if (freq < -coarse_limit_1){     // For 64MHz: [-24, -8)
1041     cm = CM_NEG_FDAC_OVER_8;
1042     coarse = -coarse_freq_1;
1043   }
1044   else if (freq < coarse_limit_1){              // For 64MHz: [-8, 8)
1045     cm = CM_OFF;
1046     coarse = 0;
1047   }
1048   else if (freq < coarse_limit_2){      // For 64MHz: [8, 24)
1049     cm = CM_POS_FDAC_OVER_8;
1050     coarse = coarse_freq_1;
1051   }
1052   else if (freq <= high_limit){ // For 64MHz: [24, 44]
1053     cm = CM_POS_FDAC_OVER_4;
1054     coarse = coarse_freq_2;
1055   }
1056   else                          // too high
1057     return false;
1058
1059
1060   set_coarse_modulator (channel, cm);   // set bits in d_tx_modulator_shadow
1061
1062   double fine = freq - coarse;
1063
1064
1065   // Compute fine tuning word...
1066   // This assumes we're running the 4x on-chip interpolator.
1067   // (This is required to use the fine modulator.)
1068
1069   unsigned int v =
1070     compute_freq_control_word_9862 (dac_rate () / 4,
1071                                     fine, &d_tx_freq[channel], d_verbose);
1072
1073   d_tx_freq[channel] += coarse;         // adjust actual
1074   
1075   unsigned char high, mid, low;
1076
1077   high = (v >> 16) & 0xff;
1078   mid =  (v >>  8) & 0xff;
1079   low =  (v >>  0) & 0xff;
1080
1081   bool ok = true;
1082
1083   // write the fine tuning word
1084   ok &= _write_9862 (channel, REG_TX_NCO_FTW_23_16, high);
1085   ok &= _write_9862 (channel, REG_TX_NCO_FTW_15_8,  mid);
1086   ok &= _write_9862 (channel, REG_TX_NCO_FTW_7_0,   low);
1087
1088
1089   d_tx_modulator_shadow[channel] |= TX_MODULATOR_ENABLE_NCO;
1090
1091   if (fine < 0)
1092     d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_FINE_TUNE;
1093   else
1094     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_NEG_FINE_TUNE;
1095
1096   ok &=_write_9862 (channel, REG_TX_MODULATOR, d_tx_modulator_shadow[channel]);
1097
1098   return ok;
1099 }
1100 #endif
1101
1102 bool
1103 usrp_standard_tx::set_coarse_modulator (int channel, coarse_mod_t cm)
1104 {
1105   if (channel < 0 || channel >= MAX_CHAN)
1106     return false;
1107
1108   switch (cm){
1109   case CM_NEG_FDAC_OVER_4:
1110     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
1111     d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4;
1112     d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE;
1113     break;
1114
1115   case CM_NEG_FDAC_OVER_8:
1116     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
1117     d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8;
1118     d_tx_modulator_shadow[channel] |= TX_MODULATOR_NEG_COARSE_TUNE;
1119     break;
1120
1121   case CM_OFF:
1122     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
1123     break;
1124
1125   case CM_POS_FDAC_OVER_8:
1126     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
1127     d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_8;
1128     break;
1129
1130   case CM_POS_FDAC_OVER_4:
1131     d_tx_modulator_shadow[channel] &= ~TX_MODULATOR_CM_MASK;
1132     d_tx_modulator_shadow[channel] |= TX_MODULATOR_COARSE_MODULATION_F_OVER_4;
1133     break;
1134
1135   default:
1136     return false;
1137   }
1138
1139   d_coarse_mod[channel] = cm;
1140   return true;
1141 }
1142
1143 unsigned int
1144 usrp_standard_tx::interp_rate () const { return d_interp_rate; }
1145
1146 int
1147 usrp_standard_tx::nchannels () const { return d_nchan; }
1148
1149 int
1150 usrp_standard_tx::mux () const { return d_sw_mux; }
1151
1152 double
1153 usrp_standard_tx::tx_freq (int channel) const
1154 {
1155   if (channel < 0 || channel >= MAX_CHAN)
1156     return 0;
1157
1158   return d_tx_freq[channel];
1159 }
1160
1161 usrp_standard_tx::coarse_mod_t
1162 usrp_standard_tx::coarse_modulator (int channel) const
1163 {
1164   if (channel < 0 || channel >= MAX_CHAN)
1165     return CM_OFF;
1166
1167   return d_coarse_mod[channel];
1168 }
1169
1170 bool
1171 usrp_standard_tx::tune(int chan, db_base_sptr db, double target_freq, usrp_tune_result *result)
1172 {
1173   duc_control dxc(this, chan);
1174   return tune_a_helper(db, target_freq, converter_rate(), dxc, result);
1175 }