mirror of
https://github.com/rtlsdrblog/rtl-sdr-blog.git
synced 2025-02-28 18:04:09 +01:00
FC0012 doc and fixes
Fix selection of VCO band (needed for example to get to 166 MHz) for the FC0012 tuner, and add a lot of register descriptions. Signed-Off-by: Michael Karcher <osmosdr@mkarcher.dialup.fu-berlin.de> Signed-off-by: Steve Markgraf <steve@steve-m.de>
This commit is contained in:
parent
6328438479
commit
c4c48a69ea
@ -20,21 +20,35 @@
|
|||||||
/* Incomplete list of register settings:
|
/* Incomplete list of register settings:
|
||||||
*
|
*
|
||||||
* Name Reg Bits Desc
|
* Name Reg Bits Desc
|
||||||
|
* CHIP_ID 0x00 0-7 Chip ID (constant 0xA1)
|
||||||
|
* RF_A 0x01 0-3 Number of count-to-9 cycles in RF
|
||||||
|
* divider (suggested: 2..9)
|
||||||
|
* RF_M 0x02 0-7 Total number of cycles (to-8 and to-9)
|
||||||
|
* in RF divider
|
||||||
|
* RF_K_HIGH 0x03 0-6 Bits 8..14 of fractional divider
|
||||||
|
* RF_K_LOW 0x04 0-7 Bits 0..7 of fractional RF divider
|
||||||
|
* RF_OUTDIV_A 0x05 3-7 Power of two required?
|
||||||
* LNA_POWER_DOWN 0x06 0 Set to 1 to switch off low noise amp
|
* LNA_POWER_DOWN 0x06 0 Set to 1 to switch off low noise amp
|
||||||
* VCO_SPEED 0x06 3 Set the speed of the VCO. example
|
* RF_OUTDIV_B 0x06 1 Set to select 3 instead of 2 for the
|
||||||
* driver hardcodes to 1 for some reason
|
* RF output divider
|
||||||
|
* VCO_SPEED 0x06 3 Select tuning range of VCO:
|
||||||
|
* 0 = Low range, (ca. 1.1 - 1.5GHz)
|
||||||
|
* 1 = High range (ca. 1.4 - 1.8GHz)
|
||||||
* BANDWIDTH 0x06 6-7 Set bandwidth. 6MHz = 0x80, 7MHz=0x40
|
* BANDWIDTH 0x06 6-7 Set bandwidth. 6MHz = 0x80, 7MHz=0x40
|
||||||
* 8MHz=0x00
|
* 8MHz=0x00
|
||||||
* XTAL_SPEED 0x07 5 Set to 1 for 28.8MHz Crystal input
|
* XTAL_SPEED 0x07 5 Set to 1 for 28.8MHz Crystal input
|
||||||
* or 0 for 36MHz
|
* or 0 for 36MHz
|
||||||
|
* <agc params> 0x08 0-7
|
||||||
* EN_CAL_RSSI 0x09 4 Enable calibrate RSSI
|
* EN_CAL_RSSI 0x09 4 Enable calibrate RSSI
|
||||||
* (Receive Signal Strength Indicator)
|
* (Receive Signal Strength Indicator)
|
||||||
* LNA_FORCE 0x0d 0
|
* LNA_FORCE 0x0d 0
|
||||||
* AGC_FORCE 0x0d ?
|
* AGC_FORCE 0x0d ?
|
||||||
* LNA_GAIN 0x13 0-4 Low noise amp gain
|
* LNA_GAIN 0x13 3-4 Low noise amp gain
|
||||||
* LNA_COMPS 0x15 3 ?
|
* LNA_COMPS 0x15 3 ?
|
||||||
* VCO_CALIB 0x0e 7 Set high then low to calibrate VCO
|
* VCO_CALIB 0x0e 7 Set high then low to calibrate VCO
|
||||||
*
|
* (fast lock?)
|
||||||
|
* VCO_VOLTAGE 0x0e 0-6 Read Control voltage of VCO
|
||||||
|
* (big value -> low freq)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* glue functions to rtl-sdr code */
|
/* glue functions to rtl-sdr code */
|
||||||
@ -99,12 +113,11 @@ void FC0012_Dump_Registers()
|
|||||||
DEBUGF("LNA Force:\t%s\n", (regBuf & 0x1) ? "Forced" : "Not Forced");
|
DEBUGF("LNA Force:\t%s\n", (regBuf & 0x1) ? "Forced" : "Not Forced");
|
||||||
FC0012_Read(pTuner, 0x13, ®Buf);
|
FC0012_Read(pTuner, 0x13, ®Buf);
|
||||||
DEBUGF("LNA Gain:\t");
|
DEBUGF("LNA Gain:\t");
|
||||||
switch (regBuf) {
|
switch (regBuf & 0x18) {
|
||||||
case (0x10): DEBUGF("19.7dB\n"); break;
|
case (0x00): DEBUGF("Low\n"); break;
|
||||||
case (0x17): DEBUGF("17.9dB\n"); break;
|
case (0x08): DEBUGF("Middle\n"); break;
|
||||||
case (0x08): DEBUGF("7.1dB\n"); break;
|
case (0x10): DEBUGF("High\n"); break;
|
||||||
case (0x02): DEBUGF("-9.9dB\n"); break;
|
default: DEBUGF("unknown gain value 0x18\n");
|
||||||
default: DEBUGF("unknown gain value 0x02x\n");
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -173,7 +186,7 @@ void FC0012_Frequency_Control(unsigned int Frequency, unsigned short Bandwidth)
|
|||||||
|
|
||||||
int FC0012_SetFrequency(void *pTuner, unsigned long Frequency, unsigned short Bandwidth)
|
int FC0012_SetFrequency(void *pTuner, unsigned long Frequency, unsigned short Bandwidth)
|
||||||
{
|
{
|
||||||
int VCO1 = 0;
|
int VCO_band = 0;
|
||||||
unsigned long doubleVCO;
|
unsigned long doubleVCO;
|
||||||
unsigned short xin, xdiv;
|
unsigned short xin, xdiv;
|
||||||
unsigned char reg[21], am, pm, multi;
|
unsigned char reg[21], am, pm, multi;
|
||||||
@ -230,7 +243,7 @@ int FC0012_SetFrequency(void *pTuner, unsigned long Frequency, unsigned short Ba
|
|||||||
doubleVCO = Frequency * multi;
|
doubleVCO = Frequency * multi;
|
||||||
|
|
||||||
reg[6] = reg[6] | 0x08;
|
reg[6] = reg[6] | 0x08;
|
||||||
VCO1 = 1;
|
VCO_band = 1;
|
||||||
xdiv = (unsigned short)(doubleVCO / (CrystalFreqKhz / 2));
|
xdiv = (unsigned short)(doubleVCO / (CrystalFreqKhz / 2));
|
||||||
if( (doubleVCO - xdiv * (CrystalFreqKhz / 2)) >= (CrystalFreqKhz / 4) )
|
if( (doubleVCO - xdiv * (CrystalFreqKhz / 2)) >= (CrystalFreqKhz / 4) )
|
||||||
xdiv = xdiv + 1;
|
xdiv = xdiv + 1;
|
||||||
@ -269,7 +282,6 @@ int FC0012_SetFrequency(void *pTuner, unsigned long Frequency, unsigned short Ba
|
|||||||
if (FC0012_Write(pTuner, 0x03, reg[3])) return -1;
|
if (FC0012_Write(pTuner, 0x03, reg[3])) return -1;
|
||||||
if (FC0012_Write(pTuner, 0x04, reg[4])) return -1;
|
if (FC0012_Write(pTuner, 0x04, reg[4])) return -1;
|
||||||
//reg[5] = reg[5] | 0x07; // This is really not cool. Why is it there?
|
//reg[5] = reg[5] | 0x07; // This is really not cool. Why is it there?
|
||||||
// Same with hardcoding VCO=1
|
|
||||||
if (FC0012_Write(pTuner, 0x05, reg[5])) return -1;
|
if (FC0012_Write(pTuner, 0x05, reg[5])) return -1;
|
||||||
if (FC0012_Write(pTuner, 0x06, reg[6])) return -1;
|
if (FC0012_Write(pTuner, 0x06, reg[6])) return -1;
|
||||||
|
|
||||||
@ -277,16 +289,19 @@ int FC0012_SetFrequency(void *pTuner, unsigned long Frequency, unsigned short Ba
|
|||||||
if (FC0012_Write(pTuner, 0x0E, 0x80)) return -1;
|
if (FC0012_Write(pTuner, 0x0E, 0x80)) return -1;
|
||||||
if (FC0012_Write(pTuner, 0x0E, 0x00)) return -1;
|
if (FC0012_Write(pTuner, 0x0E, 0x00)) return -1;
|
||||||
|
|
||||||
// VCO Re-Calibration if needed
|
// Read resulting VCO control voltage
|
||||||
if (FC0012_Write(pTuner, 0x0E, 0x00)) return -1;
|
if (FC0012_Write(pTuner, 0x0E, 0x00)) return -1;
|
||||||
if (FC0012_Read(pTuner, 0x0E, &read_byte)) return -1;
|
if (FC0012_Read(pTuner, 0x0E, &read_byte)) return -1;
|
||||||
reg[14] = 0x3F & read_byte;
|
reg[14] = 0x3F & read_byte;
|
||||||
|
|
||||||
if (VCO1)
|
// Adjust VCO range if control voltage is at the limit
|
||||||
|
if (VCO_band)
|
||||||
{
|
{
|
||||||
|
// high-band VCO hitting low frequency bound
|
||||||
if (reg[14] > 0x3C)
|
if (reg[14] > 0x3C)
|
||||||
{
|
{
|
||||||
reg[6] = 0x08 | reg[6];
|
// select low-band VCO
|
||||||
|
reg[6] = ~0x08 & reg[6];
|
||||||
|
|
||||||
if (FC0012_Write(pTuner, 0x06, reg[6])) return -1;
|
if (FC0012_Write(pTuner, 0x06, reg[6])) return -1;
|
||||||
if (FC0012_Write(pTuner, 0x0E, 0x80)) return -1;
|
if (FC0012_Write(pTuner, 0x0E, 0x80)) return -1;
|
||||||
@ -295,7 +310,9 @@ int FC0012_SetFrequency(void *pTuner, unsigned long Frequency, unsigned short Ba
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// low-band VCO hitting high frequency bound
|
||||||
if (reg[14] < 0x02) {
|
if (reg[14] < 0x02) {
|
||||||
|
// select high-band VCO
|
||||||
reg[6] = 0x08 | reg[6];
|
reg[6] = 0x08 | reg[6];
|
||||||
|
|
||||||
if (FC0012_Write(pTuner, 0x06, reg[6])) return -1;
|
if (FC0012_Write(pTuner, 0x06, reg[6])) return -1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user