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