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

📄 tunealg.c

📁 LV24000的单片机DEMO程序
💻 C
📖 第 1 页 / 共 2 页
字号:
} // End InterpolateX

int InterpolateOscStep(WORD wY, WORD wX1, WORD wX2, WORD wY1, WORD wY2)
{
	// Draw a line from (X1,Y1) to (X2,Y2) to calculate the X (ie the OSC-value) belongs to desired Y (ie the dwExpFreq)
	// formula:
	//					x2 - x1
	//			step = (y - y1)---------
	//					y2 - y1
	// The OscValue is then (x1+step)
	INT32 iDeltaY;
	INT32 sA,sB, sC;

	iDeltaY = (INT32)wY2-(INT32)wY1;
	if (iDeltaY == 0 )
		return(0);
//	return( (int)((((signed long)dwY - (signed long)dwY1) * ((int)wX2 - (int)wX1)) + (iDeltaY/2))/iDeltaY );
	sA = (INT32)wY - (INT32)wY1;
	sB = sA * ((int)wX2 - (int)wX1);
	sB += (iDeltaY/2);
	sC = sB/iDeltaY;
	return((int)sC);
} // End InterpolateOscStep

BYTE InitTuningRfCapOsc(void)
{
	WORD wCfg;
	WORD wTmp;

	// Select correct oscillator output and enable measuring mode
	wCfg = SetUpChipMode(CO_RF_OSC | CHIP_MEASURE_MODE | CHIP_AFC_OFF);

	// Determine the min/max RF frequency (hardware RF-limit)
	// Set CAP/OSC at minimal value and measure the the minimal hardware RF
	GetRfAtCapOsc(QSS_MIN_RFCAP, QSS_MIN_RFOSC, LV_MSR_TIME_32ms, &g_wHwRfLow);

	// Set CAP/OSC at maximal value and measure the maximal hardware RF
	GetRfAtCapOsc(QSS_MAX_RFCAP, QSS_MAX_RFOSC, LV_MSR_TIME_32ms, &g_wHwRfHigh);

	// Init QSSF-data
	// Determine the 2 points for CAP-low line and the OSC-low resolution
	Qssf1.CoefLo = CalculateCoeff(g_wHwRfLow);	// Point1_0: Cap=min, Osc=min)
	GetRfAtCapOsc(QSS_MIN_RFCAP, QSS_MAX_RFOSC, LV_MSR_TIME_32ms, &wTmp);
	Qssf1.CoefHi = CalculateCoeff(wTmp);		// Point1_1: Cap=min, Osc=max)

	// Determine the 2 points for CAP-high line and the OSC-high resolution
	GetRfAtCapOsc(QSS_MAX_RFCAP, QSS_MIN_RFOSC, LV_MSR_TIME_32ms, &wTmp);
	Qssf2.CoefLo = CalculateCoeff(wTmp);		// Point2_0: Cap=max, Osc=min)
	Qssf2.CoefHi = CalculateCoeff(g_wHwRfHigh);	// Point2_0: Cap=max, Osc=max)

	// Restore chip config
	SetUpChipMode(wCfg);

	// Error check
	if ( g_wHwRfHigh <= g_wHwRfLow)
		return(LVLS_INV_RFLIMIT_ERR);
	return(LVLS_NO_ERROR);
} // End InitTuningRfCapOsc

BYTE GetRfAtCapOsc(WORD wCapValue, WORD wOscValue, DWORD dwMsrTimeUs, PWORD pwFreq)
{
	WriteRfCap(wCapValue);
	WriteRfOsc(wOscValue);
	return(CountPulse(dwMsrTimeUs, pwFreq)); // Measure the RF
} // End GetRfAtCapOsc

