📄 ofdm_fft.c
字号:
/*=================================================================================
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 + -