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

📄 predet.c

📁 DSP 5409 plc应用程序,调试通过,是用在电力线通讯上的演示程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
	//---- allocate a diagnostic array to pass to Matlab ----------
	#if DEBUGIT == DEBUG_GETFEQ
		diagArray = mxCreateDoubleMatrix(4, CARRIER_LEN, mxCOMPLEX);
		mxSetName(diagArray, "feq_diag");
		diag.r = mxGetPr(diagArray);
		diag.i = mxGetPi(diagArray);
	#endif

	//-----------------------------------------------------------------
	//	calc the complex freq equalization value that is 
	//	multiplied with each carrier in the data frames
	//-----------------------------------------------------------------
	preamble = (iCplx *)distanceArray;	// get complex phase from txPhase data 
	getPrePhases( preamble, PreambleArray );
	pwrScaleFactor = numFramesAve << PWR_SCALE_SHIFT;
		
	for( n = 0; n < CARRIER_LEN; n++ )
	{								
		//------------------------------------------------
		//	(1.15 * 1.15) >> 12 = 2.30 >> 12 = 14.18 ==> -2.18
		//		so carrierPwr is 15-PWR_SHIFT bigger than a 1.15 number
		//-------------------------------------------------
		carrierPwr = iSquare(aveCarrier->re, PWR_SHIFT) 
				   + iSquare(aveCarrier->im, PWR_SHIFT)
				   + 1;										// make it at least 1
		if( carrierPwr < 0 )
		{
			PostErrorCode(0xBAE2, "getFreqEq", "preDet.c", "Overflowed carrier power");
		}
		if( carrierPwr < minPwr )
			minPwr = carrierPwr;

		#if DEBUGIT == DEBUG_GETFEQ
			*diag.r++ = (double)preamble->re;
			*diag.i++ = (double)preamble->im;

			*diag.r++ = (double)aveCarrier->re;
			*diag.i++ = (double)aveCarrier->im;

			*diag.r++ = (double)carrierPwr;
		#endif

		//---------------------------------------------------------
		//  Ideally we would multiply FEQ by numFramesAve/carrierPwr.
		//  But this means dividing by carrierPwr. Instead, find the 
		//  2^k closest to numFramesAve/carrierPwr and do a shift
		//  instead of the divide.
        //---------------------------------------------------------
		for( k = PWR_SCALE_SHIFT;  k > 1;  k-- )
		{
			if( carrierPwr > pwrScaleFactor )
                break;
            carrierPwr <<= 1;
		}

		if( k <= 1 )
		{
			#if COMPILE_MODE == MEX_COMPILE
				char	prtStr[80];
				//mexPrintf("aveCarrier = %d %+dj\ncarrierPwr = %d\npwrScaleFactor = %d\n",
				//		aveCarrier->re, aveCarrier->im, carrierPwr, pwrScaleFactor );
				diagData(symbolArray, CARRIER_LEN, "feqSymbols", diagICPLX);
				diagData(recSignalArray, RX_CIRC_BUFFER_LEN, "rxArray", diagI16);
				sprintf(prtStr, "Failed doing power scale factor.  numFramesAve = %d  aveCarrier = %d, %d",
						numFramesAve, aveCarrier->re, aveCarrier->im );
				PostErrorCode(0xBAD1, "getFreqEq", "preDet.c", prtStr);
			#endif
			//uStatus = 0xBAD1;
			PostErrorCode(0xBAD1, "getFreqEq", "preDet.c", "Failed doing power scale factor");
			#if SAVETRACE == TRUE
				SaveTraceData(0xBAD1);			//!!!DEBUG  Put a marker in the trace buffer
				SaveTraceData(n);				//!!!DEBUG  Put a marker in the trace buffer
				SaveTraceData((u16)carrierPwr);		//!!!DEBUG  Put a marker in the trace buffer
			#endif
		}

		shift = CARRIER_SCALE - (15-PWR_SHIFT) - k;		// 13-15+12-k = 10-k
		
		if( shift >= 0 )
		{
			carrierPwr  = aveCarrier->re * preamble->re;
			carrierPwr += aveCarrier->im * preamble->im;
			freqEq->re  = (i16)(carrierPwr << shift);
			carrierPwr  = aveCarrier->re * preamble->im;
			carrierPwr -= aveCarrier->im * preamble->re;
			freqEq->im  = (i16)(carrierPwr << shift);
		}
		else
		{
			shift = -shift;
			carrierPwr  = aveCarrier->re * preamble->re;
			carrierPwr += aveCarrier->im * preamble->im;
			freqEq->re  = (i16)(carrierPwr >> shift);
			carrierPwr  = aveCarrier->re * preamble->im;
			carrierPwr -= aveCarrier->im * preamble->re;
			freqEq->im  = (i16)(carrierPwr >> shift);
		}

		#if DEBUGIT == DEBUG_GETFEQ
			*diag.i++ = (double)shift;

			*diag.r++ = (double)freqEq->re;
			*diag.i++ = (double)freqEq->im;
		#endif

		aveCarrier++;
		freqEq++;
		preamble++;
 	}

	#if DEBUGIT == DEBUG_GETFEQ
		mexPutArray(diagArray, "caller");
	#endif
	
	return minPwr;
}
#endif


#if FEQ_NORM_TYPE == FEQ_NORM_LOOKUP		// Use lookup table to normalize
//==========================================================================================
// Function:		getFreqEq()
//
// Description: 	Frequency equalization calculation 
//					EQ = tx/rx = preamble / receive = Preamble / (aveCarrier/N) = N*P/A
//							where N is the number of FFT averages
//
//					complex math:
//						EQ = N/(ar*ar + ai*ai) * ((ar*pr + ai*pi) + j*(ar*pi - ai*pr))
//						   = invPwr * ((ar*pr + ai*pi) + j*(ar*pi - ai*pr))
//
// Revision History:
//==========================================================================================
#define	RES_LO		8
#define	RES_HI		11
#define	KSM_LO		9
#define	KSM_HI		15
#define INV_SHIFT	10
i16 getFreqEq( iCplx *freqEq, iCplx *aveCarrier, i16 numFramesAve )
{
	u16				n, c;					// loop counter, return code
	iCplx			*preamble;

	i32				carrierPwr, invPwr;		
	i16				minPwr = 0x7FFF;	// init to a big number

	static const i32		invLookupSlope[] = {
				  //-1024,  -256,  -85,  -43,  -26,  -17,  -12,   -9 };
					-8192, -2048, -683, -341, -205, -137,  -98,  -73 };
		static const i32		invLookupOffLo[] = {
				  //1536,  768,  427,  299,  230,  188,  158,  137 };
					6144, 3072, 1707, 1195,  922,  751,  634,  549 };
	static const i32		invLookupOffHi[] = {
				  //192,   96,   53,   37,   29,   23,   20,   17 };
					768,  384,  213,  149,  115,   94,   79,   69 };

	
	//---- allocate a diagnostic array to pass to Matlab ----------
	#if DEBUGIT == DEBUG_GETFEQ
		diagArray = mxCreateDoubleMatrix(4, CARRIER_LEN, mxCOMPLEX);
		mxSetName(diagArray, "feq_diag");
		diag.r = mxGetPr(diagArray);
		diag.i = mxGetPi(diagArray);
	#endif

	//-----------------------------------------------------------------
	//	calc the complex freq equalization value that is 
	//	multiplied with each carrier in the data frames
	//-----------------------------------------------------------------
	preamble = (iCplx *)distanceArray;	// get complex phase from txPhase data 
	getPrePhases( preamble, PreambleArray );

	//---- calc frequency equalization for each carrier ---------------
	for( n = 0; n < CARRIER_LEN; n++ )
	{								
		carrierPwr = iSquare(aveCarrier->re, PWR_SHIFT)			// get the signal power
				   + iSquare(aveCarrier->im, PWR_SHIFT);
		if( carrierPwr < 0 )
		{
			PostErrorCode(0xBAE2, "getFreqEq", "preDet.c", "Overflowed carrier power");
		}
		if( carrierPwr < minPwr )
			minPwr = carrierPwr;

		//---- calculate 1/carrierPwr using a table lookup -----------
		if( carrierPwr < (1<<RES_HI) )
		{
			c = carrierPwr >> RES_LO;
			invPwr = (invLookupSlope[c]*carrierPwr) >> KSM_LO;
			invPwr += invLookupOffLo[c];
		}
		else
		{
			c = carrierPwr >> RES_HI;
			invPwr = (invLookupSlope[c]*carrierPwr) >> KSM_HI;
			invPwr += invLookupOffHi[c];
		}
		invPwr *= numFramesAve;

		//---- now to the complex math to get FEQ values -------------
		freqEq->re  = aveCarrier->re * preamble->re;
		freqEq->re += aveCarrier->im * preamble->im;
		freqEq->re  = (i16)(( invPwr * (i32)freqEq->re ) >> INV_SHIFT );

		freqEq->im  = aveCarrier->re * preamble->im;
		freqEq->im -= aveCarrier->im * preamble->re;
		freqEq->im  = (i16)(( invPwr * (i32)freqEq->im ) >> INV_SHIFT );
		
		#if DEBUGIT == DEBUG_GETFEQ
			*diag.r++ = (double)preamble->re;
			*diag.i++ = (double)preamble->im;

			*diag.r++ = (double)aveCarrier->re;
			*diag.i++ = (double)aveCarrier->im;

			*diag.r++ = (double)carrierPwr;
			*diag.i++ = (double)invPwr;

			*diag.r++ = (double)freqEq->re;
			*diag.i++ = (double)freqEq->im;
		#endif

		aveCarrier++;
		freqEq++;
		preamble++;
 	}

	#if DEBUGIT == DEBUG_GETFEQ
		mexPutArray(diagArray, "caller");
	#endif
	
	return minPwr;
}
#endif


