3 * Copyright 2008,2009 Free Software Foundation, Inc.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include <memory_map.h>
26 bool tvrx_init(struct db_base *db);
27 bool tvrx_set_freq(struct db_base *db, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc);
28 bool tvrx_set_gain(struct db_base *db, u2_fxpt_gain_t gain);
31 #define REF_FREQ (U2_DOUBLE_TO_FXPT_FREQ(4e6)/640*8)
33 #define ref_div 640 /* choices are 640, 512, 1024 */
36 #define ref_div_byte 0
39 #define ref_div_byte 0x6
41 #define ref_div_byte 0x2
45 #define fast_tuning 0x40
47 #define control_byte_1 (0x88|fast_tuning|ref_div_byte)
50 struct db_tvrx_common {
52 u2_fxpt_freq_t first_if;
53 u2_fxpt_freq_t second_if;
56 struct db_tvrx_dummy {
58 struct db_tvrx_common common;
63 struct db_tvrx_common common;
68 struct db_tvrx_common common;
73 struct db_tvrx_common common;
76 /* The class instances */
77 struct db_tvrx1 db_tvrx1 = {
80 .base.output_enables = 0x0000,
81 .base.used_pins = 0x0000,
82 .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(50e6),
83 .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(860e6),
84 .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
85 .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(95),
86 .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(1),
87 .base.is_quadrature = false,
88 .base.i_and_q_swapped = false,
89 .base.spectrum_inverted = false,
90 .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
91 .base.init = tvrx_init,
92 .base.set_freq = tvrx_set_freq,
93 .base.set_gain = tvrx_set_gain,
94 .base.set_tx_enable = 0,
95 .base.atr_mask = 0x0000,
98 // .base.atr_tx_delay =
99 // .base.atr_rx_delay =
100 .common.first_if = U2_DOUBLE_TO_FXPT_FREQ(43.75e6),
101 .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(5.75e6),
105 struct db_tvrx2 db_tvrx2 = {
108 .base.output_enables = 0x0000,
109 .base.used_pins = 0x0000,
110 .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(50e6),
111 .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(860e6),
112 .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
113 .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(95),
114 .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(1),
115 .base.is_quadrature = false,
116 .base.i_and_q_swapped = false,
117 .base.spectrum_inverted = false,
118 .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
119 .base.init = tvrx_init,
120 .base.set_freq = tvrx_set_freq,
121 .base.set_gain = tvrx_set_gain,
122 .base.set_tx_enable = 0,
123 .base.atr_mask = 0x0000,
126 // .base.atr_tx_delay =
127 // .base.atr_rx_delay =
128 .common.first_if = U2_DOUBLE_TO_FXPT_FREQ(44e6),
129 .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(56e6), // Fs - 44e6
133 struct db_tvrx3 db_tvrx3 = {
136 .base.output_enables = 0x0000,
137 .base.used_pins = 0x0000,
138 .base.freq_min = U2_DOUBLE_TO_FXPT_FREQ(50e6),
139 .base.freq_max = U2_DOUBLE_TO_FXPT_FREQ(860e6),
140 .base.gain_min = U2_DOUBLE_TO_FXPT_GAIN(0),
141 .base.gain_max = U2_DOUBLE_TO_FXPT_GAIN(95),
142 .base.gain_step_size = U2_DOUBLE_TO_FXPT_GAIN(1),
143 .base.is_quadrature = false,
144 .base.i_and_q_swapped = false,
145 .base.spectrum_inverted = false,
146 .base.default_lo_offset = U2_DOUBLE_TO_FXPT_FREQ(0),
147 .base.init = tvrx_init,
148 .base.set_freq = tvrx_set_freq,
149 .base.set_gain = tvrx_set_gain,
150 .base.set_tx_enable = 0,
151 .base.atr_mask = 0x0000,
154 // .base.atr_tx_delay =
155 // .base.atr_rx_delay =
156 .common.first_if = U2_DOUBLE_TO_FXPT_FREQ(44e6),
157 .common.second_if = U2_DOUBLE_TO_FXPT_FREQ(56e6), // Fs - 44e6
161 tvrx_init(struct db_base *dbb)
163 struct db_tvrx_dummy *db = (struct db_tvrx_dummy *) dbb;
164 db->base.set_gain(dbb,U2_DOUBLE_TO_FXPT_GAIN(94.0));
169 tvrx_set_freq(struct db_base *dbb, u2_fxpt_freq_t freq, u2_fxpt_freq_t *dc)
172 if (freq < dbb->freq_min || freq > dbb->freq_max)
175 struct db_tvrx_dummy *db = (struct db_tvrx_dummy *) dbb;
177 u2_fxpt_freq_t target_lo_freq = freq + db->common.first_if;
178 int n_div = u2_fxpt_freq_round_to_int(((1LL<<20) * target_lo_freq)/REF_FREQ);
180 u2_fxpt_freq_t actual_lo_freq = REF_FREQ * n_div;
181 u2_fxpt_freq_t actual_freq = actual_lo_freq - db->common.first_if;
186 printf("n_div = %d, actual_freq = %d, actual_lo_freq = %d\n",
187 n_div, u2_fxpt_freq_round_to_int(actual_freq),
188 u2_fxpt_freq_round_to_int(actual_lo_freq));
190 unsigned char buf[4];
191 buf[0] = (n_div>>8) & 0xff;
192 buf[1] = n_div & 0xff;
193 buf[2] = control_byte_1;
194 buf[3] = ((actual_freq < U2_DOUBLE_TO_FXPT_FREQ(158e6)) ? 0xa8 : // VHF LOW
195 (actual_freq < U2_DOUBLE_TO_FXPT_FREQ(464e6)) ? 0x98 : // VHF HIGH
198 *dc = actual_freq - db->common.second_if;
199 return i2c_write(I2C_ADDR,buf,4);
203 tvrx_set_gain(struct db_base *dbb, u2_fxpt_gain_t gain)
205 //struct db_tvrx_dummy *db = (struct db_tvrx_dummy *) dbb;
208 if(gain>U2_DOUBLE_TO_FXPT_GAIN(95.0))
213 if(gain>U2_DOUBLE_TO_FXPT_GAIN(60.0)) {
214 rfgain = U2_DOUBLE_TO_FXPT_GAIN(60.0);
215 ifgain = gain-U2_DOUBLE_TO_FXPT_GAIN(60.0);
221 int rf_slope_q8 = 256 * 4096 * 2.5 / 60.0 / 1.22 / 3.3;
222 int rf_offset_q8 = 128 * 256 * 4096 * 1.25 / 1.22 / 3.3;
223 int if_slope_q8 = 256 * 4096 * 2.25 / 35.0 / 1.22 / 3.3;
224 int if_offset_q8 = 128 * 256 * 4096 * 1.4 / 1.22 / 3.3;
227 int rfdac = (rfgain*rf_slope_q8 + rf_offset_q8)>>15;
228 int ifdac = (ifgain*if_slope_q8 + if_offset_q8)>>15;
229 lsdac_write_rx(0,rfdac);
230 lsdac_write_rx(1,ifdac);
233 printf("Setting gain %d, rf %d, if %d\n",gain,rfdac,ifdac);
240 tvrx_lock_detect(struct db_base *dbb)
242 // struct db_tvrx_dummy *db = (struct db_tvrx_dummy *) dbb;