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

📄 datadet.c

📁 DSP 5409 plc应用程序,调试通过,是用在电力线通讯上的演示程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
//==========================================================================================
// Filename:		dataDet.c
//
// Description:		Functions for data detection in an OFDM power line modem.
//
// Copyright (C) 2000 - 2003 Texas Instruments Incorporated
// Texas Instruments Proprietary Information
// Use subject to terms and conditions of TI Software License Agreement
//
// Revision History:
//========================================================================
#include "ofdm_modem.h"
#if COMPILE_MODE == DSP_COMPILE
	#include "intr.h"		// Needed for interrupt enable/disable macros
#endif

//==============================================================
//	global vars for this module
//===============================================================
iCplx			prevCarrier1;  	// symbol from previous frame first carrier


//==============================================================
//	function prototypes for this module
//===============================================================
void aveDistance( MetricType *distance, iCplx *symbols );


//==========================================================================================
// Function:		readDataFrames()
//
// Description:		Main data detection function. 	
//
// Revision History:
//==========================================================================================
u16 readDataFrames(	u16 *pUserData, i16 *recPtr, iCplx *freqEq )
{
	u16				block, frame;
	u16				parityGood;
	MetricType		*distance;

	//---- allocate a diagnostic array to pass to Matlab ----------
	#if DEBUGIT == DEBUG_VITERBI_STATES
		diagArray = mxCreateDoubleMatrix(2, NUM_SYMBOLS*VITERBI_NUM_STATES, mxREAL);
		mxSetName(diagArray, "vStates");
		diag.r = mxGetPr(diagArray);
	#endif
	#if DEBUGIT == DEBUG_DISTANCE
		diagArray = mxCreateDoubleMatrix(2, NUM_SYMBOLS, mxREAL);
		mxSetName(diagArray, "vDist");
		diag.r = mxGetPr(diagArray);
	#endif
	#if DEBUGIT == DEBUG_DISTANCE2
		diagArray = mxCreateDoubleMatrix(8, NUM_SYMBOLS*DATA_FRAMES_PER_BLOCK, mxREAL);
		mxSetName(diagArray, "vDist2");
		diag.r = mxGetPr(diagArray);
	#endif
	#if DEBUGIT == DEBUG_DATAFFT
		diagArray = mxCreateDoubleMatrix(2, NUM_SYMBOLS*DATA_FRAMES_PER_BLOCK, mxCOMPLEX);
		mxSetName(diagArray, "dataFFT");
		diag.r = mxGetPr(diagArray);
		diag.i = mxGetPi(diagArray);
	#endif
	#if DEBUGIT == DEBUG_CIRCFFT
		diagArray = mxCreateDoubleMatrix(2*FFT_LEN, DATA_FRAMES_PER_BLOCK*NUM_DATA_BLOCKS, mxCOMPLEX);
		mxSetName(diagArray, "dataFFT");
		diag.r = mxGetPr(diagArray);
		diag.i = mxGetPi(diagArray);
	#endif

	distance = distanceArray;

	//prevCarrier1.re = VITERBI_CAR1_RE*DATA_FRAMES_PER_BLOCK;	// init for first carrier
	//prevCarrier1.im = VITERBI_CAR1_IM*DATA_FRAMES_PER_BLOCK;
	prevCarrier1.re = VITERBI_CAR1_RE;	// init for first carrier
	prevCarrier1.im = VITERBI_CAR1_IM;

	initPathMemory(pUserData); 			// init path memory and path metrics

	#if (SAVESYMBOLS == TRUE)			// Clear the symbol debug array
		if( uTraceEnable == TRUE )
		{
			uTraceIndex = 0;
		}
	#endif

	//---- process each data frame ----------------------------
	for( block = 0; block < NUM_DATA_BLOCKS;  block++ )
	{
		memset( distance, 0, 2*CARRIER_LEN*sizeof(MetricType) );	// reset distance array
		
		for( frame = 0; frame < DATA_FRAMES_PER_BLOCK;  frame++ )
		{	
			recPtr = dataFFT( symbolArray, recPtr, freqEq ); 	// read a frame and adv the pointer
			aveDistance( distance + frame*2*SYMBOL_OFFSET, symbolArray );

			// If this is the last frame, set up the variables so the periodic interrupt 
			// functions can start doing AGC operations and looking for the next packet,
			// while we finish processing this packet.
			if (  (block == (NUM_DATA_BLOCKS-1)) 
			    &&(frame == (DATA_FRAMES_PER_BLOCK-1)) )
			{
				agcState = AgcIdle;			// change back to idle mode
				SNRflag = -3;				// Do not look for preambles yet
				recSignal = recPtr;			// Set the global recSignal pointer to the end of the data we have just received

				#if SAVETRACE == TRUE
					SaveTraceData((u16)(0xDB00 + (block<<4) + frame));	//!!!DEBUG  Put a marker in the trace buffer (Shouldn't need to cast this, but Visual C++ complains)
					SaveTraceData((u16)recPtr);							//!!!DEBUG  Put a marker in the trace buffer
					SaveTraceData((u16)ReadRxDMAPointer());				//!!!DEBUG  Put a marker in the trace 
				#endif
			}
		}

		viterbiDecodeFrame( distance, CARRIER_LEN );
	}

	agcState = AgcIdle;			// change back to idle mode
	preambleDetCount = 0;		// restart counter
	prevSnrSample = ReadRxDMAPointer() - recSignalArray;	// Let SNR calc re-start here					
	SNRflag = 0;				// Allow looking for preambles
	#if SAVETRACE == TRUE
		SaveTraceData((u16)(0xDC00 + (block<<4) + frame));	//!!!DEBUG  Put a marker in the trace buffer (Shouldn't need to cast this, but Visual C++ complains)
		SaveTraceData((u16)recPtr);							//!!!DEBUG  Put a marker in the trace buffer
		SaveTraceData((u16)ReadRxDMAPointer());				//!!!DEBUG  Put a marker in the trace 
	#endif

	flushPathMemoryV();
	//diagData(pUserData, DATA_BUFFER_LEN, "rxScramble", diagU16);

	scramble(pUserData, DATA_BUFFER_LEN);			// unscramble the whole buffer
	//diagData(pUserData, DATA_BUFFER_LEN, "rxData", diagU16);

	parityGood = compareParityCheckBytes(pUserData, NUM_USER_BYTES);

	#if ( ( DEBUGIT == DEBUG_VITERBI_STATES ) \
		|| ( DEBUGIT == DEBUG_DISTANCE ) \
		|| ( DEBUGIT == DEBUG_DISTANCE2 ) \
		|| ( DEBUGIT == DEBUG_DATAFFT ) \
		|| ( DEBUGIT == DEBUG_CIRCFFT ) )
		mexPutArray(diagArray, "caller");
	#endif

	return parityGood;
}