BYTE ScanSetFreq(WORD wTuneFreq, BYTE byPrecisionLevel)
{
	// iPrecisionLevel		ScanSetFreq	  	CalculateRfCapOsc
	//	QSSF_PRECISION_NONE	WriteOsc	  	No CAP verification
	//	QSSF_PRECISION_LOW	WriteOsc	  	CAP verification with 8ms measuring
	//	QSSF_PRECISION_MED	FineTuning 8ms	  	CAP verification with 32ms measuring
	//	QSSF_PRECISION_HIGH	FineTuning 32ms	  	CAP verification with 64ms measuring
	BYTE byResult;
	WORD  wCapValue, wOscValue;

	// Calculate Cap, Osc value
	byResult = CalculateRfCapOsc(wTuneFreq, &wCapValue, &wOscValue, byPrecisionLevel);

	// Write CAP value
	if (byResult == LVLS_NO_ERROR)
	{
		if (GetRfCapValue() != wCapValue)
			byResult = WriteRfCap(wCapValue);
	}
			
	// Fine tuning if precision needed
	if (byResult == LVLS_NO_ERROR)
	{
		if (byPrecisionLevel==QSSF_PRECISION_MED)
		{
			byResult = FineTuneRfOsc(wTuneFreq, LV_MSR_TIME_8ms, wOscValue, FALSE);
		}
		else if (byPrecisionLevel==QSSF_PRECISION_HIGH)
		{
			byResult = FineTuneRfOsc(wTuneFreq, LV_MSR_TIME_32ms, wOscValue, FALSE);
		}
		else // byPrecisionLevel==QSSF_PRECISION_NONE or QSSF_PRECISION_LOW
		{
			// Just write the OscValue, (CapValue is already written by CalculateRfCapOsc
			byResult = WriteRfOsc(wOscValue);
		}
	}
	if (byResult != LVLS_NO_ERROR)
		byResult = FineTuneRfOsc(wTuneFreq, LV_MSR_TIME_32ms, QSS_MIN_RFOSC, FALSE);
	return(byResult);
} // End ScanSetFreq

/* ************************************************************************************************
 *
 *  Function:   FineTuneRfOsc
 *
 *  Authors:    Hung van Le
 *  Purpose:    Validate and possibly correcting the calculated CAP/OSC
 *  Input:      
 *  Output:     Status as defined in LvErr.h
 *  Comments:
 *
 * ************************************************************************************************
 * Copyright (c) 2002-2004. Semiconductor Ideas to the Market (ItoM) B.V. All rights reserved.
 * ************************************************************************************************ */
BYTE FineTuneRfOsc(WORD wRfFreq, DWORD dwMeasureTimeUs, WORD wExpOscValue, BYTE byNeedPrecision)
{	
	BYTE i;
	BYTE byResult;
	WORD wCapValue;
	
	wCapValue = GetRfCapValue();
	for (i=0; i<5; i++)
	{
		byResult = WriteRfCap(wCapValue);
		if (byResult == LVLS_NO_ERROR)
		{
			byResult = LinTuneDac(wRfFreq, dwMeasureTimeUs, WriteRfOsc, wExpOscValue, QSS_MAX_RFOSC, byNeedPrecision);
			wExpOscValue = QSS_MIN_RFOSC; // Change to minimun value for next approach
		}
		if ( byResult != LVLS_RFOSC_OUTOFLIMIT_ERR)
			break;
		if (g_wLastMsrRF < wRfFreq )
			wCapValue++;
		else
			wCapValue--;
	}
	
	return(byResult);
} // End FineTuneRfOsc

