2 * Copyright 2008,2009 Free Software Foundation, Inc.
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.
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.
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/>.
19 #include <memory_map.h>
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);
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
49 #define DIVSEL 0 // N Counter always operates on full rate
60 #define phdet_freq (U2_DOUBLE_TO_FXPT_FREQ(100e6/R_DIV))
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
68 struct db_rfx_common {
79 struct db_rfx_common common;
83 struct db_rfx_400_rx {
85 struct db_rfx_common common;
88 struct db_rfx_400_tx {
90 struct db_rfx_common common;
93 struct db_rfx_900_rx {
95 struct db_rfx_common common;
98 struct db_rfx_900_tx {
100 struct db_rfx_common common;
103 struct db_rfx_1200_rx {
105 struct db_rfx_common common;
108 struct db_rfx_1200_tx {
110 struct db_rfx_common common;
113 struct db_rfx_1800_rx {
115 struct db_rfx_common common;
118 struct db_rfx_1800_tx {
120 struct db_rfx_common common;
123 struct db_rfx_2200_rx {
125 struct db_rfx_common common;
128 struct db_rfx_2200_tx {
130 struct db_rfx_common common;
133 struct db_rfx_2400_rx {
135 struct db_rfx_common common;
138 struct db_rfx_2400_tx {
140 struct db_rfx_common common;
145 * The class instances
147 struct db_rfx_400_rx db_rfx_400_rx = {
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,
174 .common.spi_mask = SPI_SS_RX_DB,
175 .common.freq_mult = 2
179 struct db_rfx_400_tx db_rfx_400_tx = {
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,
206 .common.spi_mask = SPI_SS_TX_DB,
207 .common.freq_mult = 2
210 struct db_rfx_900_rx db_rfx_900_rx = {
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,
230 .base.atr_rxval = MIX_EN,
231 // .base.atr_tx_delay =
232 // .base.atr_rx_delay =
233 .base.set_antenna = 0,
237 .common.spi_mask = SPI_SS_RX_DB,
238 .common.freq_mult = 2
242 struct db_rfx_900_tx db_rfx_900_tx = {
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,
269 .common.spi_mask = SPI_SS_TX_DB,
270 .common.freq_mult = 2
273 struct db_rfx_1200_rx db_rfx_1200_rx = {
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,
293 .base.atr_rxval = MIX_EN,
294 // .base.atr_tx_delay =
295 // .base.atr_rx_delay =
296 .base.set_antenna = 0,
300 .common.spi_mask = SPI_SS_RX_DB,
301 .common.freq_mult = 2
305 struct db_rfx_1200_tx db_rfx_1200_tx = {
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,
332 .common.spi_mask = SPI_SS_TX_DB,
333 .common.freq_mult = 2
336 struct db_rfx_1800_rx db_rfx_1800_rx = {
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,
356 .base.atr_rxval = MIX_EN,
357 // .base.atr_tx_delay =
358 // .base.atr_rx_delay =
359 .base.set_antenna = 0,
363 .common.spi_mask = SPI_SS_RX_DB,
364 .common.freq_mult = 1
368 struct db_rfx_1800_tx db_rfx_1800_tx = {
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,
395 .common.spi_mask = SPI_SS_TX_DB,
396 .common.freq_mult = 1
400 struct db_rfx_2200_rx db_rfx_2200_rx = {
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,
420 .base.atr_rxval = MIX_EN,
421 // .base.atr_tx_delay =
422 // .base.atr_rx_delay =
423 .base.set_antenna = 0,
427 .common.spi_mask = SPI_SS_RX_DB,
428 .common.freq_mult = 1
432 struct db_rfx_2200_tx db_rfx_2200_tx = {
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,
459 .common.spi_mask = SPI_SS_TX_DB,
460 .common.freq_mult = 1
464 struct db_rfx_2400_rx db_rfx_2400_rx = {
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,
484 .base.atr_rxval = MIX_EN,
485 // .base.atr_tx_delay =
486 // .base.atr_rx_delay =
487 .base.set_antenna = 0,
491 .common.spi_mask = SPI_SS_RX_DB,
492 .common.freq_mult = 1
496 struct db_rfx_2400_tx db_rfx_2400_tx = {
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,
523 .common.spi_mask = SPI_SS_TX_DB,
524 .common.freq_mult = 1
529 rfx_init_tx(struct db_base *dbb)
531 //struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
532 clocks_enable_tx_dboard(true, 0);
534 // Set the freq now to get the one time 10ms delay out of the way.
536 dbb->set_freq(dbb, dbb->freq_min, &dc);
541 rfx_init_rx(struct db_base *dbb)
543 //struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
544 clocks_enable_rx_dboard(true, 0);
547 dbb->set_gain(dbb,U2_DOUBLE_TO_FXPT_GAIN(45.0));
549 // Set the freq now to get the one time 10ms delay out of the way.
551 dbb->set_freq(dbb, dbb->freq_min, &dc);
557 rfx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc)
559 static unsigned char first = true;
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;
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;
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);
582 spi_transact(SPI_TXONLY,db->common.spi_mask,N,24,SPIF_PUSH_FALL);
584 //printf("A = %d, B = %d, N_DIV = %d\n",A, B, N_DIV);
585 *dc = (N_DIV * phdet_freq) / db->common.freq_mult;
590 rfx_set_gain_tx(struct db_base *dbb, u2_fxpt_gain_t gain)
592 // There is no analog gain control on TX
597 rfx_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain)
599 struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
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;
605 int dacword = ((slope_q8 * gain) + offset_q8)>>15;
606 //printf("DACWORD %d\n",dacword);
607 lsdac_write_rx(1,dacword);
613 rfx_set_tx_enable(struct db_base *dbb, bool on)
615 struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
623 rfx_lock_detect(struct db_base *dbb)
625 struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
627 pins = hal_gpio_read( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK );
628 if(pins & LOCKDET_MASK)
634 def select_rx_antenna(self, which_antenna):
636 Specify which antenna port to use for reception.
637 @param which_antenna: either 'TX/RX' or 'RX2'
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)
644 raise ValueError, "which_antenna must be either 'TX/RX' or 'RX2'"
646 def set_gain(self, gain):
650 @param gain: gain in decibels
653 maxgain = self.gain_range()[1] - self._u.pga_max()
654 mingain = self.gain_range()[0]
656 pga_gain = gain-maxgain
657 assert pga_gain <= self._u.pga_max()
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))
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