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