#if FEQ_NORM_TYPE == FEQ_NORM_NONE		// don't normalize
//==========================================================================================
// Function:		getFreqEq()
//
// Description: 	Frequency equalization calculation 
//
// Revision History:
//==========================================================================================
i16 getFreqEq( iCplx *freqEq, iCplx *aveCarrier, i16 numFramesAve )
{
	u16				n;					// loop counter, return code
	iCplx			*preamble;
	
	
	//---- allocate a diagnostic array to pass to Matlab ----------
	#if DEBUGIT == DEBUG_GETFEQ
		diagArray = mxCreateDoubleMatrix(4, CARRIER_LEN, mxCOMPLEX);
		mxSetName(diagArray, "feq_diag");
		diag.r = mxGetPr(diagArray);
		diag.i = mxGetPi(diagArray);
	#endif

	//-----------------------------------------------------------------
	//	calc the complex freq equalization value that is 
	//	multiplied with each carrier in the data frames
	//-----------------------------------------------------------------
	preamble = (iCplx *)distanceArray;	// get complex phase from txPhase data 
	getPrePhases( preamble, PreambleArray );
	//pwrScaleFactor = numFramesAve << PWR_SCALE_SHIFT;
		
	for( n = 0; n < CARRIER_LEN; n++ )
	{	
		freqEq->re = 1024;
		freqEq->im = 0;

		#if DEBUGIT == DEBUG_GETFEQ
		{
			i32				carrierPwr;		

			*diag.r++ = (double)preamble->re;
			*diag.i++ = (double)preamble->im;

			*diag.r++ = (double)aveCarrier->re;
			*diag.i++ = (double)aveCarrier->im;

			carrierPwr = iSquare(aveCarrier->re, PWR_SHIFT) 
					   + iSquare(aveCarrier->im, PWR_SHIFT);

			*diag.r++ = (double)carrierPwr;
			*diag.i++ = (double)FEQ_SHIFT;

			*diag.r++ = (double)freqEq->re;
			*diag.i++ = (double)freqEq->im;
		}
		#endif

		aveCarrier++;
		freqEq++;
		preamble++;
 	}

	#if DEBUGIT == DEBUG_GETFEQ
		mexPutArray(diagArray, "caller");
	#endif
	
	return 0x2000;
}
#endif

⌨️ 快捷键说明

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