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

📄 ofdm_fft.c

📁 DSP 5409 plc应用程序,调试通过,是用在电力线通讯上的演示程序.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*=================================================================================
Filename:			ofdm_fft.c

 Description:		function calls for ifft and fft to Matlab

 Copyright (C) 2002 Texas Instruments Incorporated
 Texas Instruments Proprietary Information
 Use subject to terms and conditions of TI Software License Agreement

 Revision History:
========================================================================*/
#include "ofdm_modem.h"

// IGNORE_RX_DMA:  When defined, the circ_fft() function will ignore the hardware DMA 
//  pointer and will copy directly from memory.	 Useful for debugging.
// Comment out next line for normal operation.
//#define	IGNORE_RX_DMA

/*
#if FFT_LEN == 256
	#define	FFT_LEN_SHIFT		8
#elif FFT_LEN == 128
	#define	FFT_LEN_SHIFT		7
#else
	#error unexpected FFT_LEN
#endif
*/

//==========================================================================================
// Function:		fillCarriers()
//
// Description: 	This function fills in the carrier array.
//
// Revision History:
//==========================================================================================
void fillCarriers( iCplx  *fftBuf, const iCplx *carriers, i16 scale )

{
	i16				n;					// loop counter
	DATA			*pfftBuf;			// working pointer
	i16				scaleDn;			// shift right
	
	//-------------------------------------------------------------
	pfftBuf = (DATA *)(fftBuf);	// point to start of fft buffer

	for( n = 0; n < CARRIER_LOW; n++ )	
	{
		*pfftBuf++ = 0;		// zero out the non-carrier bins, real part
		*pfftBuf++ = 0;		// imag part
	}

	if( scale < 0 )
	{
		scaleDn  = -scale;
		for( n = 0; n < CARRIER_LEN; n++ )	
		{	
			*pfftBuf++ = carriers[n].re >> scaleDn;	// put the carriers in the ifft bins
			*pfftBuf++ = carriers[n].im >> scaleDn;
		}
	}
	else
	{
		for( n = 0; n < CARRIER_LEN; n++ )	
		{	
			*pfftBuf++ = carriers[n].re << scale;	// put the carriers in the ifft bins
			*pfftBuf++ = carriers[n].im << scale;
		}
	}
	
	for( n = CARRIER_HIGH+1; n < FFT_LEN-CARRIER_HIGH; n++ )
	{
		*pfftBuf++ = 0;					// zero out middle bins
		*pfftBuf++ = 0;
	}

	if( scale < 0 )
	{
		for( n = CARRIER_LEN-1; n >= 0; n-- )	
		{	
			*pfftBuf++ =  carriers[n].re >> scaleDn; 	// calc the conj of the carriers
			*pfftBuf++ = -carriers[n].im >> scaleDn; 	// and put in the ifft bins
		}
	}
	else
	{
		for( n = CARRIER_LEN-1; n >= 0; n-- )	
		{	
			*pfftBuf++ =  carriers[n].re << scale; 		// calc the conj of the carriers
			*pfftBuf++ = -carriers[n].im << scale; 		// and put in the ifft bins
		}
	}
	
	for( n = FFT_LEN-CARRIER_LOW+1; n < FFT_LEN; n++ )
	{
		*pfftBuf++ = 0;					// zero out the rest of the bins
		*pfftBuf++ = 0;
	}

	DebugDelay();						// Flush C54x if in debug mode.

	#if COMPILE_MODE == DSP_COMPILE
		pfftBuf = (DATA *)(fftBuf);	// point to start of fft buffer
		cbrev(pfftBuf, pfftBuf, FFT_LEN);
	#endif

	DebugDelay();						// Flush C54x if in debug mode.

}


//==========================================================================================
// Function:		WrapRecPointer()
//
// Description: 	This function handles wraparound at the beginning and end of the
//					receive buffer.
//
// Revision History:
//==========================================================================================
i16* WrapRecPtr(i16* recPtr, i16 offset) 
{
	i32	tempPtr;
	tempPtr = recPtr - recSignalArray;
	tempPtr += offset;
	if (tempPtr < 0)
	{
		tempPtr += RX_CIRC_BUFFER_LEN;
	}
	if (tempPtr > RX_CIRC_BUFFER_LEN)
	{
		tempPtr -= RX_CIRC_BUFFER_LEN;
	}

	return(recSignalArray + tempPtr);
}


