/* -*- c++ -*- */ /* * Copyright 2008,2009 Free Software Foundation, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #include #include #include #include #include bool tvrx_init(struct db_base *db); bool tvrx_set_freq(struct db_base *db, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc); bool tvrx_set_gain(struct db_base *db, u2_fxpt_gain_t gain); #define I2C_ADDR 0x60 #define ref_freq (U2_DOUBLE_TO_FXPT_FREQ(4e6)/640*8) #define ref_div 640 /* choices are 640, 512, 1024 */ #if (ref_div == 640) #define ref_div_byte 0 #else #if (ref_div == 512) #define ref_div_byte 0x6 #else #define ref_div_byte 0x2 #endif #endif #define fast_tuning 0x40 #define control_byte_1 (0x88|fast_tuning|ref_div_byte) struct db_tvrx_common { // TVRX common stuff u2_fxpt_freq_t first_if; u2_fxpt_freq_t second_if; }; struct db_tvrx_dummy { struct db_base base; struct db_tvrx_common common; }; struct db_tvrx1 { struct db_base base; struct db_tvrx_common common; }; struct db_tvrx2 { struct db_base base; struct db_tvrx_common common; }; struct db_tvrx3 { struct db_base base; struct db_tvrx_common common; }; /* The class instances */ struct db_tvrx1 db_tvrx1 = { .base.dbid = 0x0003, .base.is_tx = false, .base.output_enables = 0x0000, .base.used_pins = 0x0000, .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(50e6), .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(860e6), .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0), .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(95), .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(1), .base.is_quadrature = false, .base.i_and_q_swapped = false, .base.spectrum_inverted = false, .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = tvrx_init, .base.set_freq = tvrx_set_freq, .base.set_gain = tvrx_set_gain, .base.set_tx_enable = 0, .base.atr_mask = 0x0000, .base.atr_txval = 0, .base.atr_rxval = 0, // .base.atr_tx_delay = // .base.atr_rx_delay = .common.first_if = U2_DOUBLE_TO_FXPT_FREQ(43.75e6), .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(5.75e6), }; struct db_tvrx2 db_tvrx2 = { .base.dbid = 0x000c, .base.is_tx = false, .base.output_enables = 0x0000, .base.used_pins = 0x0000, .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(50e6), .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(860e6), .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0), .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(95), .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(1), .base.is_quadrature = false, .base.i_and_q_swapped = false, .base.spectrum_inverted = true, .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = tvrx_init, .base.set_freq = tvrx_set_freq, .base.set_gain = tvrx_set_gain, .base.set_tx_enable = 0, .base.atr_mask = 0x0000, .base.atr_txval = 0, .base.atr_rxval = 0, // .base.atr_tx_delay = // .base.atr_rx_delay = .common.first_if = U2_DOUBLE_TO_FXPT_FREQ(44e6), .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(44e6), }; struct db_tvrx3 db_tvrx3 = { .base.dbid = 0x0040, .base.is_tx = false, .base.output_enables = 0x0000, .base.used_pins = 0x0000, .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(50e6), .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(860e6), .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0), .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(95), .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(1), .base.is_quadrature = false, .base.i_and_q_swapped = false, .base.spectrum_inverted = true, .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0), .base.init = tvrx_init, .base.set_freq = tvrx_set_freq, .base.set_gain = tvrx_set_gain, .base.set_tx_enable = 0, .base.atr_mask = 0x0000, .base.atr_txval = 0, .base.atr_rxval = 0, // .base.atr_tx_delay = // .base.atr_rx_delay = .common.first_if = U2_DOUBLE_TO_FXPT_FREQ(44e6), .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(44e6), }; bool tvrx_init(struct db_base *dbb) { struct db_tvrx_dummy *db = (struct db_tvrx_dummy *) dbb; db->base.set_gain(dbb,U2_DOUBLE_TO_FXPT_GAIN(94.0)); return true; } bool tvrx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc) { *dc = 0; if (freq < dbb->freq_min || freq > dbb->freq_max) return false; struct db_tvrx_dummy *db = (struct db_tvrx_dummy *) dbb; u2_fxpt_freq_t target_lo_freq = freq + db->common.first_if; int N_DIV = u2_fxpt_freq_round_to_int(((1LL<<20) * target_lo_freq)/ref_freq); u2_fxpt_freq_t actual_lo_freq = ref_freq * N_DIV; u2_fxpt_freq_t actual_freq = actual_lo_freq - db->common.first_if; if(N_DIV > 32767) return false; if (0) printf("N_DIV = %d, actual_freq = %d, actual_lo_freq = %d\n", N_DIV, u2_fxpt_freq_round_to_int(actual_freq), u2_fxpt_freq_round_to_int(actual_lo_freq)); unsigned char buf[4]; buf[0] = (N_DIV>>8) & 0xff; buf[1] = N_DIV & 0xff; buf[2] = control_byte_1; buf[3] = (freq < U2_DOUBLE_TO_FXPT_FREQ(158e6)) ? 0xa8 : // VHF LOW (freq < U2_DOUBLE_TO_FXPT_FREQ(464e6)) ? 0x98 : // VHF HIGH 0x38; // UHF *dc = actual_freq - db->common.second_if; return i2c_write(I2C_ADDR,buf,4); } bool tvrx_set_gain(struct db_base *dbb, u2_fxpt_gain_t gain) { //struct db_tvrx_dummy *db = (struct db_tvrx_dummy *) dbb; int rfgain; int ifgain; if(gain>U2_DOUBLE_TO_FXPT_GAIN(95.0)) return false; if(gain<0) return false; if(gain>U2_DOUBLE_TO_FXPT_GAIN(60.0)) { rfgain = U2_DOUBLE_TO_FXPT_GAIN(60.0); ifgain = gain-U2_DOUBLE_TO_FXPT_GAIN(60.0); } else { rfgain = gain; ifgain = 0; } int rf_slope_q8 = 256 * 4096 * 2.5 / 60.0 / 1.22 / 3.3; int rf_offset_q8 = 128 * 256 * 4096 * 1.25 / 1.22 / 3.3; int if_slope_q8 = 256 * 4096 * 2.25 / 35.0 / 1.22 / 3.3; int if_offset_q8 = 128 * 256 * 4096 * 1.4 / 1.22 / 3.3; int rfdac = (rfgain*rf_slope_q8 + rf_offset_q8)>>15; int ifdac = (ifgain*if_slope_q8 + if_offset_q8)>>15; lsdac_write_rx(0,rfdac); lsdac_write_rx(1,ifdac); if (0) printf("Setting gain %d, rf %d, if %d\n",gain,rfdac,ifdac); return true; } bool tvrx_lock_detect(struct db_base *dbb) { // struct db_tvrx_dummy *db = (struct db_tvrx_dummy *) dbb; return true; }