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

📄 maui_cal.c

📁 atheros ar5001 5002 driver
💻 C
📖 第 1 页 / 共 5 页
字号:

	A_UINT16 numExtrema, numTotalExtrema ; 
	A_UINT16 *extrema ;

	A_UINT16 ii, jj;

	numTotalExtrema = 0;
	
	extrema = (A_UINT16 *)malloc(pDataset->numChannels * sizeof(A_UINT16)) ;
	if (extrema == NULL)
	{
		uiPrintf("Could not allocate memory for extrema. Exiting...\n");
		exit(0);
	}

	for (ii=0; ii<pDataset->pDataPerChannel[0].numPcdacValues; ii++)
	{
		pick_local_extrema(pDerivDataset, ii, extrema, &(numExtrema)) ; // numExtrema stores the number of extrema found
		for (jj=0; jj<numExtrema; jj++)
		{
			addUniqueElementToList(TPlist, extrema[jj], &(numTotalExtrema));
		}
	}

	*totalTPs = numTotalExtrema ;
	qsort( (void *) TPlist, numTotalExtrema, sizeof(A_UINT16), numerical_compare) ;
	
	free(extrema);
}

void addUniqueElementToList(A_UINT16 *list, A_UINT16 element, A_UINT16 *listSize)
{
	A_UINT16 ii = 0;
	A_BOOL isUnique = TRUE;
	A_UINT16 size = *listSize ;

	while ((ii<size) && (isUnique))
	{
		if (element == list[ii])
		{
			isUnique = FALSE;
		}
		ii++;
	}

	if (isUnique)
	{
 		list[size] = element ;
		(*listSize) = size + 1 ;
	}

}


int numerical_compare( const void *arg1, const void *arg2 )
{
	A_INT16 comparison = 0;
	A_UINT16 val1 = * ( A_UINT16 * ) arg1;
	A_UINT16 val2 = * ( A_UINT16 * ) arg2;

	if (val1 > val2)
		comparison = 1;
	if (val1 < val2)
		comparison = -1;

	return ( comparison );
}

void pick_local_extrema(dPCDACS_EEPROM *pDataset, A_UINT16 pcd_idx, A_UINT16 *retList, A_UINT16 *listSize)
{

	A_UINT16 ii;
	A_INT16 flatRunStartDirection, dirxn, newDirexn, midPoint ;
	A_UINT16 *flatRun ;
	A_UINT16 sizeFlatRun =0;
	A_UINT16 ch0, ch1, chN;
	double noise;
	double delta;
	A_UINT16 numTPs = 0;

	flatRun = (A_UINT16*)malloc(pDataset->numChannels * sizeof(A_UINT16)) ;
	if (flatRun == NULL)
	{
		uiPrintf("Could not allocate memory for list flatRun. Exiting...\n");
		exit(0);
	}

	ch0 = pDataset->pChannels[0];
	ch1 = pDataset->pChannels[1];
	chN = pDataset->pChannels[pDataset->numChannels-1];
	// noise calculated to ignore a change in slope causing a 1dB deviation over entire range
	// an adjustment factor of 10 seems to work better for a 30MHz measurement step
	noise = fabs(1.0/(10*(ch1-ch0)*(chN-ch0))) ;

	retList[numTPs] = ch0;
	numTPs++;

	flatRunStartDirection = 0; // implicitly indicates out of flatrun
	delta = (pDataset->pDataPerChannel[1].pPwrValues[pcd_idx] -	pDataset->pDataPerChannel[0].pPwrValues[pcd_idx]) ;
	newDirexn =  (delta >= 0) ? 1 : -1 ;

	for (ii=1; ii<(pDataset->numChannels-1); ii++)
	{
		dirxn = newDirexn;
		newDirexn = 0;
		delta = (pDataset->pDataPerChannel[ii+1].pPwrValues[pcd_idx] -	pDataset->pDataPerChannel[ii].pPwrValues[pcd_idx]) ;
		if (delta > 2*noise)
		{
			newDirexn = 1;
		}
		if (-delta > 2*noise)
		{
			newDirexn = -1;
		}
		if (abs(newDirexn - dirxn) < 1) // that is, no change in direction
		{
			if (abs(dirxn) < 1) // start populating flatRun
			{
				flatRun[sizeFlatRun] = ii ;
				sizeFlatRun++;
			}
			continue;
		}
		if (abs(newDirexn - dirxn) > 1) // a reversal in direction
		{
			// pick only the NON-ZERO extrema
			if (fabs(pDataset->pDataPerChannel[ii].pPwrValues[pcd_idx]) > noise)
			{
				retList[numTPs] = pDataset->pChannels[ii];
				numTPs++;
			}
			continue;
		}
		// at this point, either starting a flatrun or ending one
		if (abs(newDirexn) < 1) // implies start of a flatrun
		{
			flatRunStartDirection = newDirexn;
			flatRun[sizeFlatRun] = ii ;
			sizeFlatRun++;
			continue ;
		}
		if (abs(dirxn) < 1) // implies end of a flatrun
		{
			midPoint = flatRun[(A_UINT16)(sizeFlatRun-1)/2] ;
			if ((abs(newDirexn-flatRunStartDirection) > 1) &&  // pick only extrema, not plateaus
				(fabs(pDataset->pDataPerChannel[midPoint].pPwrValues[pcd_idx]) > noise)) // only non-zero extrema
			{
				retList[numTPs] = pDataset->pChannels[ii];
				numTPs++;
			}
			flatRunStartDirection = 0 ; 
			sizeFlatRun = 0; // effectively clears the list flatRun
		}
	}

	retList[numTPs] = pDataset->pChannels[pDataset->numChannels-1];
	numTPs++;

	*listSize = numTPs;	
	
	free(flatRun);
}

void consolidate_turning_points(A_UINT16 **tpList, A_UINT16 *sizeList, A_UINT16 debug)
{

	A_UINT16 *newList;
	A_UINT16 sizeNewList = 0;
	A_UINT16 binSize = 40;
	A_UINT16 ii;

	newList = (A_UINT16 *)malloc(numRAWChannels * sizeof(A_UINT16));
	if (newList == NULL)
	{
		uiPrintf("Could not allocate newList to consolidate turning points. Exiting...\n");
		exit(0);
	}

	newList[0] = (*tpList)[0] ;
	sizeNewList++;

	for (ii=1; ii<*sizeList-2; ii++)
	{
		if ( ((*tpList)[ii] - newList[sizeNewList-1]) > binSize)
		{
			newList[sizeNewList] = (*tpList)[ii];
			sizeNewList++;
		}
	}

		if ( ( ((*tpList)[*sizeList-2] - newList[sizeNewList-1]) > binSize) &&
			 ( ((*tpList)[*sizeList-1] - (*tpList)[*sizeList-2]) > binSize) )
		{
			newList[sizeNewList] = (*tpList)[*sizeList-2];
			sizeNewList++;
		}

		newList[sizeNewList] = (*tpList)[*sizeList-1];
		sizeNewList++;

		// free the memory associated with the old list that had all the TPs
		free( (void *) (*tpList));
		// point the allTP list to the consolidated list
		(*tpList) = newList ;
		*sizeList = sizeNewList ;
		
}


void build_turningpoint_totempole(dPCDACS_EEPROM *pDataset, TP_VAL **totempole, A_UINT16 sizeTotempole, A_UINT16 *tpList, A_UINT16 debug)
{

	A_INT16 ii, jj;
	double avg, cost;
	A_UINT16 left, right;


	(*totempole) = (TP_VAL *)malloc(sizeTotempole * sizeof(TP_VAL)) ;
	if ((*totempole) == NULL)
	{
		uiPrintf("Could not allocate memory for the totempole. Exiting...\n");
		exit(0);
	}

	jj = 0;
	for (ii=0; ii<pDataset->numChannels; ii++)
	{
		if (tpList[jj] == pDataset->pChannels[ii])
		{
			(*totempole)[jj].channel_idx = ii ;
			jj++ ;
		}
	}

	if (jj != sizeTotempole)
	{
		uiPrintf("Bad juju happened in assigning totempole. jj=%d, numTPs=%d. Exiting...\n",jj, sizeTotempole);
		exit(0);
	}

	for (ii=1; ii<(sizeTotempole-1); ii++)
	{
		cost = 0.0;
		left = pRawDataset->pChannels[(*totempole)[ii].channel_idx] - 
			    pRawDataset->pChannels[(*totempole)[ii-1].channel_idx];
		right= pRawDataset->pChannels[(*totempole)[ii+1].channel_idx] - 
			    pRawDataset->pChannels[(*totempole)[ii].channel_idx]; 
		
		for (jj=0; jj<pDataset->pDataPerChannel[0].numPcdacValues; jj++)
		{
			avg = (double) (right*pDataset->pDataPerChannel[(*totempole)[ii-1].channel_idx].pPwrValues[jj] +
				   left*pDataset->pDataPerChannel[(*totempole)[ii+1].channel_idx].pPwrValues[jj])/(left+right) ;
			cost += fabs(pDataset->pDataPerChannel[(*totempole)[ii].channel_idx].pPwrValues[jj] - avg);
		}
		(*totempole)[ii].val = cost ;
		if(debug > 0)
		{
			uiPrintf("Impact of TP#%d at %d = %2.1f.\n", ii, pDataset->pChannels[(*totempole)[ii].channel_idx], (*totempole)[ii].val);
		}
	}

	//guarantee inclusion of 1st and last TP
	(*totempole)[0].val = 9999.0;
	(*totempole)[sizeTotempole-1].val = 9999.0; 
}

int totempole_compare( const void *arg1, const void *arg2 )
{
	A_INT16 comparison = 0;
	TP_VAL tp1 = * ( TP_VAL * ) arg1;
	TP_VAL tp2 = * ( TP_VAL * ) arg2;

	if ( tp1.val> tp2.val )
		comparison = -1;
	if ( tp1.val < tp2.val )
		comparison = 1; 

	return ( comparison ); // for descending qsort of totempole
}

void dMapGrid(dPCDACS_EEPROM *pSrcStruct, dPCDACS_EEPROM *pDestStruct)
{
	dDATA_PER_CHANNEL	*pChannelData;
	A_UINT16			*pPcdacValue;
	double				*pPwrValue;
	A_UINT16			i, j;
	A_UINT16            channel, pcdac;

	pChannelData = pDestStruct->pDataPerChannel; 

	for(i = 0; i < pDestStruct->numChannels; i++ ) {
		pPcdacValue = pChannelData->pPcdacValues;
		pPwrValue = pChannelData->pPwrValues;
		for(j = 0; j < pChannelData->numPcdacValues; j++ ) {
			channel = pChannelData->channelValue;
			pcdac = *pPcdacValue;
			*pPwrValue = getPowerAt(channel, pcdac, pSrcStruct);
			pPcdacValue++;
			pPwrValue++;
	    }
		pChannelData++;			
	}
}

double getPowerAt( A_UINT16 channel, A_UINT16	pcdacValue, dPCDACS_EEPROM *pSrcStruct)
{
	double	powerValue;
	A_UINT16	lFreq, rFreq;			//left and right frequency values
	A_UINT16	llPcdac, ulPcdac;		//lower and upper left pcdac values
	A_UINT16	lrPcdac, urPcdac;		//lower and upper right pcdac values
	double	lPwr, uPwr;				//lower and upper temp pwr values
	double	lScaledPwr, rScaledPwr;	//left and right scaled power


	if(dFindValueInList(channel, pcdacValue, pSrcStruct, &powerValue)){
		//value was copied from srcStruct
		return(powerValue);
	}

	dGetLeftRightChannels(channel, pSrcStruct, &lFreq, &rFreq);
	dGetLowerUpperPcdacs(pcdacValue, lFreq, pSrcStruct, &llPcdac, &ulPcdac);
	dGetLowerUpperPcdacs(pcdacValue, rFreq, pSrcStruct, &lrPcdac, &urPcdac);
    
	//get the power index for the pcdac value
	dFindValueInList(lFreq, llPcdac, pSrcStruct, &lPwr);
	dFindValueInList(lFreq, ulPcdac, pSrcStruct, &uPwr);
	lScaledPwr = dGetInterpolatedValue( pcdacValue, llPcdac, ulPcdac, lPwr, uPwr);
    
	dFindValueInList(rFreq, lrPcdac, pSrcStruct, &lPwr);
	dFindValueInList(rFreq, urPcdac, pSrcStruct, &uPwr);
	rScaledPwr = dGetInterpolatedValue( pcdacValue, lrPcdac, urPcdac, lPwr, uPwr);

	return(dGetInterpolatedValue( channel, lFreq, rFreq, lScaledPwr, rScaledPwr));
} 

// the "double" returning version of findValueInList that works with scaled integer values
A_BOOL dFindValueInList( A_UINT16 channel, A_UINT16 pcdacValue, dPCDACS_EEPROM *pSrcStruct, double *powerValue)
{
	dDATA_PER_CHANNEL	*pChannelData;
	A_UINT16			*pPcdac;
	A_UINT16			i, j;

	pChannelData = pSrcStruct->pDataPerChannel; 
	for(i = 0; i < pSrcStruct->numChannels; i++ ) {
		if (pChannelData->channelValue == channel) {
			pPcdac = pChannelData->pPcdacValues;
			for(j = 0; j < pChannelData->numPcdacValues; j++ ) {
				if (*pPcdac == pcdacValue) {
					*powerValue = pChannelData->pPwrValues[j];
					return(1);
				}
				pPcdac++;
			}
	    }
		pChannelData++;			
	}
	return(0);
}

// only searches for integer values in integer lists. used for channel and pcdac lists
void iGetLowerUpperValues 
(
 A_UINT16	value,			//value to search for
 A_UINT16	*pList,			//ptr to the list to search
 A_UINT16	listSize,		//number of entries in list
 A_UINT16	*pLowerValue,	//return the lower value
 A_UINT16	*pUpperValue	//return the upper value	
)
{
	A_UINT16	i;
	A_UINT16	listEndValue = *(pList + listSize - 1);
	A_UINT16	target = value ;

	//see if value is lower than the first value in the list
	//if so return first value
	if (target <= (*pList)) {
		*pLowerValue = *pList;
		*pUpperValue = *pList;
		return;
	}
  
	//see if value is greater than last value in list
	//if so return last value
	if (target >= listEndValue) {
		*pLowerValue = listEndValue;
		*pUpperValue = listEndValue;
		return;
	}

	//look for value being near or between 2 values in list
	for(i = 0; i < listSize; i++) {
		//if value is close to the current value of the list 
		//then target is not between values, it is one of the values
		if (pList[i] == target) {
			*pLowerValu

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -