⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 meeprom.c

📁 Atheros AP Test with Agilent N4010A source code
💻 C
📖 第 1 页 / 共 5 页
字号:
(
 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 + -