BYTE CalculateRfCapOsc(WORD wFreq, PWORD pwCap, PWORD pwOsc, BYTE byPrecisionLevel)
{
	// Calculate the CAP/OSC value for dwFreqHz (frequency in Hz)

	WORD wCoeff, wCorFreq;
	BYTE byRetry;
	WORD wCap;
	DWORD dwMsrTimeUs;
	
	// TODO: Check if QSSF-data initialised
//	if (m_pQssfData==NULL)
//		return(LVLS_NO_SSF_DATA_ERR); 
	
	// calculate Coeff of desired frequency
	wCoeff = CalculateCoeff(wFreq);
	
	// Determine measuring deviation
	if (byPrecisionLevel==QSSF_PRECISION_NONE)
	{
		dwMsrTimeUs = 0;
		wCorFreq = 0;
	}
	else if (byPrecisionLevel==QSSF_PRECISION_LOW)
	{
		dwMsrTimeUs = LV_MSR_TIME_8ms;
		wCorFreq = 3;	// (128 Hz * 256)/10 kHz (128Hz: fault by 8ms, 256: RF divider factor, 10kHz:RF unit
	}
	else if (byPrecisionLevel==QSSF_PRECISION_MED)
	{
		dwMsrTimeUs = LV_MSR_TIME_32ms;
		wCorFreq = 0;	// (32 Hz * 256)/10 kHz (32Hz: fault by 32ms, 256: RF divider factor, 10kHz:RF unit
	}
	else //if (byPrecisionLevel==QSSF_PRECISION_HIGH)
	{
		dwMsrTimeUs = LV_MSR_TIME_64ms;
		wCorFreq = 0;	// (16 Hz * 256)/10 kHz (16Hz: fault by 64ms, 256: RF divider factor, 10kHz:RF unit
	}	
	//wCorFreq *= GetDividerFactor();
	//wCorFreq /= 10000; //@@@ 10 kHz unit for RF

	// Derive CAP from low data
	wCap = InterpolateX( wCoeff, QSS_MIN_RFCAP, QSS_MAX_RFCAP, Qssf1.CoefLo, Qssf2.CoefLo);

	// Calculate OSC value
	byRetry = 3;
	WriteRfOsc(QSS_MIN_RFOSC);	// Kep OSC at fixed value during CAP calculation
	while (byRetry)
	{
		WORD wCoefLo, wCoefHi, wCoefRange, wCoefReal, wCoefCor;
		WORD wMsrFreq;
		
		// Get coefficient of calculated CAP from low Qfm-Data 
		wCoefLo = InterpolateY(wCap, QSS_MIN_RFCAP, QSS_MAX_RFCAP, Qssf1.CoefLo, Qssf2.CoefLo);
		
		// Get coefficient of calculated CAP from high Qfm-Data 
		wCoefHi = InterpolateY(wCap, QSS_MIN_RFCAP, QSS_MAX_RFCAP, Qssf1.CoefHi, Qssf2.CoefHi);
		
		// Calculate range
		wCoefRange = wCoefLo - wCoefHi;	// vCoefLo should be greater than vCoefHi
		
		// Verify CAP value: Write CAP, OSC and measure the frequency
		if ( WriteRfCap(wCap) == LVLS_NO_ERROR)
		{
			// Determine the real coefficient of this CAP
			if (byPrecisionLevel != QSSF_PRECISION_NONE)
			{
				CountPulse(dwMsrTimeUs, &wMsrFreq);
				wCoefReal = CalculateCoeff(wMsrFreq);
				if (wCorFreq > 0)
					wCoefCor = wCoefReal - CalculateCoeff(wMsrFreq+wCorFreq);
				else
					wCoefCor = 0;
			}
			else
			{
				wCoefReal = wCoefLo;
				wCoefCor = 0;
			}
			
			// Do we have the correct CAP
			if ( (wCoeff<=(wCoefReal+wCoefCor)) && (wCoeff>=(wCoefReal-wCoefRange-wCoefCor)) )
			{
				// Derive the OSC value
				*pwOsc = InterpolateX(wCoeff, QSS_MIN_RFOSC, QSS_MAX_RFOSC, wCoefReal+wCoefCor, wCoefReal-wCoefRange-wCoefCor);
				
				// Done when approriate OSC value
				if ( (*pwOsc>=QSS_MIN_RFOSC) && (*pwOsc<=QSS_MAX_RFOSC))
					break;
			}
			
			// Not success, recalculate and try again
			{
				WORD wCapNew;
				
				wCapNew = InterpolateX(wCoeff, wCap, QSS_MAX_RFCAP, wCoefReal, Qssf2.CoefLo);
				if (wCapNew == wCap) // Interpolate doesn't work - stepping
				{
					if (wCoeff<wCoefReal)
						wCap++;	// Increase CAP to decrease vCoefReal
					else
						wCap--;
				}
				else
					wCap = wCapNew;
			}
			// Retry
			byRetry--;
		}
		else
		{
			// Write Cap failed - terminate
			wCap = QSS_MAX_RFCAP; //xx
			*pwOsc=QSS_MAX_RFOSC;  //xx
			break;
			//iRetry=0;
		}
	} // EndWhile

	*pwCap=wCap;
	if (byRetry==0)
		return(LVLS_CAPOSC_CALC_ERR);
	return(LVLS_NO_ERROR);
} // End CalculateRfCapOsc

⌨️ 快捷键说明

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