📄 meeprom.c
字号:
pLowerPcdac, pUpperPcdac);
return;
}
/**************************************************************************
* getPwrTable - Get Linear power table from the linear pcdac table
*
* Given a linear pcdac table, calculate the pcdac values that are needed
* to get a linear power table
*
* RETURNS: Fill in the linear power table
*/
void getPwrTable
(
MDK_FULL_PCDAC_STRUCT *pPcdacStruct, //pointer to linear pcdac table
A_UINT16 *pPwrTable //ptr to power table to fill
)
{
A_INT16 minScaledPwr;
A_INT16 maxScaledPwr;
A_INT16 pwr;
A_UINT16 pcdacMin = 0;
A_UINT16 pcdacMax = 63;
A_UINT16 i, j;
A_UINT16 numPwrEntries = 0;
A_UINT16 scaledPcdac;
minScaledPwr = pPcdacStruct->PwrValues[0];
maxScaledPwr = pPcdacStruct->PwrValues[pPcdacStruct->numPcdacValues - 1];
//find minimum and make monotonic
for(j = 0; j < pPcdacStruct->numPcdacValues; j++) {
if (minScaledPwr >= pPcdacStruct->PwrValues[j]) {
minScaledPwr = pPcdacStruct->PwrValues[j];
pcdacMin = j;
}
//make the list monotonically increasing otherwise interpolation algorithm will get fooled
//gotta start working from the top, hence i = numpcdacs - j.
i = (A_UINT16)(pPcdacStruct->numPcdacValues - 1 - j);
if(i == 0) {
break;
}
if (pPcdacStruct->PwrValues[i-1] > pPcdacStruct->PwrValues[i]) {
//it could be a glitch, so make the power for this pcdac,
//the same as the power from the next highest pcdac
pPcdacStruct->PwrValues[i - 1] = pPcdacStruct->PwrValues[i];
}
}
for(j = 0; j < pPcdacStruct->numPcdacValues; j++) {
if (maxScaledPwr < pPcdacStruct->PwrValues[j]) {
maxScaledPwr = pPcdacStruct->PwrValues[j];
pcdacMax = j;
}
}
//may not get control at lower power values,
//Fill lower power values with min pcdac, until reach min pcdac/power value
pwr = (A_UINT16)(PWR_STEP * ((minScaledPwr-PWR_MIN + PWR_STEP/2)/PWR_STEP) + PWR_MIN);
for (i = 0; i < (2 * (pwr - PWR_MIN)/SCALE + 1); i++) {
*pPwrTable = pcdacMin;
pPwrTable++;
numPwrEntries++;
}
//interpolate the correct pcdac value for required power until reach max power
i = 0;
while (pwr < pPcdacStruct->PwrValues[pPcdacStruct->numPcdacValues - 1])
{
pwr += PWR_STEP;
while ((pwr < pPcdacStruct->PwrValues[pPcdacStruct->numPcdacValues - 1]) && //stop if dbM > max_power_possible
((pwr - pPcdacStruct->PwrValues[i])*(pwr - pPcdacStruct->PwrValues[i+1]) > 0))
{
i++;
}
scaledPcdac = (A_UINT16)(getInterpolatedValue(pwr, pPcdacStruct->PwrValues[i],
pPcdacStruct->PwrValues[i+1],
(A_UINT16)(pPcdacStruct->PcdacValues[i]*2),
(A_UINT16)(pPcdacStruct->PcdacValues[i+1]*2),
0 ) + 1); //scale by 2 and add 1 to enable round up or down as needed
*pPwrTable = (A_UINT16)(scaledPcdac/2);
if(*pPwrTable > pcdacMax) {
*pPwrTable = pcdacMax;
}
pPwrTable++;
numPwrEntries++;
}
//fill remainder of power table with max pcdac value if saturation was reached
while ( numPwrEntries < PWR_TABLE_SIZE ) {
*pPwrTable = *(pPwrTable - 1);
pPwrTable++;
numPwrEntries++;
}
return;
}
/**************************************************************************
* getPcdacInterceptsFromPcdacMinMax - Calculate pcdac values from percentage
* intercepts
*
* Give the min and max pcdac values, use the percentage intercepts to calculate
* what the pcdac values should be
*
* RETURNS: Fill in the the pcdac values
*/
void getPcdacInterceptsFromPcdacMinMax
(
A_UINT16 pcdacMin, //minimum pcdac value
A_UINT16 pcdacMax, //maximim pcdac value
A_UINT16 *pPcdacValues //return the pcdac value
)
{
A_UINT16 i;
//loop for the percentages in steps or 5
for(i = 0; i < NUM_INTERCEPTS; i++ ) {
*pPcdacValues = (A_UINT16)((intercepts[i] * pcdacMax + (100-intercepts[i]) * pcdacMin)/100);
pPcdacValues++;
}
return;
}
/**************************************************************************
* getMaxRDPowerlistForFreq - Get the max power values for this channel
*
* Use the test group data read in from the eeprom to get the max power
* values for the channel
*
* RETURNS: Fill in the max power for each rate
*/
void getMaxRDPowerlistForFreq
(
A_UINT32 devNum,
A_UINT16 channel, //input channel value
A_INT16 *pRatesPower //pointer to power/rate table to fill
)
{
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
A_UINT16 lowerChannel, lowerIndex=0, lowerPower=0;
A_UINT16 upperChannel, upperIndex=0, upperPower=0;
A_INT16 twiceMaxEdgePower=63;
A_INT16 twicePower = 0;
A_UINT16 i;
A_UINT16 tempChannelList[NUM_16K_EDGES]; //temp array for holding edge channels
A_UINT16 numChannels = 0;
MDK_TRGT_POWER_INFO *pPowerInfo = NULL;
switch(pLibDev->mode) {
case MODE_11A:
numChannels = pLibDev->p16KTrgtPowerInfo->numTargetPwr_11a;
pPowerInfo = pLibDev->p16KTrgtPowerInfo->trgtPwr_11a;
pRatesPower[XR_POWER_INDEX] = pLibDev->p16kEepHeader->info11a.xrTargetPower;
break;
case MODE_11G:
case MODE_11O:
numChannels = pLibDev->p16KTrgtPowerInfo->numTargetPwr_11g;
pPowerInfo = pLibDev->p16KTrgtPowerInfo->trgtPwr_11g;
pRatesPower[XR_POWER_INDEX] = pLibDev->p16kEepHeader->info11g.xrTargetPower;
break;
case MODE_11B:
numChannels = pLibDev->p16KTrgtPowerInfo->numTargetPwr_11b;
pPowerInfo = pLibDev->p16KTrgtPowerInfo->trgtPwr_11b;
pRatesPower[XR_POWER_INDEX] = 0;
break;
}
//extrapolate the power values for the test Groups
for (i = 0; i < numChannels; i++) {
tempChannelList[i] = pPowerInfo[i].testChannel;
}
getLowerUpperValues(channel, tempChannelList, numChannels, &lowerChannel, &upperChannel);
//get the index for the channel
for (i = 0; i < numChannels; i++) {
if (lowerChannel == tempChannelList[i]) {
lowerIndex = i;
}
if (upperChannel == tempChannelList[i]) {
upperIndex = i;
break;
}
}
for(i = 0; i < 8; i++) {
if(pLibDev->mode != MODE_11B) {
//power for rates 6,9,12,18,24 are all the same
if (i < 5) {
lowerPower = pPowerInfo[lowerIndex].twicePwr6_24;
upperPower = pPowerInfo[upperIndex].twicePwr6_24;
}
if (i == 5) {
lowerPower = pPowerInfo[lowerIndex].twicePwr36;
upperPower = pPowerInfo[upperIndex].twicePwr36;
}
if (i == 6) {
lowerPower = pPowerInfo[lowerIndex].twicePwr48;
upperPower = pPowerInfo[upperIndex].twicePwr48;
}
if (i == 7) {
lowerPower = pPowerInfo[lowerIndex].twicePwr54;
upperPower = pPowerInfo[upperIndex].twicePwr54;
}
} else {
switch(i) {
case 0:
case 1:
lowerPower = pPowerInfo[lowerIndex].twicePwr6_24;
upperPower = pPowerInfo[upperIndex].twicePwr6_24;
break;
case 2:
case 3:
lowerPower = pPowerInfo[lowerIndex].twicePwr36;
upperPower = pPowerInfo[upperIndex].twicePwr36;
break;
case 4:
case 5:
lowerPower = pPowerInfo[lowerIndex].twicePwr48;
upperPower = pPowerInfo[upperIndex].twicePwr48;
break;
case 6:
case 7:
lowerPower = pPowerInfo[lowerIndex].twicePwr54;
upperPower = pPowerInfo[upperIndex].twicePwr54;
break;
}
}
twicePower = (A_UINT16)(getInterpolatedValue(channel, lowerChannel, upperChannel, lowerPower,
upperPower, 0));
if(twicePower > twiceMaxEdgePower) {
twicePower = twiceMaxEdgePower;
}
pRatesPower[i] = twicePower;
}
//fill in the CCK power values (fill for all modes)
fillCCKMaxPower(devNum, channel, pRatesPower);
return;
}
void fillCCKMaxPower
(
A_UINT32 devNum,
A_UINT16 channel, //input channel value
A_INT16 *pRatesPower //pointer to power/rate table to fill
)
{
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
A_UINT16 lowerChannel, lowerIndex=0;
A_INT16 lowerPower=0;
A_UINT16 upperChannel, upperIndex=0;
A_INT16 upperPower=0;
A_INT16 twiceMaxEdgePower=63;
A_INT16 twicePower = 0;
A_UINT16 i;
A_UINT16 tempChannelList[NUM_16K_EDGES]; //temp array for holding edge channels
A_UINT16 numChannels = 0;
MDK_TRGT_POWER_INFO *pPowerInfo = NULL;
numChannels = pLibDev->p16KTrgtPowerInfo->numTargetPwr_11b;
pPowerInfo = pLibDev->p16KTrgtPowerInfo->trgtPwr_11b;
//extrapolate the power values for the test Groups
for (i = 0; i < numChannels; i++) {
tempChannelList[i] = pPowerInfo[i].testChannel;
}
getLowerUpperValues(channel, tempChannelList, numChannels, &lowerChannel, &upperChannel);
//get the index for the channel
for (i = 0; i < numChannels; i++) {
if (lowerChannel == tempChannelList[i]) {
lowerIndex = i;
}
if (upperChannel == tempChannelList[i]) {
upperIndex = i;
break;
}
}
for(i = 8; i < XR_POWER_INDEX; i++) {
switch(i) {
case 8:
lowerPower = pPowerInfo[lowerIndex].twicePwr6_24;
upperPower = pPowerInfo[upperIndex].twicePwr6_24;
break;
case 9:
case 10:
lowerPower = pPowerInfo[lowerIndex].twicePwr36;
upperPower = pPowerInfo[upperIndex].twicePwr36;
break;
case 11:
case 12:
lowerPower = pPowerInfo[lowerIndex].twicePwr48;
upperPower = pPowerInfo[upperIndex].twicePwr48;
break;
case 13:
case 14:
lowerPower = pPowerInfo[lowerIndex].twicePwr54;
upperPower = pPowerInfo[upperIndex].twicePwr54;
break;
}
twicePower = (A_UINT16)(getInterpolatedValue(channel, lowerChannel, upperChannel, lowerPower,
upperPower, 0));
if(twicePower > twiceMaxEdgePower) {
twicePower = twiceMaxEdgePower;
}
pRatesPower[i] = twicePower;
}
return;
}
/**************************************************************************
* forcePCDACTable - Write the linear power - pcdac table to device registers
*
*
* RETURNS:
*/
MANLIB_API void forcePCDACTable
(
A_UINT32 devNum,
A_UINT16 *pPcdacs
)
{
A_UINT16 regOffset;
A_UINT16 i;
A_UINT32 temp32;
regOffset = 0x9800 + (608 << 2) ;
for(i = 0; i < 32; i++) {
temp32 = 0xffff & ((pPcdacs[2*i + 1] << 8) | 0xff);
temp32 = (temp32 << 16) | (0xffff & ((pPcdacs[2*i] << 8) | 0xff));
REGW(devNum, regOffset, temp32);
//printf("Snoop: regOffset = %x, regValue = %x\n", regOffset, temp32);
regOffset += 4;
}
}
/**************************************************************************
* fbin2freq - Get channel value from binary representation held in eeprom
*
*
* RETURNS: the frequency in MHz
*/
A_UINT16 fbin2freq(A_UINT32 devNum, A_UINT16 fbin)
{
A_UINT16 returnValue;
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
if((pLibDev->p16kEepHeader->majorVersion == 3) && (pLibDev->p16kEepHeader->minorVersion <= 2)) {
returnValue = (fbin>62) ? (A_UINT16)(5100 + 10*62 + 5*(fbin-62)) : (A_UINT16)(5100 + 10*fbin);
}
else {
returnValue = (A_UINT16)(4800 + 5*fbin);
}
return returnValue;
}
A_UINT16 fbin2freq_2p4(A_UINT32 devNum, A_UINT16 fbin)
{
A_UINT16 returnValue;
LIB_DEV_INFO *pLibDev = gLibInfo.pLibDevArray[devNum];
if((pLibDev->p16kEepHeader->majorVersion == 3) && (pLibDev->p16kEepHeader->minorVersion <= 2)) {
returnValue = (A_UINT16)(2400 + fbin);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -