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

📄 predet.c

📁 DSP 5409 plc应用程序,调试通过,是用在电力线通讯上的演示程序.
💻 C
📖 第 1 页 / 共 3 页
字号:
//					When the sum of phase differences is sufficiently large we can say that
//					we've found the sync frame since it is coded 180 degrees different from
//					the preamble frames.
//
// Revision History:
//==========================================================================================
i16 AlignPhaseCompare(i16 carLen, iCplx *prev, iCplx *curr )
{
	int 		n;
	i16 		prevdif, prevsum;
	i16			bit1, bit0;
	i16 		dPhase;
	i16			phaseError = 0;
	i32			acc;

	static i16	phasemap[] = {2, -1, 1, 0 };


	#if DEBUGIT == DEBUG_PHASE
		char	prtStr[255];
		char	numStr[50];
		strcpy(prtStr,"phase diff:");
	#endif

	for( n = 0 ; n < carLen ; n++ )
 	{
		#if DEBUGIT == DEBUG_PHASE
			sprintf(numStr, "%5d%5d%5d%5d ", prev->re, prev->im, curr->re, curr->im );
			strcat(prtStr, numStr);
		#endif

		prevdif = prev->re - prev->im;
		prevsum = prev->re + prev->im;

		acc  =  (i32)(prevdif) * (i32)(curr->re);
		acc +=  (i32)(prevsum) * (i32)(curr->im);
		bit1 = acc > 0;

		acc  =  (i32)(prevsum) * (i32)(curr->re);
		acc -=  (i32)(prevdif) * (i32)(curr->im);
		bit0 = acc > 0;

		dPhase = phasemap[ (bit1<<1) + bit0 ];	// decoded phase

		phaseError += abs(dPhase);	// sum of differences

		prev++;						// point to next carriers
		curr++;

		#if DEBUGIT == DEBUG_PHASE
			sprintf(numStr, "%3d   ", dPhase);
			strcat(prtStr, numStr);
		#endif
	}

	#if DEBUGIT == DEBUG_PHASE
		strcat(prtStr, "\n");
		mexPrintf("%s",prtStr);
	#endif

	return phaseError;
}


//==========================================================================================
// Function:		getFrameStartFromImpulse()
//
// Description: 	Calculate the impulse response from the averaged frequency values.  
//					The maximum point in the impulse response corresponds to the beginning
//					of the frame.
//
//					impulse	= received/transmitted = Y/X = [y0 y1...yN] ./ [x0 x1...xN]
//				   		    = [y0*conj(x0)...yN*conj(xN)] ./ [x0*conj(x0)...xN*conj(xN)]  
//				           	= C*[y0*conj(x0)...yN*conj(xN)]
//	
//					Uses symbolArray (data passed in) and phaseEqArray as the impulse array 
//
// Revision History:
//==========================================================================================
i16 getFrameStartFromImpulse( iCplx *aveCarrier)
{
	i16				n;					// loop counter, return code
	i16				sample;				// sample number in frame
	u16				impulseSample;		// these three variables are used to 
	u16				maxValue;			// find the max in the impulse response
	i16				maxSample;			// true frame start that is returned

	iCplx			*fftBuf;			// pointer to fft array
	iCplx			*aveCar;			// pointer current and average complex data
	iCplx			*preamble;			// pointer to preamble pattern
	iCplx			*impulse;			// working pointer to complex data


	//---- init pointers ---------------------
	aveCar = aveCarrier;
	fftBuf = fftArray;
	preamble = (iCplx *)distanceArray;	// get complex phase from txPhase data 
	impulse = phaseEqArray;


	getPrePhases( preamble, PreambleArray );

	//---- calc the impulse response and put it in the ifft bins -------
	for( n = 0; n < CARRIER_LEN; n++ )
	{				
		impulse->re		= (aveCar->re * preamble->re)
						+ (aveCar->im * preamble->im);

		(impulse++)->im	= (aveCar->im * preamble->re)
					  	- (aveCar->re * preamble->im);
		aveCar++;
		preamble++;
	}

	//---- Fill the carriers for an IFFT, then invert.  Result is a time signal that
	//---- looks like a correlation, with a big spike where the frame offset is best.	
	// Note: When doing IFFT operations, there is scaling on both the fillCarrier() function
	// and the cifft() function.  Here we will scale up by +2 in fillCarrier(), then down
	// by -8 in cifft().  This gives us the least  quantization on the input terms without
	// rolling over the cifft output.
	// ( Shift of +2 works well.  +3 seems to work but values are close to rolling over.)
	// Contrast this with the transmit function.  There the phase terms only have four
	// unique, known values, so there we shift down before doing cifft().

	fillCarriers( fftArray, phaseEqArray, +2 );		// Fill the carriers in freq domain
	DebugDelay();									// Flush C54x if in debug mode.
	//diagData(fftArray, FFT_LEN, "impulseF", diagICPLX);

	#if COMPILE_MODE == MEX_COMPILE
		cifft( (DATA *)(fftArray), FFT_LEN, 0 );		// Invert to get a time-domain "correlation"
	#else
		cifft( (DATA *)(fftArray), FFT_LEN, 1 );		// Invert to get a time-domain "correlation"
	#endif
	DebugDelay();									// Flush C54x if in debug mode.
	
	#if DEBUGIT == DEBUG_FRAME
		diagData(aveCarrier, CARRIER_LEN, "avecar", diagICPLX);
		diagData((iCplx *)distanceArray, CARRIER_LEN, "impulseP", diagICPLX);	// preamble
		diagData(phaseEqArray, CARRIER_LEN, "impulseF", diagICPLX);
		diagData(fftBuf, FFT_LEN, "impulseT", diagICPLX);
	#endif
	
	//---- Find biggest sample.  Its index indicates offset from beginning of frame --------
	fftBuf = fftArray;		// point to the real samples
	maxValue  = 0;			
	for( sample = 0 ; sample < FFT_LEN ; sample++ )
	{
		impulseSample = abs(fftBuf->re);
		fftBuf++;

		if( impulseSample > maxValue )	// find the max sample
		{
			maxSample = sample;
			maxValue  = impulseSample;
		}
	}

	#if SAVETRACE == TRUE
		SaveTraceData(0xDDDD);					//!!!DEBUG  Put a marker in the trace buffer
		SaveTraceData((u16)maxSample);			//!!!DEBUG  Put a marker in the trace buffer
		SaveTraceData((u16)maxValue);			//!!!DEBUG  Put a marker in the trace buffer
	#endif

 	return maxSample;
}
	 