#if 1
//==========================================================================================
// Function:		FillFFTBuff2()
//
// Description: 	This function copies a block of data from the receive DMA buffer to 
//					FFT buffer, properly handling wraparound at the end of the rx buffer.
//
// Revision History:
//==========================================================================================
i16* FillFFTBuff2(DATA* dest, i16* recStart, i16* recEnd)
{
	u16 		segmentLen;
	#if	(AFE_RX_FORMAT == 24)
		u16		i;				// Generic loop counter
	#endif

	if (recEnd > recStart)	// Copy in one contigous block
	{
		segmentLen = recEnd - recStart;
		#ifndef	IGNORE_RX_DMA
			WaitForRxBufferFree(recStart, segmentLen);
		#endif

		#if	(AFE_RX_FORMAT == 16)
			memcpy(dest, recStart, segmentLen*sizeof(DATA) );
			dest += segmentLen;
		#else
			for (i=0; i<segmentLen/RX_SRC_INC; i++)
			{
				*dest++ = *recStart++;		// Copy source to destination
				recStart++;					// Increment the source pointer one extra time
			}
		#endif

	}
	else				  	// Wrapped around end of buffer: handle in two pieces
	{
		// First piece: Copy from near end of rec buffer to beginning of fft buffer
		segmentLen = (recSignalArray+RX_CIRC_BUFFER_LEN) - recStart;
		#ifndef	IGNORE_RX_DMA
			WaitForRxBufferFree(recStart, segmentLen);
		#endif

		#if	(AFE_RX_FORMAT == 16)
			memcpy(dest, recStart, segmentLen*sizeof(DATA) );
			dest += segmentLen;
		#else
			for (i=0; i<segmentLen/RX_SRC_INC; i++)
			{
				*dest++ = *recStart++;		// Copy source to destination
				recStart++;					// Increment the source pointer one extra time
			}
		#endif


		// Second piece: Copy from beginning of rec buffer to middle of fft buffer
		recStart = recSignalArray;
		segmentLen = recEnd - recSignalArray;
		#ifndef	IGNORE_RX_DMA
			WaitForRxBufferFree(recStart, segmentLen);
		#endif

		#if	(AFE_RX_FORMAT == 16)
			memcpy(dest, recStart, segmentLen*sizeof(DATA) );
			dest += segmentLen;
		#else
			for (i=0; i<segmentLen/RX_SRC_INC; i++)
			{
				*dest++ = *recStart++;		// Copy source to destination
				recStart++;					// Increment the source pointer one extra time
			}
		#endif

	}

	return(recEnd);
}



#else

