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