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

📄 meeprom.c

📁 atheros ar5001 5002 driver
💻 C
📖 第 1 页 / 共 5 页
字号:
						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 + -