Deadly printfs turned off... Specified gain ranges for TV Rx and RFX boards.
[debian/gnuradio] / usrp2 / firmware / lib / db_rfx.c
1 /*
2  * Copyright 2008 Free Software Foundation, Inc.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <spi.h>
19 #include <memory_map.h>
20 #include <db_base.h>
21 #include <hal_io.h>
22 #include <ad9510.h>
23 #include <stdio.h>
24 #include <mdelay.h>
25 #include <lsdac.h>
26 #include <clocks.h>
27
28
29 bool rfx_init_rx(struct db_base *db);
30 bool rfx_init_tx(struct db_base *db);
31 bool rfx_set_freq(struct db_base *db, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc);
32 bool rfx_set_gain_rx(struct db_base *db, u2_fxpt_gain_t gain);
33 bool rfx_set_gain_tx(struct db_base *db, u2_fxpt_gain_t gain);
34 bool rfx_set_tx_enable(struct db_base *, bool on);
35
36 // Control Latch Defines
37 #define P 0  // Prescalar value for setting in regs, must match the next line...
38 #define PRESCALER 8  // Presacalar value for computations
39 #define PD 0  // Power down, 0 = normal operation
40 #define PL 0 // PLL power output
41 #define MTLD 1 // Mute till lock detect
42 #define CPGAIN 0 // Charge pump gain, use setting 1, also in N-reg
43 #define CP3S 0 // Charge pump tri-state, 0 = normal operation
44 #define PDP 1 // Phase detector polarity
45 #define MUXOUT 1 // Digital lock detect, active high
46 #define CR 0 // normal operation
47 #define PC 1 // core power
48
49 // N Latch Defines
50 #define DIVSEL 0 // N Counter always operates on full rate
51 #define N_RSV 0
52
53 // R Latch Defines
54 #define R_RSV 0
55 #define R_BSC 3
56 #define R_TMB 0
57 #define R_LDP 1
58 #define R_ABP 0
59 #define R_DIV 16
60
61 #define phdet_freq (U2_DOUBLE_TO_FXPT_FREQ(100e6/R_DIV))
62
63 // IO Pin functions
64 #define POWER_UP  (1 << 7)  //  Low enables power supply
65 #define ANT_SW  (1 << 6)   // On TX DB, 0 = TX, 1 = RX, on RX DB 0 = main ant, 1 = RX2
66 #define MIX_EN  (1 << 5)   // Enable appropriate mixer
67 #define LOCKDET_MASK (1 << 2)   // Input pin
68
69 struct db_rfx_common {
70   // RFX common stuff
71   unsigned char DIV2;
72   unsigned char CP1;
73   unsigned char CP2;
74   int freq_mult;
75   int spi_mask;
76 };
77
78 struct db_rfx_dummy {
79   struct db_base        base;
80   struct db_rfx_common  common;
81 };
82
83
84 struct db_rfx_400_rx {
85   struct db_base        base;
86   struct db_rfx_common  common;
87 };
88
89 struct db_rfx_400_tx {
90   struct db_base        base;
91   struct db_rfx_common  common;
92 };
93
94 struct db_rfx_900_rx {
95   struct db_base        base;
96   struct db_rfx_common  common;
97 };
98
99 struct db_rfx_900_tx {
100   struct db_base        base;
101   struct db_rfx_common  common;
102 };
103
104 struct db_rfx_1200_rx {
105   struct db_base        base;
106   struct db_rfx_common  common;
107 };
108
109 struct db_rfx_1200_tx {
110   struct db_base        base;
111   struct db_rfx_common  common;
112 };
113
114 struct db_rfx_1800_rx {
115   struct db_base        base;
116   struct db_rfx_common  common;
117 };
118
119 struct db_rfx_1800_tx {
120   struct db_base        base;
121   struct db_rfx_common  common;
122 };
123
124 struct db_rfx_2400_rx {
125   struct db_base        base;
126   struct db_rfx_common  common;
127 };
128
129 struct db_rfx_2400_tx {
130   struct db_base        base;
131   struct db_rfx_common  common;
132 };
133
134
135 /*
136  * The class instances
137  */
138 struct db_rfx_400_rx db_rfx_400_rx = {
139   .base.dbid = 0x0024,
140   .base.is_tx = false,
141   .base.output_enables = 0x00E0,
142   .base.used_pins = 0x00FF,
143   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(400e6),
144   .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(500e6),
145   .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
146   .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(45),
147   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.022),
148   .base.is_quadrature = true,
149   .base.i_and_q_swapped = true,
150   .base.spectrum_inverted = false,
151   //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6),
152   .base.init = rfx_init_rx,
153   .base.set_freq = rfx_set_freq,
154   .base.set_gain = rfx_set_gain_rx,
155   .base.set_tx_enable = 0,
156   .base.atr_mask = 0x00E0,
157   .base.atr_txval = POWER_UP,
158   .base.atr_rxval = POWER_UP|MIX_EN,
159   // .base.atr_tx_delay =
160   // .base.atr_rx_delay =
161   .common.DIV2 = 0,
162   .common.CP1 = 7,
163   .common.CP2 = 7,
164   .common.spi_mask = SPI_SS_RX_DB,
165   .common.freq_mult = 2
166 };
167
168
169 struct db_rfx_400_tx db_rfx_400_tx = {
170   .base.dbid = 0x0028,
171   .base.is_tx = true,
172   .base.output_enables = 0x00E0,
173   .base.used_pins = 0x00FF,
174   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(400e6),
175   .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(500e6),
176   //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
177   //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
178   //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
179   .base.is_quadrature = true,
180   .base.i_and_q_swapped = true,
181   .base.spectrum_inverted = false,
182   //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6),
183   .base.init = rfx_init_tx,
184   .base.set_freq = rfx_set_freq,
185   .base.set_gain = rfx_set_gain_tx,
186   .base.set_tx_enable = rfx_set_tx_enable,
187   .base.atr_mask = 0x00E0,
188   .base.atr_txval = POWER_UP|MIX_EN, 
189   .base.atr_rxval = POWER_UP|ANT_SW,
190   // .base.atr_tx_delay =
191   // .base.atr_rx_delay =
192   .common.DIV2 = 1,
193   .common.CP1 = 7,
194   .common.CP2 = 7,
195   .common.spi_mask = SPI_SS_TX_DB,
196   .common.freq_mult = 2
197 };
198
199 struct db_rfx_900_rx db_rfx_900_rx = {
200   .base.dbid = 0x0025,
201   .base.is_tx = false,
202   .base.output_enables = 0x00E0,
203   .base.used_pins = 0x00FF,
204   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(800e6),
205   .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1000e6),
206   .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
207   .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(70),
208   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.034),
209   .base.is_quadrature = true,
210   .base.i_and_q_swapped = true,
211   .base.spectrum_inverted = false,
212   //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6),
213   .base.init = rfx_init_rx,
214   .base.set_freq = rfx_set_freq,
215   .base.set_gain = rfx_set_gain_rx,
216   .base.set_tx_enable = 0,
217   .base.atr_mask = 0x00E0,
218   .base.atr_txval = 0,
219   .base.atr_rxval = MIX_EN,
220   // .base.atr_tx_delay =
221   // .base.atr_rx_delay =
222   .common.DIV2 = 1,
223   .common.CP1 = 7,
224   .common.CP2 = 7,
225   .common.spi_mask = SPI_SS_RX_DB,
226   .common.freq_mult = 2
227 };
228
229
230 struct db_rfx_900_tx db_rfx_900_tx = {
231   .base.dbid = 0x0029,
232   .base.is_tx = true,
233   .base.output_enables = 0x00E0,
234   .base.used_pins = 0x00FF,
235   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(800e6),
236   .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1000e6),
237   //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
238   //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
239   //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
240   .base.is_quadrature = true,
241   .base.i_and_q_swapped = true,
242   .base.spectrum_inverted = false,
243   //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6),
244   .base.init = rfx_init_tx,
245   .base.set_freq = rfx_set_freq,
246   .base.set_gain = rfx_set_gain_tx,
247   .base.set_tx_enable = rfx_set_tx_enable,
248   .base.atr_mask = 0x00E0,
249   .base.atr_txval = MIX_EN, 
250   .base.atr_rxval = ANT_SW,
251   // .base.atr_tx_delay =
252   // .base.atr_rx_delay =
253   .common.DIV2 = 1,
254   .common.CP1 = 7,
255   .common.CP2 = 7,
256   .common.spi_mask = SPI_SS_TX_DB,
257   .common.freq_mult = 2
258 };
259
260 struct db_rfx_1200_rx db_rfx_1200_rx = {
261   .base.dbid = 0x0026,
262   .base.is_tx = false,
263   .base.output_enables = 0x00E0,
264   .base.used_pins = 0x00FF,
265   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(1150e6),
266   .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1350e6),
267   .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
268   .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(70),
269   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.034),
270   .base.is_quadrature = true,
271   .base.i_and_q_swapped = true,
272   .base.spectrum_inverted = false,
273   //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6),
274   .base.init = rfx_init_rx,
275   .base.set_freq = rfx_set_freq,
276   .base.set_gain = rfx_set_gain_rx,
277   .base.set_tx_enable = 0,
278   .base.atr_mask = 0x00E0,
279   .base.atr_txval = 0,
280   .base.atr_rxval = MIX_EN,
281   // .base.atr_tx_delay =
282   // .base.atr_rx_delay =
283   .common.DIV2 = 1,
284   .common.CP1 = 7,
285   .common.CP2 = 7,
286   .common.spi_mask = SPI_SS_RX_DB,
287   .common.freq_mult = 2
288 };
289
290
291 struct db_rfx_1200_tx db_rfx_1200_tx = {
292   .base.dbid = 0x002a,
293   .base.is_tx = true,
294   .base.output_enables = 0x00E0,
295   .base.used_pins = 0x00FF,
296   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(1150e6),
297   .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(1350e6),
298   //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
299   //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
300   //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
301   .base.is_quadrature = true,
302   .base.i_and_q_swapped = true,
303   .base.spectrum_inverted = false,
304   //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6),
305   .base.init = rfx_init_tx,
306   .base.set_freq = rfx_set_freq,
307   .base.set_gain = rfx_set_gain_tx,
308   .base.set_tx_enable = rfx_set_tx_enable,
309   .base.atr_mask = 0x00E0,
310   .base.atr_txval = MIX_EN, 
311   .base.atr_rxval = ANT_SW,
312   // .base.atr_tx_delay =
313   // .base.atr_rx_delay =
314   .common.DIV2 = 1,
315   .common.CP1 = 7,
316   .common.CP2 = 7,
317   .common.spi_mask = SPI_SS_TX_DB,
318   .common.freq_mult = 2
319 };
320
321 struct db_rfx_1800_rx db_rfx_1800_rx = {
322   .base.dbid = 0x0034,
323   .base.is_tx = false,
324   .base.output_enables = 0x00E0,
325   .base.used_pins = 0x00FF,
326   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(1600e6),
327   .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2000e6),
328   .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
329   .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(70),
330   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.034),
331   .base.is_quadrature = true,
332   .base.i_and_q_swapped = true,
333   .base.spectrum_inverted = false,
334   //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6),
335   .base.init = rfx_init_rx,
336   .base.set_freq = rfx_set_freq,
337   .base.set_gain = rfx_set_gain_rx,
338   .base.set_tx_enable = 0,
339   .base.atr_mask = 0x00E0,
340   .base.atr_txval = 0,
341   .base.atr_rxval = MIX_EN,
342   // .base.atr_tx_delay =
343   // .base.atr_rx_delay =
344   .common.DIV2 = 0,
345   .common.CP1 = 7,
346   .common.CP2 = 7,
347   .common.spi_mask = SPI_SS_RX_DB,
348   .common.freq_mult = 1
349 };
350
351
352 struct db_rfx_1800_tx db_rfx_1800_tx = {
353   .base.dbid = 0x0035,
354   .base.is_tx = true,
355   .base.output_enables = 0x00E0,
356   .base.used_pins = 0x00FF,
357   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(1600e6),
358   .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2000e6),
359   //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
360   //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
361   //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
362   .base.is_quadrature = true,
363   .base.i_and_q_swapped = true,
364   .base.spectrum_inverted = false,
365   //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6),
366   .base.init = rfx_init_tx,
367   .base.set_freq = rfx_set_freq,
368   .base.set_gain = rfx_set_gain_tx,
369   .base.set_tx_enable = rfx_set_tx_enable,
370   .base.atr_mask = 0x00E0,
371   .base.atr_txval = MIX_EN, 
372   .base.atr_rxval = ANT_SW,
373   // .base.atr_tx_delay =
374   // .base.atr_rx_delay =
375   .common.DIV2 = 0,
376   .common.CP1 = 7,
377   .common.CP2 = 7,
378   .common.spi_mask = SPI_SS_TX_DB,
379   .common.freq_mult = 1
380 };
381
382
383 struct db_rfx_2400_rx db_rfx_2400_rx = {
384   .base.dbid = 0x0027,
385   .base.is_tx = false,
386   .base.output_enables = 0x00E0,
387   .base.used_pins = 0x00FF,
388   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(2300e6),
389   .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2700e6),
390   .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
391   .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(70),
392   .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(0.034),
393   .base.is_quadrature = true,
394   .base.i_and_q_swapped = true,
395   .base.spectrum_inverted = false,
396   //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6),
397   .base.init = rfx_init_rx,
398   .base.set_freq = rfx_set_freq,
399   .base.set_gain = rfx_set_gain_rx,
400   .base.set_tx_enable = 0,
401   .base.atr_mask = 0x00E0,
402   .base.atr_txval = 0,
403   .base.atr_rxval = MIX_EN,
404   // .base.atr_tx_delay =
405   // .base.atr_rx_delay =
406   .common.DIV2 = 0,
407   .common.CP1 = 7,
408   .common.CP2 = 7,
409   .common.spi_mask = SPI_SS_RX_DB,
410   .common.freq_mult = 1
411 };
412
413
414 struct db_rfx_2400_tx db_rfx_2400_tx = {
415   .base.dbid = 0x002b,
416   .base.is_tx = true,
417   .base.output_enables = 0x00E0,
418   .base.used_pins = 0x00FF,
419   .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(2300e6),
420   .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(2700e6),
421   //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
422   //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
423   //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
424   .base.is_quadrature = true,
425   .base.i_and_q_swapped = true,
426   .base.spectrum_inverted = false,
427   //.base.lo_offset = U2_DOUBLE_TO_FXPT_FREQ(4e6),
428   .base.init = rfx_init_tx,
429   .base.set_freq = rfx_set_freq,
430   .base.set_gain = rfx_set_gain_tx,
431   .base.set_tx_enable = rfx_set_tx_enable,
432   .base.atr_mask = 0x00E0,
433   .base.atr_txval = MIX_EN, 
434   .base.atr_rxval = ANT_SW,
435   // .base.atr_tx_delay =
436   // .base.atr_rx_delay =
437   .common.DIV2 = 0,
438   .common.CP1 = 7,
439   .common.CP2 = 7,
440   .common.spi_mask = SPI_SS_TX_DB,
441   .common.freq_mult = 1
442 };
443
444
445 bool
446 rfx_init_tx(struct db_base *dbb)
447 {
448   //struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
449   clocks_enable_tx_dboard(true, 0);
450   return true;
451 }
452
453 bool
454 rfx_init_rx(struct db_base *dbb)
455 {
456   //struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
457   clocks_enable_rx_dboard(true, 0);
458
459   // test gain
460   dbb->set_gain(dbb,U2_DOUBLE_TO_FXPT_GAIN(45.0));
461   return true;
462 }
463
464 bool
465 rfx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc)
466 {
467   *dc = 0;
468   struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
469   //u2_fxpt_freq_t desired_n = db->common.freq_mult*freq/phdet_freq;
470   //int N_DIV = u2_fxpt_freq_round_to_int(desired_n);
471   u2_fxpt_freq_t desired_n = ((1LL<<20) * db->common.freq_mult*freq)/phdet_freq;
472   int N_DIV = u2_fxpt_freq_round_to_int(desired_n);
473   int B = N_DIV/PRESCALER;
474   int A = N_DIV - PRESCALER*B;
475
476   if(B<A)
477     return false;
478
479   int R = (R_RSV<<22)|(R_BSC<<20)|(R_TMB<<19)|(R_LDP<<18)|(R_ABP<<16)|(R_DIV<<2)|1;
480   int N = (DIVSEL<<23)|(db->common.DIV2<<22)|(CPGAIN<<21)|(B<<8)|(N_RSV<<7)|(A<<2)|2;
481   int C = (P<<22)|(PD<<20)|(db->common.CP2<<17)|(db->common.CP1<<14)|(PL<<12)|
482     (MTLD<<11)|(CPGAIN<<10)|(CP3S<<9)|(PDP<<8)|(MUXOUT<<5)|(CR<<4)|(PC<<2)|0;
483
484   spi_transact(SPI_TXONLY,db->common.spi_mask,R,24,SPIF_PUSH_FALL);
485   spi_transact(SPI_TXONLY,db->common.spi_mask,C,24,SPIF_PUSH_FALL);
486   mdelay(10);
487   spi_transact(SPI_TXONLY,db->common.spi_mask,N,24,SPIF_PUSH_FALL);
488
489   //printf("A = %d, B = %d, N_DIV = %d\n",A, B, N_DIV);
490   *dc = (N_DIV * phdet_freq) / db->common.freq_mult;
491   return true;
492 }
493
494 bool
495 rfx_set_gain_tx(struct db_base *dbb, u2_fxpt_gain_t gain)
496 {
497   // There is no analog gain control on TX
498   return true;
499 }
500
501 bool
502 rfx_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain)
503 {
504   struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
505
506   u2_fxpt_gain_t MAXGAIN = U2_DOUBLE_TO_FXPT_GAIN(70.0);
507
508   int offset_q8 = (int)(1.2/3.3*4096*(1<<15));  
509   int slope_q8 = (int)(-1.0/45.0*4096/3.3*256); 
510   int dacword = ((slope_q8 * gain) + offset_q8)>>15;
511   //printf("DACWORD %d\n",dacword);
512   lsdac_write_rx(1,dacword);
513   return true;
514   /*
515     def set_gain(self, gain):
516         """
517         Set the gain.
518
519         @param gain:  gain in decibels
520         @returns True/False
521         """
522         maxgain = self.gain_range()[1] - self._u.pga_max()
523         mingain = self.gain_range()[0]
524         if gain > maxgain:
525             pga_gain = gain-maxgain
526             assert pga_gain <= self._u.pga_max()
527             agc_gain = maxgain
528         else:
529             pga_gain = 0
530             agc_gain = gain
531         V_maxgain = .2
532         V_mingain = 1.2
533         V_fullscale = 3.3
534         dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale
535         assert dac_value>=0 and dac_value<4096
536         return self._u.write_aux_dac(self._which, 0, int(dac_value)) and \
537                self._set_pga(int(pga_gain))
538
539     def gain_range(self):
540         return (self._u.pga_min(), self._u.pga_max() + 70, 0.05) -- For 900-2400
541         return (self._u.pga_min(), self._u.pga_max() + 45, 0.035) -- For 400
542   */
543 }
544
545
546 bool
547 rfx_set_tx_enable(struct db_base *dbb, bool on)
548 {
549   struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
550
551   // FIXME
552
553   return false;
554 }
555
556 bool
557 rfx_lock_detect(struct db_base *dbb)
558 {
559   struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
560   int pins;
561   pins = hal_gpio_read( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK );
562   if(pins & LOCKDET_MASK)
563     return true;
564   return false;
565 }
566
567 /* 
568     def select_rx_antenna(self, which_antenna):
569         """
570         Specify which antenna port to use for reception.
571         @param which_antenna: either 'TX/RX' or 'RX2'
572         """
573         if which_antenna in (0, 'TX/RX'):
574             self._u.write_io(self._which, 0,        RX2_RX1N)
575         elif which_antenna in (1, 'RX2'):
576             self._u.write_io(self._which, RX2_RX1N, RX2_RX1N)
577         else:
578             raise ValueError, "which_antenna must be either 'TX/RX' or 'RX2'"
579
580     def set_gain(self, gain):
581         """
582         Set the gain.
583
584         @param gain:  gain in decibels
585         @returns True/False
586         """
587         maxgain = self.gain_range()[1] - self._u.pga_max()
588         mingain = self.gain_range()[0]
589         if gain > maxgain:
590             pga_gain = gain-maxgain
591             assert pga_gain <= self._u.pga_max()
592             agc_gain = maxgain
593         else:
594             pga_gain = 0
595             agc_gain = gain
596         V_maxgain = .2
597         V_mingain = 1.2
598         V_fullscale = 3.3
599         dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale
600         assert dac_value>=0 and dac_value<4096
601         return self._u.write_aux_dac(self._which, 0, int(dac_value)) and \
602                self._set_pga(int(pga_gain))
603
604     def gain_range(self):
605         return (self._u.pga_min(), self._u.pga_max() + 70, 0.05) -- For 900-2400
606         return (self._u.pga_min(), self._u.pga_max() + 45, 0.035) -- For 400
607
608 */