//==========================================================================================
// Function:		aveDistance(N)
//
// Description: 	Calculate the geometric distance from the received complex symbol to each
//					of the 4 possible differential phase constelation values.  Since it turns 
//					out that the second order parts of the distance equations are the same 
//					for each case, the distance metric is a linear equation.  Since this equation 
//					is negative, the branch with the closest distance is the most positive one.
//						distance[0] = p.re * c.re + p.im * c.im;		// 0 deg		
//						distance[1] = p.re * c.im - p.im * c.re;		// 90 deg
//						distance[2] = -distance[0];						// 180 deg
//						distance[3] = -distance[1]; 					// -90 deg
//					Only the first two values are saved.  The distance meteic is summed for
//					each repeated symbol in a block.
//
//					Distance can also be described as:
//						distance[0] = AmpPrev*AmpCurr*cos(dPhase) / 2^shift
//						distance[1] = AmpPrev*AmpCurr*sin(dPhase) / 2^shift
//
// Revision History:
//==========================================================================================
void aveDistance( MetricType *distance, iCplx *symbols )
{
	#if METRIC_OFFSET == 0
		#define	DIST_LIMIT	0x3FFF
	#else
		#define	DIST_LIMIT	0x7FFF
	#endif

	i16				ncar;
	iCplx			prevSymbol;		// working previous symbol value
	iCplx			currSymbol;		// working current symbol value
	i16				dist0, dist1;
	MetricType		*bufEnd;

	bufEnd = distanceArray;
	bufEnd += 2*CARRIER_LEN;

	//---- handle the first subcarrier different ---------------------------------
	prevSymbol.re = prevCarrier1.re;
	prevSymbol.im = prevCarrier1.im;
	currSymbol.re = symbols->re;
	currSymbol.im = (symbols++)->im;

	prevCarrier1.re = currSymbol.re;
	prevCarrier1.im = currSymbol.im;

	//---- loop thourgh the rest of the subcarriers ---------------------------------
	for( ncar = 0; ncar < CARRIER_LEN; ncar++ )
	{
		dist0   = ( ((i32)currSymbol.re * (i32)prevSymbol.re) 	
	          	+ ((i32)currSymbol.im * (i32)prevSymbol.im) )	
	           	>> VITERBI_DISTANCE_SHIFT;				// 0 deg

		dist1   = ( ((i32)currSymbol.im * (i32)prevSymbol.re)	
		 		- ((i32)currSymbol.re * (i32)prevSymbol.im) )
	  			>> VITERBI_DISTANCE_SHIFT;				// 90 deg

		//---- diagnostic -----------------------
		#if DEBUGIT == DEBUG_DISTANCE2
			*diag.r++ = (double)prevSymbol.re;
			*diag.r++ = (double)prevSymbol.im;
			*diag.r++ = (double)currSymbol.re;
			*diag.r++ = (double)currSymbol.im;
			*diag.r++ = (double)dist0;
			*diag.r++ = (double)dist1;
		#endif

		*distance += dist0;							// for debug!	
		if( abs(*distance) > DIST_LIMIT )				//
		{
			PostErrorCode(0xBAD3, "aveDistance", "dataDet.c", "Overran distance metric");
			#if COMPILE_MODE == MEX_COMPILE
				mexPrintf("Distance = %d\n", *distance );
			#endif
		}

 		#if DEBUGIT == DEBUG_DISTANCE2
			*diag.r++ = (double)*distance;
		#endif
		distance++;									//

		*distance += dist1;							//
		if( abs(*distance) > DIST_LIMIT )				//
		{
			PostErrorCode(0xBAD3, "aveDistance", "dataDet.c", "Overran distance metric");
			#if COMPILE_MODE == MEX_COMPILE
				mexPrintf("Distance = %d\n", *distance );
			#endif
		}

		#if DEBUGIT == DEBUG_DISTANCE2
			*diag.r++ = (double)*distance;
		#endif
		distance++;									//

		if( distance >= bufEnd )
			distance = distanceArray;

		prevSymbol.re = currSymbol.re;		// get next complex symbol
		prevSymbol.im = currSymbol.im;

⌨️ 快捷键说明

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