#if FEQ_NORM_TYPE == FEQ_NORM_DIV		// Use division to calculate freq equalization
//==========================================================================================
// Function:		getFreqEq()
//
// Description: 	Frequency equalization calculation 
//					EQ = tx/rx = preamble / receive = Preamble / (aveCarrier/N) = N*P/A
//
//					complex math:
//						EQ = N/(ar*ar + ai*ai) * ((ar*pr + ai*pi) + j*(ar*pi - ai*pr))
//							where N is the number of FFT averages
//
// Revision History:
//==========================================================================================
#define 	FEQ_SHIFT_DIV		9
//#define 	FEQ_SHIFT_DIV		7
i16 getFreqEq( iCplx *freqEq, iCplx *aveCarrier, i16 numFramesAve )
{
	u16				n;					// loop counter, return code
	iCplx			*preamble;

	i32				carrierPwr;		
	static i32				feqNum;

	i32				minPwr = 0x7FFFFFFF;	// init to a big number

	
	//---- allocate a diagnostic array to pass to Matlab ----------
	#if DEBUGIT == DEBUG_GETFEQ
		diagArray = mxCreateDoubleMatrix(5, 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.
	//  Use distance array as a container for cmplex preamble symbols.
	//-----------------------------------------------------------------
	preamble = (iCplx *)distanceArray;	// get complex phase from txPhase data 
	getPrePhases( preamble, PreambleArray );
		
	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( carrierPwr < WORST_PWR_LIMIT )
		{
			DebugDelay();
			DebugDelay();
		}

				
		#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)numFramesAve;
		#endif

		//---------------------------------------------------------
		//  now multiply FEQ by numFramesAve/carrierPwr.
        //---------------------------------------------------------
		DebugDelay();
		feqNum      = ((i32)(aveCarrier->re * preamble->re)) << FEQ_SHIFT_DIV;
		DebugDelay();
		feqNum     += ((i32)(aveCarrier->im * preamble->im)) << FEQ_SHIFT_DIV;
		DebugDelay();
		freqEq->re  = (i16)(numFramesAve * feqNum  / carrierPwr);
		#if DEBUGIT == DEBUG_GETFEQ
			*diag.r++ = (double)freqEq->re;
			*diag.r++ = (double)feqNum;
		#endif

		DebugDelay();
		feqNum      = ((i32)(aveCarrier->re * preamble->im)) << FEQ_SHIFT_DIV;
		DebugDelay();
		feqNum     -= ((i32)(aveCarrier->im * preamble->re)) << FEQ_SHIFT_DIV;
		DebugDelay();
		freqEq->im  = (i16)(numFramesAve * feqNum  / carrierPwr);
		#if DEBUGIT == DEBUG_GETFEQ
			*diag.i++ = (double)freqEq->im;
			*diag.i++ = (double)feqNum;
		#endif

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

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

#if FEQ_NORM_TYPE == FEQ_NORM_BIN		// Use power-of-2 shifting to approximate freq equalization
//==========================================================================================
// Function:		getFreqEq()
//
// Description: 	Frequency equalization calculation 
//					EQ = tx/rx = preamble / receive = Preamble / (aveCarrier/N) = N*P/A
//
//					complex math:
//						EQ = N/(ar*ar + ai*ai) * ((ar*pr + ai*pi) + j*(ar*pi - ai*pr))
//							where N is the number of FFT averages
//
// Revision History:
//==========================================================================================
i16 getFreqEq( iCplx *freqEq, iCplx *aveCarrier, i16 numFramesAve )
{
	u16				n;					// loop counter, return code
	iCplx			*preamble;

	i32				carrierPwr;		
	i16				minPwr = 0x7FFF;	// init to a big number
	i16				pwrScaleFactor;
	i16				k, shift;
	
	

⌨️ 快捷键说明

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