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