📄 rf4kcclib.c
字号:
/* RF44KCCLib.c */
/****************************************************************************************************************
*****************************************************************************************************************
** **
** (C) Copyright 2005 RF Magic Inc., All rights reserved **
** **
** The information presented here is subject to the RF Magic License agreement. It is "RF Magic Confidential" **
** and therefore subject to corporate Non Disclosure Agreements. The software is believed to be accurate and **
** reliable and may be changed at any time without notice. RF Magic does not warrant the accuracy or **
** completeness of this software nor documents describing this software. Furthermore, information provided **
** herein covers RF Magic products only. RF Magic is not responsible for any circuitry used with RF Magic **
** products. RF Magic assumes no liability whatsoever for this information except as may be provided in **
** RF Magic's Terms and Conditions of Sale or other negotiated and signed agreements. **
** **
** No circuit licenses or patent licenses, express or implied, by estoppels or otherwise, to any intellectual **
** property rights, is granted by this software or documentation. **
** **
*****************************************************************************************************************
****************************************************************************************************************/
/* NOTE: This is a "library" of functions that are used to communicate with the
RF4000 device. Each of the functions is described by comments associated with
the function, however, there is a general scheme. The functions all return an
integer where the value of zero indicates an "OK" return; that is, one without
/ errors. If an error occurs, there will be a return value greater than zero,
/ and the value may contain error type content.
/
/
/ Ver 1.0.0: JW Huss 02/09/06
/ This version has been created from version 1.5 of the "RF4kCCLib" library.
/ It has been modified specifically to operate in the "STAPI" environment of
/ STMicroelectronics.*/
#include "stcommon.h"
#include "ioreg.h"
#include "tuntdrv.h" /* header for this file */
#include "RF4KCCLib.h"
#if defined (ST_OS21) || defined(ST_OSLINUX)
#define rf4kDelay(X) task_delay( (signed int)(X * (ST_GetClocksPerSecond() / 1000)) ) /*task_delay(X)*/
#else
#define rf4kDelay(X) task_delay( (unsigned int)(X * (ST_GetClocksPerSecond() / 1000)) ) /*task_delay(X)*/
#endif
U16 RF4000_Address[RF4000_NBREGS]={
0x0,
0x1,
0x2,
0x3,
0x4,
0x5,
0x6,
0x7,
0x8,
0x9,
0xa,
0xb,
0xc,
0xd,
0xe,
0xf,
0x10,
0x11,
0x12,
0x13,
0x14,
0x15,
0x16,
0x17,
0x18,
0x19,
0x1a,
0x1b,
0x1c,
0x1d,
0x1e,
0x1f,
0x20,
0x21,
0x22,
0x23,
0x24,
0x25,
0x26,
0x27,
0x28,
0x29,
0x2a,
0x2b,
0x2c,
0x2d,
0x2e,
0x2f,
0x30,
0x31,
0x32,
0x33,
0x34,
0x35,
0x36,
0x37,
0x38,
0x39,
0x3a,
0x3b,
0x3c,
0x3d,
0x3e,
0x3f,
0x40,
0x41,
0x42,
0x43,
0x44,
0x45,
0x46,
0x47,
0x48,
0x49,
0x4a,
0x4b,
0x4c
};
/* The following array contains a set of frequency values that are
used to develop the table of f0ctrl values during the power-up.
The frequencies follow the "FChannel" table in so much as the
"bands" change with frequency. Thus, the end points of the band
must appear, but be less than the actual value for the next band.
this will insure that there will be a proper point available for
for the linear interpolation that will take place between frequencies
in order to determine the correct f0ctrl to use in the channel change.
In addition, the table is now an array of structures
that contain the frequency and a default f0ctrl value. The
default f0ctrl value is used in the event of an LNA Cal error,
to allow a "soft landing" for the user.*/
f0ctrlFreqs_td f0ctrlFreqs[NBR_F0CTRL] = {
{ 150000000, 58, 0 },
{ 200000000, 43, 0 },
{ 250000000, 31, 0 },
{ 300000000, 20, 0 },
{ 350000000, 11, 0 },
{ 399999000, 3, 0 },
{ 400000000, 29, 0 },
{ 450000000, 25, 0 },
{ 500000000, 22, 0 },
{ 550000000, 18, 0 },
{ 600000000, 15, 0 },
{ 650000000, 12, 0 },
{ 700000000, 10, 0 },
{ 750000000, 8, 0 },
{ 800000000, 5, 0 },
{ MAX_FREQ, 3, 0 }
};
tableFLOCF_td tableFLOCF[tableFLOCF_LEN] = {
{ 26875000, 53750000, 64, 1, 7, 1 },
{ 53750000, 107500000, 32, 1, 6, 1 },
{ 107500000, 215000000, 16, 1, 2, 1 },
{ 215000000, 430000000, 8, 2, 3, 0 },
{ 430000000, 860000000, 4, 4, 1, 0 }
};
/* The values in this table are slightly modified from
the spec so that there will be no "gaps": the min frequency
is now placed into the max frequency of the previous entry.
The compare is now based as follows: minN <= N < maxN, and
a separate test will be made for the last maxN.*/
tableNRVSNC_td tableNRVSNC[tableNRVSNC_LEN] = {
{ 1456, 2433, 0 },
{ 2433, 3441, 1 },
{ 3441, 4866, 2 },
{ 4866, 6880, 3 }
};
tableVCOSVFR_td tableVCOSVFR[TABLEVCOSVFR_LEN] = {
{ 1617000000, 1745000000, 1 },
{ 1745000000, 1872000000, 2 },
{ 1872000000, 2029000000, 3 },
{ 2029000000, 2117000000, 5 },
{ 2117000000, 2264000000, 6 },
{ 2264000000, 2421000000, 7 },
{ 2421000000, 2500000000, 9 },
{ 2500000000, 2647000000, 10 },
{ 2647000000, 2804000000, 11 },
{ 2804000000, 2892000000, 13 },
{ 2892000000, 3020000000, 14 },
{ 3020000000, 3166000000, 15 },
{ 3166000000, 3245000000, 17 },
{ 3245000000, 3382000000, 18 },
{ 3382000000, 3520000000, 19 }
};
tableLNACS_td tableLNACS[TABLELNACS_LEN] = {
{ 150000000, 300000000, 0, 0, 0, 1, 2, 1 },
{ 300000000, 375000000, 1, 0, 0, 1, 2, 1 },
{ 375000000, 400000000, 1, 0, 0, 1, 2, 1 },
{ 400000000, 650000000, 0, 0, 0, 2, 3, 2 },
{ 650000000, 750000000, 1, 0, 0, 2, 3, 2 },
{ 750000000, 862000000, 1, 0, 0, 2, 3, 2 }
};
tableWVCCFR_td tableWVCCFR_22[tableFLOCF_LEN] = {
{ 5, 0x8, 0x2 }, /* A narrow 6 for adjacent band interference (2.600).*/
{ 6, 0x9, 0xd }, /* Set for 6 MHz width (2.794).*/
{ 7, 0xa, 0x2 }, /*/ Set for 7 MHz width (3.257).*/
{ 8, 0xc, 0x5 } /* Set for 8 MHz width (3.737).*/
};
/* Table for 24 MHz crystal frequency ( IF = 36 ).*/
tableWVCCFR_td tableWVCCFR_24[tableFLOCF_LEN] = {
{ 5, 0x7, 0x0 }, /* A narrow 6 for adjacent band interference (2.600).*/
{ 6, 0x8, 0x6 }, /* Set for 6 MHz width (2.794).*/
{ 7, 0x9, 0x8 }, /* Set for 7 MHz width (3.257).*/
{ 8, 0xb, 0x5 } /* Set for 8 MHz width (3.737).*/
};
/* DUT "Chip On" default register values.
These register values are to be written directly to the chip without
the need for "or'ing" into current register values.
Table values brought up to "reg map" ver 0.30 on 7/29/05.
Changed reg 70, bit 7 -> 1, and reg 71, bit 5 -> 1 - Rev 1.5*/
/*U8 temporarily changed to U32*/
U8 DefRF4000Val[RF4000_NBREGS] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x03, 0x84, 0x44, 0xc1, 0x12, 0x01, 0x70, 0x48, 0x00,
0x80, 0x7f, 0xff, 0x00, 0xcb, 0xa9, 0x33, 0x34, 0x7f, 0x48,
0x00, 0x7f, 0xff, 0x00, 0xca, 0x8f, 0x55, 0x7f, 0x39, 0x1c,
0x4c, 0x23, 0x00, 0xcd, 0x00, 0xaf, 0xc3, 0xc8, 0x00, 0x30,
0x0c, 0x50, 0x00, 0x10, 0x58, 0x03, 0xff, 0x00, 0x05, 0x30,
0x83, 0xdc, 0xe4, 0x9f, 0x4b, 0xd2, 0x66, 0x04, 0x64, 0xc2,
0x1f, 0x00
};
/* DUT "Chip Off" default register values.
These register values are to be written directly to the chip without
th need for "or'ing" into current register values.
Table values brought up to "reg map" ver 0.30 on 7/29/05.
Register 49 is modified to leave the crystal osc, crystal buffer on,
and Loop Thru Amp on: 08/03/05.*/
U8 chipOffState[NBR_WREG] = {
0x00, 0x00, 0x04, 0x44, 0x01, 0x00, 0x01, 0x70, 0x08, 0x20,
0x60, 0x7f, 0xff, 0x00, 0xcb, 0xa9, 0x33, 0x34, 0x7f ,0x08,
0x00, 0x7f, 0xff, 0x00, 0xca, 0x8f, 0x55, 0x7f, 0x39, 0x1c,
0x06, 0x23, 0x00, 0xc1, 0x00, 0x2e, 0xc2, 0xc8, 0x00, 0x30,
0x08, 0x50, 0x00, 0x10, 0x18, 0x03, 0x00, 0x00, 0x07, 0x30,
0x03, 0x5c, 0x64, 0x1c, 0x0b, 0x52, 0x16, 0x04, 0x64, 0xc2,
0x00, 0x00 };
ST_ErrorCode_t doOneTimeDecComp(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle);
ST_ErrorCode_t baseBandFltrCal(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, S32 filterBW, S32 thermalMode);
/* This function checks the lock status of LO1 and LO2.
A return value of 0 indicates a valid lock on both VCOs.
Otherwise, a 1 is return.*/
/*In sttuner 1 means locked/ 0 means not locked */
BOOL checkLockStatus(STTUNER_IOREG_DeviceMap_t *DeviceMap,IOARCH_Handle_t IOHandle)
{
S32 lo1 = 0;
S32 lo2 = 0;
lo2 = (U8)STTUNER_IOREG_GetField(DeviceMap,IOHandle, FRF4000_DLCK2);
lo1 = (U8)STTUNER_IOREG_GetField(DeviceMap,IOHandle, FRF4000_DLCK1);
if ((lo1 > 0) && (lo2 > 0))
{
/* The chip is fully locked on both VCOs.*/
return TRUE;
}
else
{
/* One or more of the VCOs is not locked.*/
return FALSE;
}
}
/* The following function does the "chip on" procedure. This sets specific
/ registers values, and attempts to lock the 2nd local oscillator, LO2.
/ Zero is returned for success, and a "1" is returned for a "no lock" error
/ condition. */
ST_ErrorCode_t chipOn(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle)
{
U8 temp;
S32 j;
S32 retVal = 0; /* Initially set for an "OK" return.*/
ST_ErrorCode_t Error = ST_NO_ERROR;
Error = STTUNER_IOREG_Reset(DeviceMap, IOHandle,DefRF4000Val,RF4000_Address);
Error |= STTUNER_IOREG_SetField(DeviceMap, IOHandle, FRF4000_OKS2, 1);
Error |= STTUNER_IOREG_SetField(DeviceMap, IOHandle, FRF4000_VSS2, 1); /*changed according to new rfmagic library*/
rf4kDelay(1);
Error |= STTUNER_IOREG_SetField(DeviceMap, IOHandle, FRF4000_VSS2, 0);/*chanegd according to new rfmagic lib*/
for (j = 0; j < 80; j++)
{
temp = (U8)STTUNER_IOREG_GetField(DeviceMap,IOHandle, FRF4000_DLCK2);
if (temp)
{
/* Got a lock, so exit.*/
break;
}
else
rf4kDelay(1);
}
if (j >= 80)
{
retVal = 1;
}
Error |= STTUNER_IOREG_SetField(DeviceMap, IOHandle, FRF4000_OKS2, 3);
return Error;
}
/* The following function does the "Chip Off". The values that were set for
the "crystal oscillator output buffer" and "crystal oscillator power" that
were set during the call to "RF4000_doInit" function are maintained during
the "chipOff" condition.
The return value is a 0 indicating success, and 1 if there is an error
from the Two-Wire-Bus write, however finish all the writes and only report
the error upon the return.
This function is used to set the first local oscillator, LO1.
The function returns a 0 for a successful lock, a 1 for no lock,
and a 2 for a channel frequency out of range. Allowed values for
stepSize are: 1000000, 666667, 500000.*/
ST_ErrorCode_t setLO1(STTUNER_IOREG_DeviceMap_t *DeviceMap, IOARCH_Handle_t IOHandle, U32 Fchan, S32 Fxtal, S32 stepSize)
{
S32 j,k;
U32 loDiv = 16; /* default value*/
U32 Fvco = 0;
U32 Np = 0;
U8 oscs = 1; /* default value*/
U8 cprs = 0;
U8 fbps = 1; /* default value*/
U8 lodv = 2; /* default value*/
U8 lcds = 1; /* default value*/
U8 B = 0;
U8 A = 0;
U8 R = 0;
U8 temp = 0;
ST_ErrorCode_t Error = ST_NO_ERROR;
if ((Fchan < (U32)MIN_CHANNEL) || (Fchan > (U32)MAX_CHANNEL))
{
return ST_ERROR_BAD_PARAMETER;
}
if (Fchan == tableFLOCF[tableFLOCF_LEN - 1].chanMax)
{
loDiv = tableFLOCF[tableFLOCF_LEN - 1].loDivider;
fbps = tableFLOCF[tableFLOCF_LEN - 1].fbps;
lodv = tableFLOCF[tableFLOCF_LEN - 1].lodv;
lcds = tableFLOCF[tableFLOCF_LEN - 1].lcds;
}
else
{
for (j = 0; j < tableFLOCF_LEN; j++)
{
if ( (tableFLOCF[j].chanMin <= Fchan) && (Fchan < tableFLOCF[j].chanMax) )
{
loDiv = tableFLOCF[j].loDivider;
fbps = tableFLOCF[j].fbps;
lodv = tableFLOCF[j].lodv;
lcds = tableFLOCF[j].lcds;
break;
}
}
}
Fvco = Fchan * loDiv;
for (j = 0; j < TABLEVCOSVFR_LEN; j++)
{
if ( (tableVCOSVFR[j].minF <= Fvco) && (Fvco <= tableVCOSVFR[j].maxF) )
{
oscs = tableVCOSVFR[j].oscs;
for (k=0;k<2;k++)
{
oscs -= 1;
if (oscs <= 0) { oscs = 1; break; }
else if (oscs == 4) { oscs = 3; }
else if (oscs == 8) { oscs = 7; }
else if (oscs == 12) { oscs = 11; }
else if (oscs == 16) { oscs = 15; }
}
break;
}
}
if (Fxtal == 24)
{
if (stepSize == 1000000)
{
Np = Fvco / 1000000;
R = 24;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -