2 * Copyright 2008 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>
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);
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
50 #define DIVSEL 0 // N Counter always operates on full rate
61 #define phdet_freq (U2_DOUBLE_TO_FXPT_FREQ(100e6/R_DIV))
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
69 struct db_rfx_common {
80 struct db_rfx_common common;
84 struct db_rfx_400_rx {
86 struct db_rfx_common common;
89 struct db_rfx_400_tx {
91 struct db_rfx_common common;
94 struct db_rfx_900_rx {
96 struct db_rfx_common common;
99 struct db_rfx_900_tx {
101 struct db_rfx_common common;
104 struct db_rfx_1200_rx {
106 struct db_rfx_common common;
109 struct db_rfx_1200_tx {
111 struct db_rfx_common common;
114 struct db_rfx_1800_rx {
116 struct db_rfx_common common;
119 struct db_rfx_1800_tx {
121 struct db_rfx_common common;
124 struct db_rfx_2400_rx {
126 struct db_rfx_common common;
129 struct db_rfx_2400_tx {
131 struct db_rfx_common common;
136 * The class instances
138 struct db_rfx_400_rx db_rfx_400_rx = {
141 .base.output_enables = 0x00E0,
142 .base.used_pins = 0x00FF,
143 //.base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(xxx),
144 //.base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(xxx),
145 //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
146 //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
147 //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
148 .base.is_quadrature = true,
149 .base.i_and_q_swapped = false,
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 =
164 .common.spi_mask = SPI_SS_RX_DB,
165 .common.freq_mult = 2
169 struct db_rfx_400_tx db_rfx_400_tx = {
172 .base.output_enables = 0x00E0,
173 .base.used_pins = 0x00FF,
174 //.base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(xxx),
175 //.base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(xxx),
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 = false,
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 =
195 .common.spi_mask = SPI_SS_TX_DB,
196 .common.freq_mult = 2
199 struct db_rfx_900_rx db_rfx_900_rx = {
202 .base.output_enables = 0x00E0,
203 .base.used_pins = 0x00FF,
204 //.base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(xxx),
205 //.base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(xxx),
206 //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
207 //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
208 //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
209 .base.is_quadrature = true,
210 .base.i_and_q_swapped = false,
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,
219 .base.atr_rxval = MIX_EN,
220 // .base.atr_tx_delay =
221 // .base.atr_rx_delay =
225 .common.spi_mask = SPI_SS_RX_DB,
226 .common.freq_mult = 2
230 struct db_rfx_900_tx db_rfx_900_tx = {
233 .base.output_enables = 0x00E0,
234 .base.used_pins = 0x00FF,
235 //.base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(xxx),
236 //.base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(xxx),
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 = false,
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 =
256 .common.spi_mask = SPI_SS_TX_DB,
257 .common.freq_mult = 2
260 struct db_rfx_1200_rx db_rfx_1200_rx = {
263 .base.output_enables = 0x00E0,
264 .base.used_pins = 0x00FF,
265 //.base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(xxx),
266 //.base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(xxx),
267 //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
268 //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
269 //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
270 .base.is_quadrature = true,
271 .base.i_and_q_swapped = false,
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,
280 .base.atr_rxval = MIX_EN,
281 // .base.atr_tx_delay =
282 // .base.atr_rx_delay =
286 .common.spi_mask = SPI_SS_RX_DB,
287 .common.freq_mult = 2
291 struct db_rfx_1200_tx db_rfx_1200_tx = {
294 .base.output_enables = 0x00E0,
295 .base.used_pins = 0x00FF,
296 //.base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(xxx),
297 //.base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(xxx),
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 = false,
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 =
317 .common.spi_mask = SPI_SS_TX_DB,
318 .common.freq_mult = 2
321 struct db_rfx_1800_rx db_rfx_1800_rx = {
324 .base.output_enables = 0x00E0,
325 .base.used_pins = 0x00FF,
326 //.base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(xxx),
327 //.base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(xxx),
328 //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
329 //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
330 //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
331 .base.is_quadrature = true,
332 .base.i_and_q_swapped = false,
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,
341 .base.atr_rxval = MIX_EN,
342 // .base.atr_tx_delay =
343 // .base.atr_rx_delay =
347 .common.spi_mask = SPI_SS_RX_DB,
348 .common.freq_mult = 1
352 struct db_rfx_1800_tx db_rfx_1800_tx = {
355 .base.output_enables = 0x00E0,
356 .base.used_pins = 0x00FF,
357 //.base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(xxx),
358 //.base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(xxx),
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 = false,
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 =
378 .common.spi_mask = SPI_SS_TX_DB,
379 .common.freq_mult = 1
383 struct db_rfx_2400_rx db_rfx_2400_rx = {
386 .base.output_enables = 0x00E0,
387 .base.used_pins = 0x00FF,
388 //.base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(xxx),
389 //.base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(xxx),
390 //.base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(xxx),
391 //.base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(xxx),
392 //.base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(xxx),
393 .base.is_quadrature = true,
394 .base.i_and_q_swapped = false,
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,
403 .base.atr_rxval = MIX_EN,
404 // .base.atr_tx_delay =
405 // .base.atr_rx_delay =
409 .common.spi_mask = SPI_SS_RX_DB,
410 .common.freq_mult = 1
414 struct db_rfx_2400_tx db_rfx_2400_tx = {
417 .base.output_enables = 0x00E0,
418 .base.used_pins = 0x00FF,
419 //.base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(xxx),
420 //.base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(xxx),
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 = false,
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 =
440 .common.spi_mask = SPI_SS_TX_DB,
441 .common.freq_mult = 1
446 rfx_init_tx(struct db_base *dbb)
448 //struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
449 clocks_enable_tx_dboard(true, 0);
454 rfx_init_rx(struct db_base *dbb)
456 //struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
457 clocks_enable_rx_dboard(true, 0);
460 dbb->set_gain(dbb,U2_DOUBLE_TO_FXPT_GAIN(45.0));
461 printf("set the gain\n");
466 rfx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc)
469 struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
470 //u2_fxpt_freq_t desired_n = db->common.freq_mult*freq/phdet_freq;
471 //int N_DIV = u2_fxpt_freq_round_to_int(desired_n);
472 u2_fxpt_freq_t desired_n = ((1LL<<20) * db->common.freq_mult*freq)/phdet_freq;
473 int N_DIV = u2_fxpt_freq_round_to_int(desired_n);
474 int B = N_DIV/PRESCALER;
475 int A = N_DIV - PRESCALER*B;
480 int R = (R_RSV<<22)|(R_BSC<<20)|(R_TMB<<19)|(R_LDP<<18)|(R_ABP<<16)|(R_DIV<<2)|1;
481 int N = (DIVSEL<<23)|(db->common.DIV2<<22)|(CPGAIN<<21)|(B<<8)|(N_RSV<<7)|(A<<2)|2;
482 int C = (P<<22)|(PD<<20)|(db->common.CP2<<17)|(db->common.CP1<<14)|(PL<<12)|
483 (MTLD<<11)|(CPGAIN<<10)|(CP3S<<9)|(PDP<<8)|(MUXOUT<<5)|(CR<<4)|(PC<<2)|0;
485 spi_transact(SPI_TXONLY,db->common.spi_mask,R,24,SPIF_PUSH_FALL);
486 spi_transact(SPI_TXONLY,db->common.spi_mask,C,24,SPIF_PUSH_FALL);
488 spi_transact(SPI_TXONLY,db->common.spi_mask,N,24,SPIF_PUSH_FALL);
490 printf("A = %d, B = %d, N_DIV = %d\n",A, B, N_DIV);
491 *dc = (N_DIV * phdet_freq) / db->common.freq_mult;
496 rfx_set_gain_tx(struct db_base *dbb, u2_fxpt_gain_t gain)
498 // There is no analog gain control on TX
503 rfx_set_gain_rx(struct db_base *dbb, u2_fxpt_gain_t gain)
505 struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
507 u2_fxpt_gain_t MAXGAIN = U2_DOUBLE_TO_FXPT_GAIN(70.0);
509 int offset_q8 = (int)(1.2/3.3*4096*(1<<15));
510 int slope_q8 = (int)(-1.0/45.0*4096/3.3*256);
511 int dacword = ((slope_q8 * gain) + offset_q8)>>15;
512 printf("DACWORD %d\n",dacword);
513 lsdac_write_rx(1,dacword);
516 def set_gain(self, gain):
520 @param gain: gain in decibels
523 maxgain = self.gain_range()[1] - self._u.pga_max()
524 mingain = self.gain_range()[0]
526 pga_gain = gain-maxgain
527 assert pga_gain <= self._u.pga_max()
535 dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale
536 assert dac_value>=0 and dac_value<4096
537 return self._u.write_aux_dac(self._which, 0, int(dac_value)) and \
538 self._set_pga(int(pga_gain))
540 def gain_range(self):
541 return (self._u.pga_min(), self._u.pga_max() + 70, 0.05) -- For 900-2400
542 return (self._u.pga_min(), self._u.pga_max() + 45, 0.035) -- For 400
548 rfx_set_tx_enable(struct db_base *dbb, bool on)
550 struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
558 rfx_lock_detect(struct db_base *dbb)
560 struct db_rfx_dummy *db = (struct db_rfx_dummy *) dbb;
562 pins = hal_gpio_read( db->base.is_tx ? GPIO_TX_BANK : GPIO_RX_BANK );
563 if(pins & LOCKDET_MASK)
569 def select_rx_antenna(self, which_antenna):
571 Specify which antenna port to use for reception.
572 @param which_antenna: either 'TX/RX' or 'RX2'
574 if which_antenna in (0, 'TX/RX'):
575 self._u.write_io(self._which, 0, RX2_RX1N)
576 elif which_antenna in (1, 'RX2'):
577 self._u.write_io(self._which, RX2_RX1N, RX2_RX1N)
579 raise ValueError, "which_antenna must be either 'TX/RX' or 'RX2'"
581 def set_gain(self, gain):
585 @param gain: gain in decibels
588 maxgain = self.gain_range()[1] - self._u.pga_max()
589 mingain = self.gain_range()[0]
591 pga_gain = gain-maxgain
592 assert pga_gain <= self._u.pga_max()
600 dac_value = (agc_gain*(V_maxgain-V_mingain)/(maxgain-mingain) + V_mingain)*4096/V_fullscale
601 assert dac_value>=0 and dac_value<4096
602 return self._u.write_aux_dac(self._which, 0, int(dac_value)) and \
603 self._set_pga(int(pga_gain))
605 def gain_range(self):
606 return (self._u.pga_min(), self._u.pga_max() + 70, 0.05) -- For 900-2400
607 return (self._u.pga_min(), self._u.pga_max() + 45, 0.035) -- For 400