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