/*FILL_CNT*///==========================================================================================
/*FILL_CNT*/// Function:		FillFFTBuff2()
/*FILL_CNT*///
/*FILL_CNT*/// Description: 	This function copies a block of data from the receive DMA buffer to 
/*FILL_CNT*///					FFT buffer, properly handling wraparound at the end of the rx buffer.
/*FILL_CNT*///
/*FILL_CNT*/// Revision History:
/*FILL_CNT*/// 04/14/03	HEM		New function.
/*FILL_CNT*/// 05/14/03	HEM		New arguments: Use start and count instead of start and end.
/*FILL_CNT*///==========================================================================================
/*FILL_CNT*///i16* FillFFTBuff2(DATA* dest, i16* recStart, i16* recEnd)
/*FILL_CNT*/i16* FillFFTBuff2(DATA* pDest, i16* pSrc, i16 iCnt)
/*FILL_CNT*/{
/*FILL_CNT*/	i16*	pStart;
/*FILL_CNT*/	i16*	pEnd;	
/*FILL_CNT*/	u16		segmentLen;
/*FILL_CNT*/	u16		i;				// Generic loop counter
/*FILL_CNT*/
/*FILL_CNT*/
/*FILL_CNT*///	#define ST1	*(volatile unsigned int*)0x07	// Needed for XF()
/*FILL_CNT*///	SetXF();					// Turn on XF flag for debug
/*FILL_CNT*///	Delay1us();
/*FILL_CNT*///	ClearXF();					// Turn off XF flag for debug
/*FILL_CNT*///	Delay1us();
/*FILL_CNT*///	SetXF();					// Turn on XF flag for debug
/*FILL_CNT*/
/*FILL_CNT*/	// Calculate the start and end location
/*FILL_CNT*/	if (iCnt < 0)
/*FILL_CNT*/	{
/*FILL_CNT*/		pStart = WrapRecPtr(pSrc, iCnt);
/*FILL_CNT*/		pEnd = pSrc;
/*FILL_CNT*/	}
/*FILL_CNT*/	else
/*FILL_CNT*/	{
/*FILL_CNT*/		pStart = pSrc;
/*FILL_CNT*/		pEnd = WrapRecPtr(pSrc, iCnt);
/*FILL_CNT*/	}
/*FILL_CNT*/
/*FILL_CNT*/	// Copy the data from source to destination
/*FILL_CNT*/	if (pEnd > pStart)	// Copy in one contigous block
/*FILL_CNT*/	{
/*FILL_CNT*/		segmentLen = pEnd - pStart;
/*FILL_CNT*/		#ifndef	IGNORE_RX_DMA
/*FILL_CNT*/			WaitForRxBufferFree(pStart, segmentLen);
/*FILL_CNT*/		#endif
/*FILL_CNT*///DUAL		memcpy(dest, recStart, segmentLen*sizeof(DATA) );
/*FILL_CNT*/		for (i=0; i<segmentLen; i++)
/*FILL_CNT*/		{
/*FILL_CNT*/			*pDest++ = *pStart;		// Copy source to destination
/*FILL_CNT*/			pStart += SRC_INC;		// Increment the source pointer by the required amount
/*FILL_CNT*/		}
/*FILL_CNT*/
/*FILL_CNT*/		#if SAVETRACE == TRUE
/*FILL_CNT*///			SaveTraceData((u16)dest);
/*FILL_CNT*///			SaveTraceData((u16)recStart);
/*FILL_CNT*///			SaveTraceData((u16)segmentLen);
/*FILL_CNT*/		#endif
/*FILL_CNT*/	}
/*FILL_CNT*/	else				  	// Wrapped around end of buffer: handle in two pieces
/*FILL_CNT*/	{
/*FILL_CNT*/		// First piece: Copy from near end of rec buffer to beginning of fft buffer
/*FILL_CNT*/		segmentLen = (recSignalArray+RX_CIRC_BUFFER_LEN) - pStart;
/*FILL_CNT*/		#ifndef	IGNORE_RX_DMA
/*FILL_CNT*/			WaitForRxBufferFree(pStart, segmentLen);
/*FILL_CNT*/		#endif
/*FILL_CNT*///DUAL		memcpy(dest, recStart, segmentLen*sizeof(DATA) );
/*FILL_CNT*/		for (i=0; i<segmentLen; i++)
/*FILL_CNT*/		{
/*FILL_CNT*/			*pDest++ = *pStart;		// Copy source to destination
/*FILL_CNT*/			pStart += SRC_INC;		// Increment the source pointer by the required amount
/*FILL_CNT*/		}
/*FILL_CNT*///WRAP		#if SAVETRACE == TRUE
/*FILL_CNT*///WRAP			SaveTraceData((u16)dest);
/*FILL_CNT*///WRAP			SaveTraceData((u16)recStart);
/*FILL_CNT*///WRAP			SaveTraceData((u16)segmentLen);
/*FILL_CNT*///WRAP		#endif
/*FILL_CNT*/
/*FILL_CNT*/		// Second piece: Copy from beginning of rec buffer to middle of fft buffer
/*FILL_CNT*/		pDest += segmentLen;
/*FILL_CNT*/		segmentLen = pEnd - recSignalArray;
/*FILL_CNT*/		#ifndef	IGNORE_RX_DMA
/*FILL_CNT*/			WaitForRxBufferFree(recSignalArray, segmentLen);
/*FILL_CNT*/		#endif
/*FILL_CNT*///DUAL		memcpy(dest, recStart, segmentLen*sizeof(DATA) );
/*FILL_CNT*/		for (i=0; i<segmentLen; i++)
/*FILL_CNT*/		{
/*FILL_CNT*/			*pDest++ = *pStart;		// Copy source to destination
/*FILL_CNT*/			pStart += SRC_INC;		// Increment the source pointer by the required amount
/*FILL_CNT*/		}
/*FILL_CNT*///WRAP		#if SAVETRACE == TRUE
/*FILL_CNT*///WRAP			SaveTraceData((u16)dest);

⌨️ 快捷键说明

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