Merge commit 'v3.3.0' into upstream
[debian/gnuradio] / usrp / host / lib / db_flexrf.cc
1 //
2 // Copyright 2008,2009 Free Software Foundation, Inc.
3 // 
4 // This file is part of GNU Radio
5 // 
6 // GNU Radio is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either asversion 3, or (at your option)
9 // any later version.
10 // 
11 // GNU Radio is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 // 
16 // You should have received a copy of the GNU General Public License
17 // along with GNU Radio; see the file COPYING.  If not, write to
18 // the Free Software Foundation, Inc., 51 Franklin Street,
19 // Boston, MA 02110-1301, USA.
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include <usrp/db_flexrf.h>
26 #include <db_base_impl.h>
27
28 // d'board i/o pin defs
29 // Tx and Rx have shared defs, but different i/o regs
30 #define AUX_RXAGC (1 << 8)
31 #define POWER_UP  (1 << 7)         // enables power supply
32 #define RX_TXN    (1 << 6)         // Tx only: T/R antenna switch for TX/RX port
33 #define RX2_RX1N  (1 << 6)         // Rx only: antenna switch between RX2 and TX/RX port
34 #define ENABLE    (1 << 5)         // enables mixer
35 #define AUX_SEN   (1 << 4)
36 #define AUX_SCLK  (1 << 3)
37 #define PLL_LOCK_DETECT (1 << 2)
38 #define AUX_SDO   (1 << 1)
39 #define CLOCK_OUT (1 << 0)
40
41 flexrf_base::flexrf_base(usrp_basic_sptr _usrp, int which, int _power_on)
42   : db_base(_usrp, which), d_power_on(_power_on)
43 {
44   /*
45     @param usrp: instance of usrp.source_c
46     @param which: which side: 0 or 1 corresponding to side A or B respectively
47     @type which: int
48   */
49
50   d_first = true;
51   d_spi_format = SPI_FMT_MSB | SPI_FMT_HDR_0;
52
53   usrp()->_write_oe(d_which, 0, 0xffff);   // turn off all outputs
54   _enable_refclk(false);                // disable refclk
55
56   set_auto_tr(false);
57 }
58
59 flexrf_base::~flexrf_base()
60 {
61   delete d_common;
62 }
63
64 void
65 flexrf_base::_write_all(int R, int control, int N)
66 {
67   /*
68     Write R counter latch, control latch and N counter latch to VCO.
69     
70     Adds 10ms delay between writing control and N if this is first call.
71     This is the required power-up sequence.
72     
73     @param R: 24-bit R counter latch
74     @type R: int
75     @param control: 24-bit control latch
76     @type control: int
77     @param N: 24-bit N counter latch
78     @type N: int
79   */
80   timespec t;
81   t.tv_sec = 0;
82   t.tv_nsec = 10000000;
83
84   _write_R(R);
85   _write_control(control);
86   if(d_first) {
87     //time.sleep(0.010);
88     nanosleep(&t, NULL);
89     d_first = false;
90   }
91   _write_N(N);
92 }
93
94 void
95 flexrf_base::_write_control(int control)
96 {
97   _write_it((control & ~0x3) | 0);
98 }
99
100 void
101 flexrf_base::_write_R(int R)
102 {
103   _write_it((R & ~0x3) | 1);
104 }
105
106 void
107 flexrf_base::_write_N(int N)
108 {
109   _write_it((N & ~0x3) | 2);
110 }
111
112 void
113 flexrf_base::_write_it(int v)
114 {
115   char s[3];
116   s[0] = (char)((v >> 16) & 0xff);
117   s[1] = (char)((v >>  8) & 0xff);
118   s[2] = (char)(v & 0xff);
119   std::string str(s, 3);
120   usrp()->_write_spi(0, d_spi_enable, d_spi_format, str);
121 }
122         
123 bool
124 flexrf_base::_lock_detect()
125 {
126   /*
127     @returns: the value of the VCO/PLL lock detect bit.
128     @rtype: 0 or 1
129   */
130   if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
131     return true;
132   }
133   else {      // Give it a second chance
134     // FIXME: make portable sleep
135     timespec t;
136     t.tv_sec = 0;
137     t.tv_nsec = 100000000;
138     nanosleep(&t, NULL);
139     
140     if(usrp()->read_io(d_which) & PLL_LOCK_DETECT) {
141       return true;
142     }
143     else {
144       return false;
145     }
146   }
147 }
148
149 bool
150 flexrf_base::_compute_regs(double freq, int &retR, int &retcontrol,
151                            int &retN, double &retfreq)
152 {
153   /*
154     Determine values of R, control, and N registers, along with actual freq.
155     
156     @param freq: target frequency in Hz
157     @type freq: float
158     @returns: (R, control, N, actual_freq)
159     @rtype: tuple(int, int, int, float)
160     
161     Override this in derived classes.
162   */
163   
164   //raise NotImplementedError;
165   throw std::runtime_error("_compute_regs called from flexrf_base\n");
166 }
167
168 int
169 flexrf_base::_compute_control_reg()
170 {
171   return d_common->_compute_control_reg();
172 }
173
174 int
175 flexrf_base::_refclk_divisor()
176 {
177   return d_common->_refclk_divisor();
178 }
179
180 struct freq_result_t
181 flexrf_base::set_freq(double freq)
182 {
183   /*
184     @returns (ok, actual_baseband_freq) where:
185     ok is True or False and indicates success or failure,
186     actual_baseband_freq is the RF frequency that corresponds to DC in the IF.
187   */
188
189   struct freq_result_t args = {false, 0};
190
191   // Offsetting the LO helps get the Tx carrier leakage out of the way.
192   // This also ensures that on Rx, we're not getting hosed by the
193   // FPGA's DC removal loop's time constant.  We were seeing a
194   // problem when running with discontinuous transmission.
195   // Offsetting the LO made the problem go away.
196   freq += d_lo_offset;
197   
198   int R, control, N;
199   double actual_freq;
200   _compute_regs(freq, R, control, N, actual_freq);
201
202   if(R==0) {
203     return args;
204   }
205    
206   _write_all(R, control, N);
207   args.ok = _lock_detect();
208   args.baseband_freq = actual_freq;
209   return args;
210 }
211
212 bool
213 flexrf_base::_set_pga(float pga_gain)
214 {
215   if(d_which == 0) {
216     usrp()->set_pga(0, pga_gain);
217     usrp()->set_pga(1, pga_gain);
218   }
219   else {
220     usrp()->set_pga(2, pga_gain);
221     usrp()->set_pga(3, pga_gain);
222   }
223   return true;
224 }
225
226 bool
227 flexrf_base::is_quadrature()
228 {
229   /*
230     Return True if this board requires both I & Q analog channels.
231     
232     This bit of info is useful when setting up the USRP Rx mux register.
233   */
234   return true;
235 }
236
237 double
238 flexrf_base::freq_min()
239 {
240   return d_common->freq_min();
241 }
242
243 double
244 flexrf_base::freq_max()
245 {
246   return d_common->freq_max();
247 }
248
249 // ----------------------------------------------------------------
250
251 flexrf_base_tx::flexrf_base_tx(usrp_basic_sptr _usrp, int which, int _power_on)
252   : flexrf_base(_usrp, which, _power_on)
253 {
254   /*
255     @param usrp: instance of usrp.sink_c
256     @param which: 0 or 1 corresponding to side TX_A or TX_B respectively.
257   */
258   
259   if(which == 0) {
260     d_spi_enable = SPI_ENABLE_TX_A;
261   }
262   else {
263     d_spi_enable = SPI_ENABLE_TX_B;
264   }
265   
266   // power up the transmit side, but don't enable the mixer
267   usrp()->_write_oe(d_which,(POWER_UP|RX_TXN|ENABLE), 0xffff);
268   usrp()->write_io(d_which, (power_on()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
269   set_lo_offset(4e6);
270
271   set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
272 }
273
274 flexrf_base_tx::~flexrf_base_tx()
275 {
276   shutdown();
277 }
278
279
280 void
281 flexrf_base_tx::shutdown()
282 {
283   // fprintf(stderr, "flexrf_base_tx::shutdown  d_is_shutdown = %d\n", d_is_shutdown);
284
285   if (!d_is_shutdown){
286     d_is_shutdown = true;
287     // do whatever there is to do to shutdown
288
289     // Power down and leave the T/R switch in the R position
290     usrp()->write_io(d_which, (power_off()|RX_TXN), (POWER_UP|RX_TXN|ENABLE));
291
292     // Power down VCO/PLL
293     d_PD = 3;
294   
295     _write_control(_compute_control_reg());
296     _enable_refclk(false);                       // turn off refclk
297     set_auto_tr(false);
298   }
299 }
300
301 bool
302 flexrf_base_tx::set_auto_tr(bool on)
303 {
304   bool ok = true;
305   if(on) {
306     ok &= set_atr_mask (RX_TXN | ENABLE);
307     ok &= set_atr_txval(0      | ENABLE);
308     ok &= set_atr_rxval(RX_TXN | 0);
309   }
310   else {
311     ok &= set_atr_mask (0);
312     ok &= set_atr_txval(0);
313     ok &= set_atr_rxval(0);
314   }
315   return ok;
316 }
317
318 bool
319 flexrf_base_tx::set_enable(bool on)
320 {
321   /*
322     Enable transmitter if on is true
323   */
324
325   int v;
326   int mask = RX_TXN | ENABLE;
327   if(on) {
328     v = ENABLE;
329   }
330   else {
331     v = RX_TXN;
332   }
333   return usrp()->write_io(d_which, v, mask);
334 }
335
336 float
337 flexrf_base_tx::gain_min()
338 {
339   return usrp()->pga_max();
340 }
341
342 float
343 flexrf_base_tx::gain_max()
344 {
345   return usrp()->pga_max();
346 }
347
348 float
349 flexrf_base_tx::gain_db_per_step()
350 {
351   return 1;
352 }
353
354 bool
355 flexrf_base_tx::set_gain(float gain)
356 {
357   /*
358     Set the gain.
359     
360     @param gain:  gain in decibels
361     @returns True/False
362   */
363   return _set_pga(usrp()->pga_max());
364 }
365
366
367 /**************************************************************************/
368
369
370 flexrf_base_rx::flexrf_base_rx(usrp_basic_sptr _usrp, int which, int _power_on)
371   : flexrf_base(_usrp, which, _power_on)
372 {
373   /*
374     @param usrp: instance of usrp.source_c
375     @param which: 0 or 1 corresponding to side RX_A or RX_B respectively.
376   */
377
378   if(which == 0) {
379     d_spi_enable = SPI_ENABLE_RX_A;
380   }
381   else {
382     d_spi_enable = SPI_ENABLE_RX_B;
383   }
384
385   usrp()->_write_oe(d_which, (POWER_UP|RX2_RX1N|ENABLE), 0xffff);
386   usrp()->write_io(d_which,  (power_on()|RX2_RX1N|ENABLE), 
387                    (POWER_UP|RX2_RX1N|ENABLE));
388   
389   // set up for RX on TX/RX port
390   select_rx_antenna("TX/RX");
391   
392   bypass_adc_buffers(true);
393
394   set_lo_offset(-4e6);
395 }
396
397 flexrf_base_rx::~flexrf_base_rx()
398 {
399   shutdown();
400 }
401
402 void
403 flexrf_base_rx::shutdown()
404 {
405   // fprintf(stderr, "flexrf_base_rx::shutdown  d_is_shutdown = %d\n", d_is_shutdown);
406
407   if (!d_is_shutdown){
408     d_is_shutdown = true;
409     // do whatever there is to do to shutdown
410
411     // Power down
412     usrp()->common_write_io(C_RX, d_which, power_off(), (POWER_UP|ENABLE));
413
414     // Power down VCO/PLL
415     d_PD = 3;
416   
417
418     // fprintf(stderr, "flexrf_base_rx::shutdown  before _write_control\n");
419     _write_control(_compute_control_reg());
420
421     // fprintf(stderr, "flexrf_base_rx::shutdown  before _enable_refclk\n");
422     _enable_refclk(false);                       // turn off refclk
423
424     // fprintf(stderr, "flexrf_base_rx::shutdown  before set_auto_tr\n");
425     set_auto_tr(false);
426
427     // fprintf(stderr, "flexrf_base_rx::shutdown  after set_auto_tr\n");
428   }
429 }
430
431 bool
432 flexrf_base_rx::set_auto_tr(bool on)
433 {
434   bool ok = true;
435   if(on) {
436     ok &= set_atr_mask (ENABLE);
437     ok &= set_atr_txval(     0);
438     ok &= set_atr_rxval(ENABLE);
439   }
440   else {
441     ok &= set_atr_mask (0);
442     ok &= set_atr_txval(0);
443     ok &= set_atr_rxval(0);
444   }
445   return true;
446 }
447
448 bool
449 flexrf_base_rx::select_rx_antenna(int which_antenna)
450 {
451   /*
452     Specify which antenna port to use for reception.
453     @param which_antenna: either 'TX/RX' or 'RX2'
454   */
455
456   if(which_antenna == 0) {
457     usrp()->write_io(d_which, 0,RX2_RX1N);
458   }
459   else if(which_antenna == 1) {
460     usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
461   }
462   else {
463     return false;
464     // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
465   }
466   return true;
467 }
468
469 bool
470 flexrf_base_rx::select_rx_antenna(const std::string &which_antenna)
471 {
472   /*
473     Specify which antenna port to use for reception.
474     @param which_antenna: either 'TX/RX' or 'RX2'
475   */
476
477   if(which_antenna == "TX/RX") {
478     usrp()->write_io(d_which, 0, RX2_RX1N);
479   }
480   else if(which_antenna == "RX2") {
481     usrp()->write_io(d_which, RX2_RX1N, RX2_RX1N);
482   }
483   else {
484     // throw std::invalid_argument("which_antenna must be either 'TX/RX' or 'RX2'\n");
485     return false;
486   }
487   return true;
488 }
489
490 bool
491 flexrf_base_rx::set_gain(float gain)
492 {
493   /*
494     Set the gain.
495     
496     @param gain:  gain in decibels
497     @returns True/False
498   */
499   
500   // clamp gain
501   gain = std::max(gain_min(), std::min(gain, gain_max()));
502
503   float pga_gain, agc_gain;
504   float V_maxgain, V_mingain, V_fullscale, dac_value;
505
506   float maxgain = gain_max() - usrp()->pga_max();
507   float mingain = gain_min();
508   if(gain > maxgain) {
509     pga_gain = gain-maxgain;
510     assert(pga_gain <= usrp()->pga_max());
511     agc_gain = maxgain;
512   }
513   else {
514     pga_gain = 0;
515     agc_gain = gain;
516   }
517   
518   V_maxgain = .2;
519   V_mingain = 1.2;
520   V_fullscale = 3.3;
521   dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale;
522
523   assert(dac_value>=0 && dac_value<4096);
524
525   return (usrp()->write_aux_dac(d_which, 0, int(dac_value))
526           && _set_pga(int(pga_gain)));
527 }
528
529 // ----------------------------------------------------------------
530
531
532 _AD4360_common::_AD4360_common()
533 {
534   // R-Register Common Values
535   d_R_RSV = 0;  // bits 23,22
536   d_BSC   = 3;  // bits 21,20 Div by 8 to be safe
537   d_TEST  = 0;  // bit 19
538   d_LDP   = 1;  // bit 18
539   d_ABP   = 0;  // bit 17,16   3ns
540
541   // N-Register Common Values
542   d_N_RSV = 0;  // bit 7
543         
544   // Control Register Common Values
545   d_PD    = 0;  // bits 21,20   Normal operation
546   d_PL    = 0;  // bits 13,12   11mA
547   d_MTLD  = 1;  // bit 11       enabled
548   d_CPG   = 0;  // bit 10       CP setting 1
549   d_CP3S  = 0;  // bit 9        Normal
550   d_PDP   = 1;  // bit 8        Positive
551   d_MUXOUT = 1; // bits 7:5     Digital Lock Detect
552   d_CR    = 0;  // bit 4        Normal
553   d_PC    = 1;  // bits 3,2     Core power 10mA
554 }
555
556 _AD4360_common::~_AD4360_common()
557 {
558 }
559
560 bool
561 _AD4360_common::_compute_regs(double refclk_freq, double freq, int &retR, 
562                               int &retcontrol, int &retN, double &retfreq)
563 {
564   /*
565     Determine values of R, control, and N registers, along with actual freq.
566     
567     @param freq: target frequency in Hz
568     @type freq: float
569     @returns: (R, control, N, actual_freq)
570     @rtype: tuple(int, int, int, float)
571   */
572   
573   //  Band-specific N-Register Values
574   //float phdet_freq = _refclk_freq()/d_R_DIV;
575   double phdet_freq = refclk_freq/d_R_DIV;
576   double desired_n = round(freq*d_freq_mult/phdet_freq);
577   double actual_freq = desired_n * phdet_freq;
578   int B = floor(desired_n/_prescaler());
579   int A = desired_n - _prescaler()*B;
580   d_B_DIV = int(B);    // bits 20:8
581   d_A_DIV = int(A);    // bit 6:2
582
583   //assert db_B_DIV >= db_A_DIV
584   if(d_B_DIV < d_A_DIV) {
585     retR = 0;
586     retcontrol = 0;
587     retN = 0;
588     retfreq = 0;
589     return false;
590   }
591
592   int R = (d_R_RSV<<22) | (d_BSC<<20) | (d_TEST<<19) | 
593     (d_LDP<<18) | (d_ABP<<16) | (d_R_DIV<<2);
594   
595   int control = _compute_control_reg();
596
597   int N = (d_DIVSEL<<23) | (d_DIV2<<22) | (d_CPGAIN<<21) | 
598     (d_B_DIV<<8) | (d_N_RSV<<7) | (d_A_DIV<<2);
599
600   retR = R;
601   retcontrol = control;
602   retN = N;
603   retfreq = actual_freq/d_freq_mult;
604   return true;
605 }
606
607 int
608 _AD4360_common::_compute_control_reg()
609 {
610   int control = (d_P<<22) | (d_PD<<20) | (d_CP2<<17) | (d_CP1<<14)
611     | (d_PL<<12) | (d_MTLD<<11) | (d_CPG<<10) | (d_CP3S<<9) | (d_PDP<<8)
612     | (d_MUXOUT<<5) | (d_CR<<4) | (d_PC<<2);
613   
614   return control;
615 }
616
617 int
618 _AD4360_common::_refclk_divisor()
619 {
620   /*
621     Return value to stick in REFCLK_DIVISOR register
622   */
623   return 1;
624 }
625     
626 int
627 _AD4360_common::_prescaler()
628 {
629   if(d_P == 0) {
630     return 8;
631   }
632   else if(d_P == 1) {
633     return 16;
634   }
635   else {
636     return 32;
637   }
638 }
639
640 //----------------------------------------------------------------------
641
642 _2400_common::_2400_common()
643   : _AD4360_common()
644 {
645   // Band-specific R-Register Values
646   d_R_DIV = 16;  // bits 15:2
647    
648   // Band-specific C-Register values
649   d_P = 1;        // bits 23,22   Div by 16/17
650   d_CP2 = 7;      // bits 19:17
651   d_CP1 = 7;      // bits 16:14
652
653   // Band specifc N-Register Values
654   d_DIVSEL = 0;   // bit 23
655   d_DIV2 = 0;     // bit 22
656   d_CPGAIN = 0;   // bit 21
657   d_freq_mult = 1;
658 }
659
660 double
661 _2400_common::freq_min()
662 {
663   return 2300e6;
664 }
665
666 double
667 _2400_common::freq_max()
668 {
669   return 2900e6;
670 }
671
672 //----------------------------------------------------------------------
673
674 _1200_common::_1200_common()
675   : _AD4360_common()
676 {
677   // Band-specific R-Register Values
678   d_R_DIV = 16;  // bits 15:2  DIV by 16 for a 1 MHz phase detector freq
679    
680   // Band-specific C-Register values
681   d_P = 1;        // bits 23,22   Div by 16/17
682   d_CP2 = 7;      // bits 19:17   1.25 mA
683   d_CP1 = 7;      // bits 16:14   1.25 mA
684   
685   // Band specifc N-Register Values
686   d_DIVSEL = 0;   // bit 23
687   d_DIV2 = 1;     // bit 22
688   d_CPGAIN = 0;   // bit 21
689   d_freq_mult = 2;
690 }
691
692 double 
693 _1200_common::freq_min()
694 {
695   return 1150e6;
696 }
697
698 double 
699 _1200_common::freq_max()
700 {
701   return 1450e6;
702 }
703
704 //-------------------------------------------------------------------------
705
706 _1800_common::_1800_common()
707   : _AD4360_common()
708 {
709   // Band-specific R-Register Values
710   d_R_DIV = 16;  // bits 15:2  DIV by 16 for a 1 MHz phase detector freq
711     
712   // Band-specific C-Register values
713   d_P = 1;        // bits 23,22   Div by 16/17
714   d_CP2 = 7;      // bits 19:17   1.25 mA
715   d_CP1 = 7;      // bits 16:14   1.25 mA
716   
717   // Band specifc N-Register Values
718   d_DIVSEL = 0;   // bit 23
719   d_DIV2 = 0;     // bit 22
720   d_freq_mult = 1;
721   d_CPGAIN = 0;   // bit 21
722 }
723
724 double 
725 _1800_common::freq_min()
726 {
727   return 1500e6;
728 }
729
730 double 
731 _1800_common::freq_max()
732 {
733   return 2100e6;
734 }
735
736 //-------------------------------------------------------------------------
737
738 _900_common::_900_common()
739   : _AD4360_common()
740 {
741   // Band-specific R-Register Values
742   d_R_DIV = 16;  // bits 15:2  DIV by 16 for a 1 MHz phase detector freq
743    
744   // Band-specific C-Register values
745   d_P = 1;        // bits 23,22   Div by 16/17
746   d_CP2 = 7;      // bits 19:17   1.25 mA
747   d_CP1 = 7;      // bits 16:14   1.25 mA
748   
749   // Band specifc N-Register Values
750   d_DIVSEL = 0;   // bit 23
751   d_DIV2 = 1;     // bit 22
752   d_freq_mult = 2;
753   d_CPGAIN = 0;   // bit 21
754 }
755
756 double
757 _900_common::freq_min()
758 {
759   return 750e6;
760 }
761
762 double
763 _900_common::freq_max()
764 {
765   return 1050e6;
766 }
767
768 //-------------------------------------------------------------------------
769
770 _400_common::_400_common()
771   : _AD4360_common()
772 {
773   // Band-specific R-Register Values
774   d_R_DIV = 16;   // bits 15:2 
775    
776   // Band-specific C-Register values
777   d_P = 0;        // bits 23,22   Div by 8/9
778   d_CP2 = 7;      // bits 19:17   1.25 mA
779   d_CP1 = 7;      // bits 16:14   1.25 mA
780   
781   // Band specifc N-Register Values  These are different for TX/RX
782   d_DIVSEL = 0;   // bit 23
783   d_freq_mult = 2;
784   
785   d_CPGAIN = 0;   // bit 21
786 }
787
788 double 
789 _400_common::freq_min()
790 {
791   return 400e6;
792 }  
793
794 double 
795 _400_common::freq_max()
796 {
797   return 500e6;
798 }  
799
800 _400_tx::_400_tx()
801   : _400_common()
802 {
803   d_DIV2 = 1;     // bit 22
804 }
805
806 _400_rx::_400_rx()
807   : _400_common()
808 {
809   d_DIV2 = 0;    // bit 22   // RX side has built-in DIV2 in AD8348
810 }
811
812 //------------------------------------------------------------    
813
814 db_flexrf_2400_tx::db_flexrf_2400_tx(usrp_basic_sptr usrp, int which)
815   : flexrf_base_tx(usrp, which)
816 {
817   d_common = new _2400_common();
818 }
819
820 db_flexrf_2400_tx::~db_flexrf_2400_tx()
821 {
822 }
823
824 bool
825 db_flexrf_2400_tx::_compute_regs(double freq, int &retR, int &retcontrol,
826                                  int &retN, double &retfreq)
827 {
828   return d_common->_compute_regs(_refclk_freq(), freq, retR,
829                                  retcontrol, retN, retfreq);
830 }
831
832
833
834 db_flexrf_2400_rx::db_flexrf_2400_rx(usrp_basic_sptr usrp, int which)
835   : flexrf_base_rx(usrp, which)
836 {
837   d_common = new _2400_common();
838   set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
839 }
840
841 db_flexrf_2400_rx::~db_flexrf_2400_rx()
842 {
843 }
844
845 float
846 db_flexrf_2400_rx::gain_min()
847 {
848   return usrp()->pga_min();
849 }
850
851 float
852 db_flexrf_2400_rx::gain_max()
853 {
854   return usrp()->pga_max()+70;
855 }
856
857 float
858 db_flexrf_2400_rx::gain_db_per_step()
859 {
860   return 0.05;
861 }
862
863
864 bool
865 db_flexrf_2400_rx::i_and_q_swapped()
866 {
867   return true;
868 }
869
870 bool
871 db_flexrf_2400_rx::_compute_regs(double freq, int &retR, int &retcontrol,
872                                  int &retN, double &retfreq)
873 {
874   return d_common->_compute_regs(_refclk_freq(), freq, retR,
875                                  retcontrol, retN, retfreq);
876 }
877
878 //------------------------------------------------------------    
879
880
881 db_flexrf_1200_tx::db_flexrf_1200_tx(usrp_basic_sptr usrp, int which)
882   : flexrf_base_tx(usrp, which)
883 {
884   d_common = new _1200_common();
885 }
886
887 db_flexrf_1200_tx::~db_flexrf_1200_tx()
888 {
889 }
890
891 bool
892 db_flexrf_1200_tx::_compute_regs(double freq, int &retR, int &retcontrol,
893                                  int &retN, double &retfreq)
894 {
895   return d_common->_compute_regs(_refclk_freq(), freq, retR,
896                                  retcontrol, retN, retfreq);
897 }
898
899
900
901
902 db_flexrf_1200_rx::db_flexrf_1200_rx(usrp_basic_sptr usrp, int which)
903   : flexrf_base_rx(usrp, which)
904 {
905   d_common = new _1200_common();
906   set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
907 }
908
909 db_flexrf_1200_rx::~db_flexrf_1200_rx()
910 {
911 }
912
913 float
914 db_flexrf_1200_rx::gain_min()
915 {
916   return usrp()->pga_min();
917 }
918
919 float
920 db_flexrf_1200_rx::gain_max()
921 {
922   return usrp()->pga_max()+70;
923 }
924
925 float
926 db_flexrf_1200_rx::gain_db_per_step()
927 {
928   return 0.05;
929 }
930
931 bool
932 db_flexrf_1200_rx::i_and_q_swapped()
933 {
934   return true;
935 }
936
937 bool
938 db_flexrf_1200_rx::_compute_regs(double freq, int &retR, int &retcontrol,
939                                  int &retN, double &retfreq)
940 {
941   return d_common->_compute_regs(_refclk_freq(), freq, retR,
942                                  retcontrol, retN, retfreq);
943 }
944
945
946 //------------------------------------------------------------    
947
948
949 db_flexrf_1800_tx::db_flexrf_1800_tx(usrp_basic_sptr usrp, int which)
950   : flexrf_base_tx(usrp, which)
951 {
952   d_common = new _1800_common();
953 }
954
955 db_flexrf_1800_tx::~db_flexrf_1800_tx()
956 {
957 }
958
959 bool
960 db_flexrf_1800_tx::_compute_regs(double freq, int &retR, int &retcontrol,
961                                  int &retN, double &retfreq)
962 {
963   return d_common->_compute_regs(_refclk_freq(), freq, retR,
964                                  retcontrol, retN, retfreq);
965 }
966
967
968
969 db_flexrf_1800_rx::db_flexrf_1800_rx(usrp_basic_sptr usrp, int which)
970   : flexrf_base_rx(usrp, which)
971 {
972   d_common = new _1800_common();
973   set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
974 }
975
976 db_flexrf_1800_rx::~db_flexrf_1800_rx()
977 {
978 }
979
980
981 float
982 db_flexrf_1800_rx::gain_min()
983 {
984   return usrp()->pga_min();
985 }
986
987 float
988 db_flexrf_1800_rx::gain_max()
989 {
990   return usrp()->pga_max()+70;
991 }
992
993 float
994 db_flexrf_1800_rx::gain_db_per_step()
995 {
996   return 0.05;
997 }
998
999 bool
1000 db_flexrf_1800_rx::i_and_q_swapped()
1001 {
1002   return true;
1003 }
1004
1005 bool
1006 db_flexrf_1800_rx::_compute_regs(double freq, int &retR, int &retcontrol,
1007                                  int &retN, double &retfreq)
1008 {
1009   return d_common->_compute_regs(_refclk_freq(), freq, retR,
1010                                  retcontrol, retN, retfreq);
1011 }
1012
1013
1014 //------------------------------------------------------------    
1015
1016
1017 db_flexrf_900_tx::db_flexrf_900_tx(usrp_basic_sptr usrp, int which)
1018   : flexrf_base_tx(usrp, which)
1019 {
1020   d_common = new _900_common();
1021 }
1022
1023 db_flexrf_900_tx::~db_flexrf_900_tx()
1024 {
1025 }
1026
1027 bool
1028 db_flexrf_900_tx::_compute_regs(double freq, int &retR, int &retcontrol,
1029                                 int &retN, double &retfreq)
1030 {
1031   return d_common->_compute_regs(_refclk_freq(), freq, retR,
1032                                  retcontrol, retN, retfreq);
1033 }
1034
1035
1036 db_flexrf_900_rx::db_flexrf_900_rx(usrp_basic_sptr usrp, int which)
1037   : flexrf_base_rx(usrp, which)
1038 {
1039   d_common = new _900_common();
1040   set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
1041 }
1042
1043 db_flexrf_900_rx::~db_flexrf_900_rx()
1044 {
1045 }
1046
1047 float
1048 db_flexrf_900_rx::gain_min()
1049 {
1050   return usrp()->pga_min();
1051 }
1052
1053 float
1054 db_flexrf_900_rx::gain_max()
1055 {
1056   return usrp()->pga_max()+70;
1057 }
1058
1059 float
1060 db_flexrf_900_rx::gain_db_per_step()
1061 {
1062   return 0.05;
1063 }
1064
1065 bool
1066 db_flexrf_900_rx::i_and_q_swapped()
1067 {
1068   return true;
1069 }
1070
1071 bool
1072 db_flexrf_900_rx::_compute_regs(double freq, int &retR, int &retcontrol,
1073                                 int &retN, double &retfreq)
1074 {
1075   return d_common->_compute_regs(_refclk_freq(), freq, retR,
1076                                  retcontrol, retN, retfreq);
1077 }
1078
1079 //------------------------------------------------------------    
1080
1081
1082 db_flexrf_400_tx::db_flexrf_400_tx(usrp_basic_sptr usrp, int which)
1083   : flexrf_base_tx(usrp, which, POWER_UP)
1084 {
1085   d_common = new _400_tx();
1086 }
1087
1088 db_flexrf_400_tx::~db_flexrf_400_tx()
1089 {
1090 }
1091
1092 bool
1093 db_flexrf_400_tx::_compute_regs(double freq, int &retR, int &retcontrol,
1094                                 int &retN, double &retfreq)
1095 {
1096   return d_common->_compute_regs(_refclk_freq(), freq, retR,
1097                                  retcontrol, retN, retfreq);
1098 }
1099
1100
1101
1102 db_flexrf_400_rx::db_flexrf_400_rx(usrp_basic_sptr usrp, int which)
1103   : flexrf_base_rx(usrp, which, POWER_UP)
1104 {
1105   d_common = new _400_rx();
1106   set_gain((gain_min() + gain_max()) / 2.0);  // initialize gain
1107 }
1108
1109 db_flexrf_400_rx::~db_flexrf_400_rx()
1110 {
1111 }
1112
1113 float
1114 db_flexrf_400_rx::gain_min()
1115 {
1116   return usrp()->pga_min();
1117 }
1118
1119 float
1120 db_flexrf_400_rx::gain_max()
1121 {
1122   return usrp()->pga_max()+45;
1123 }
1124
1125 float
1126
1127 db_flexrf_400_rx::gain_db_per_step()
1128 {
1129   return 0.035;
1130 }
1131
1132
1133 bool
1134 db_flexrf_400_rx::i_and_q_swapped()
1135 {
1136   return true;
1137 }
1138
1139 bool
1140 db_flexrf_400_rx::_compute_regs(double freq, int &retR, int &retcontrol,
1141                                 int &retN, double &retfreq)
1142 {
1143   return d_common->_compute_regs(_refclk_freq(), freq, retR,
1144                                  retcontrol, retN, retfreq);
1145 }
1146