📄 meeprom.c
字号:
(
A_UINT16 channel, //channel to search for
MDK_PCDACS_EEPROM *pSrcStruct, //ptr to struct to search
A_UINT16 *pLowerChannel, //return lower channel
A_UINT16 *pUpperChannel //return upper channel
)
{
getLowerUpperValues(channel, pSrcStruct->pChannelList, pSrcStruct->numChannels,
pLowerChannel, pUpperChannel);
return;
}
/**************************************************************************
* getLeftRightpcdacs - Get lower and upper pcdacs from source struct.
*
* As above function, except pulls the pcdac list from the input struct
*
* RETURNS: the upper and lower pcdac values
*/void getLowerUpperPcdacs
(
A_UINT16 pcdac, //pcdac to search for
A_UINT16 channel, //current channel
MDK_PCDACS_EEPROM *pSrcStruct, //ptr to struct to search
A_UINT16 *pLowerPcdac, //return lower pcdac
A_UINT16 *pUpperPcdac //return upper pcdac
)
{
MDK_DATA_PER_CHANNEL *pChannelData;
A_UINT16 i;
//find the channel information
pChannelData = pSrcStruct->pDataPerChannel;
for (i = 0; i < pSrcStruct->numChannels; i++) {
if(pChannelData->channelValue == channel) {
break;
}
pChannelData++;
}
getLowerUpperValues(pcdac, pChannelData->PcdacValues, pChannelData->numPcdacValues,
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_INT32 ctlPower = NO_CTL_IN_EEPROM;
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;
if (isDragon(devNum)) {
#ifdef LINUX
ar6000GetPowerPerRateTable(devNum, channel, pRatesPower);
#endif
return;
}
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;
}
if(pLibDev->libCfgParams.applyCtlLimit) {
if(pLibDev->mode != MODE_11B) {
ctlPower = getCtlPower(devNum, pLibDev->libCfgParams.ctlToApply, channel, pLibDev->mode, pLibDev->turbo);
}
//note if not ctl limit, this will fail, due to default value of ctlPower being high
if(ctlPower < twicePower) {
pRatesPower[i] = (A_INT16)ctlPower;
// printf("Applying ctl power (x2) of %d to pRatesPower[%d]\n", ctlPower, i);
} else {
pRatesPower[i] = twicePower;
}
}
else {
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_INT32 ctlPower = NO_CTL_IN_EEPROM;
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:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -