📄 ofdm_fft.c
字号:
/*FILL_CNT*///WRAP SaveTraceData((u16)recSignalArray);
/*FILL_CNT*///WRAP SaveTraceData((u16)segmentLen);
/*FILL_CNT*///WRAP #endif
/*FILL_CNT*/ }
/*FILL_CNT*/
/*FILL_CNT*/// ClearXF(); // Turn off XF flag for debug
/*FILL_CNT*/// Delay1us();
/*FILL_CNT*/// SetXF(); // Turn on XF flag for debug
/*FILL_CNT*/// Delay1us();
/*FILL_CNT*/// ClearXF(); // Turn off XF flag for debug
/*FILL_CNT*/
/*FILL_CNT*/ return(pEnd);
/*FILL_CNT*/}
#endif
//==========================================================================================
// Function: circFFT()
//
// Description: Fills the FFT buffer and calls the FFT library function.
// Starts at the sample in the buffer pointed to by recSignal .
// FFT data is calculated "in place" in the fftBuffer.
// Returns a pointer to the next data in recSignal (which may have wrapped
// to the beginning of the buffer).
//
// Revision History:
//==========================================================================================
i16 *circFFT( iCplx *fftBuffer, i16 *recSignal )
{
DATA *fftBuf;
DATA *fftBuf2;
fftBuf = (DATA *)fftBuffer; // first half of the buffer
fftBuf2 = fftBuf + FFT_LEN; // second half
// Copy from the receive buffer to the second half of the FFT buffer.
// Handle wraparound at ends of rec buffer if necessary.
recSignal = FillFFTBuff2(fftBuf2, recSignal, WrapRecPtr(recSignal,FFT_LEN*RX_SRC_INC));
// ----- Copy from the second half of the FFT buffer to the first half, -----
// with bit reversal if necessary.
#if COMPILE_MODE == DSP_COMPILE
cbrev( fftBuf2, fftBuf, FFT_LEN/2 ); // copy data in bit
#else // reversed format
memcpy(fftBuf, fftBuf2, FFT_LEN*sizeof(DATA) );
#endif
//---- call the fft library funciton ------------------------
#if DEBUGIT == DEBUG_CIRCFFT
{
int n;
DATA *fBuf;
if( diag.r != NULL )
{
fBuf = fftBuf;
for(n = 0; n < FFT_LEN; n++ )
{
*diag.r++ = (double)(*fBuf++);
*diag.i++ = (double)(n);
}
}
}
#endif
rfft( fftBuf, FFT_LEN, FFT_SCALE );
#if DEBUGIT == DEBUG_CIRCFFT
{
int n;
DATA *fBuf;
if( diag.r != NULL )
{
fBuf = fftBuf;
for(n = 0; n < FFT_LEN; n++ )
{
*diag.r++ = (double)(*fBuf++);
*diag.i++ = (double)(*fBuf++);
}
}
}
#endif
return recSignal;
}
//==========================================================================================
// Function: backFFT()
//
// Description: Fills the FFT buffer and calls the FFT library function.
// Ends at the sample in the buffer pointed to by recSignal.
// FFT data is calculated "in place" in the fftBuffer.
// Returns a pointer to the next data in recSignal (which may have wrapped
// to the beginning of the buffer).
//
// Revision History:
//==========================================================================================
void backFFT( iCplx *fftBuffer, i16 *recSignal )
{
DATA *fftBuf;
DATA *fftBuf2;
fftBuf = (DATA *)fftBuffer; // first half of the buffer
fftBuf2 = fftBuf + FFT_LEN; // second half
// Copy from the receive buffer to the second half of the FFT buffer.
// Handle wraparound at ends of rec buffer if necessary.
recSignal = FillFFTBuff2(fftBuf2, WrapRecPtr(recSignal,-FFT_LEN*RX_SRC_INC), recSignal);
// ----- Copy from the second half of the FFT buffer to the first half, -----
// with bit reversal if necessary.
#if COMPILE_MODE == DSP_COMPILE
cbrev( fftBuf2, fftBuf, FFT_LEN/2 ); // copy data in bit-reversed format
#else
memcpy(fftBuf, fftBuf2, FFT_LEN*sizeof(DATA) ); //copy data
#endif
//---- call the fft library funciton ------------------------
rfft( fftBuf, FFT_LEN, FFT_SCALE );
return;
}
#if COMPILE_MODE == MEX_COMPILE
/*====================================================================
do ifft and fft by calling Matlab
=====================================================================*/
void mexfft( i16 *fftBuffer, i16 len, i16 scale, char cmdCh, char typeCh )
{
int n, rc; // loop counter
int task;
i32 acc;
DATA *fBuf;
dCplxPtr dFftBuf; // buffer pointer
mxArray *fftInArray[1]; // fft/ifft input buffer
mxArray *fftOutArray[1]; // fft/ifft output buffer
// Note that this is allocated by
// mexCallMatlab and must be destroyed
if( scale != 0 )
{
switch( len )
{
case 64:
scale = 6;
break;
case 128:
scale = 7;
break;
case 256:
scale = 8;
break;
case 512:
scale = 9;
break;
default:
mexErrMsgTxt("unsupported FFT buffer length.");
}
}
//---- allocate mxArray for call to Matlab iFFT/FFT routine --------
// note that this initializes both arrays to all zeros
if( typeCh == 'C' )
{
fftInArray[0] = mxCreateDoubleMatrix(FFT_LEN, 1, mxCOMPLEX);
dFftBuf.r = mxGetPr(fftInArray[0]);
dFftBuf.i = mxGetPi(fftInArray[0]);
dFftBuf.len = FFT_LEN;
//---- load the Matlab input array -------------------------
fBuf = fftBuffer;
for( n = 0; n<FFT_LEN; n++ )
{
*dFftBuf.r++ = (double)(*fBuf++);
*dFftBuf.i++ = (double)(*fBuf++);
}
}
else // typeCh == 'R'
{
fftInArray[0] = mxCreateDoubleMatrix(FFT_LEN, 1, mxREAL);
dFftBuf.r = mxGetPr(fftInArray[0]);
dFftBuf.i = NULL;
dFftBuf.len = FFT_LEN;
//---- load the Matlab input array -------------------------
fBuf = fftBuffer;
for( n = 0; n<FFT_LEN; n++ )
{
*dFftBuf.r++ = (double)(*fBuf++);
}
}
//---- do the fft/ifft by calling Matlab -------------------
if( cmdCh == 'I' )
{
rc = mexCallMATLAB(1, fftOutArray, 1, fftInArray, "ifft");
if( rc != 0 )
mexErrMsgTxt("IFFT call failed.");
}
else
{
rc = mexCallMATLAB(1, fftOutArray, 1, fftInArray, "fft");
if( rc != 0 )
mexErrMsgTxt("FFT call failed.");
}
dFftBuf.r = mxGetPr(fftOutArray[0]);
dFftBuf.i = mxGetPi(fftOutArray[0]);
fBuf = fftBuffer;
//---- copy the Matlab output array -------------------------
task = (typeCh == 'C')*4 + (cmdCh == 'I')*2 + (dFftBuf.i == NULL);
switch( task )
{
case 0: //---- RFFT with complex output from matlab -----------------
for( n = 0; n<FFT_LEN/2; n++ )
{
//acc = (i32)(*dFftBuf.r++);
//*fBuf++ = (DATA)(acc >> scale); // divide by len for FFT
//acc = (i32)(*dFftBuf.i++);
//*fBuf++ = (DATA)(acc >> scale);
*fBuf++ = (DATA)(*dFftBuf.r++ / (1<<scale)); // do floating point divide
*fBuf++ = (DATA)(*dFftBuf.i++ / (1<<scale)); // divide by len for FFT
}
break;
case 1: //---- RFFT with only real output from matlab -----------------
for( n = 0; n<FFT_LEN/2; n++ )
{
acc = (i32)(*dFftBuf.r++);
*fBuf++ = (DATA)(acc >> scale); // divide by len for FFT
*fBuf++ = 0;
}
break;
case 2: //---- RIFFT. only care about read output from matlab -----------------
case 3:
for( n = 0; n<FFT_LEN; n++ )
{
acc = (i32)(*dFftBuf.r++);
*fBuf++ = (DATA)(acc << scale); // mult by len for IFFT
*fBuf++ = 0;
}
break;
case 4: //---- CFFT with complex output from matlab -----------------
for( n = 0; n<FFT_LEN; n++ )
{
acc = (i32)(*dFftBuf.r++);
*fBuf++ = (DATA)(acc >> scale); // divide by len for FFT
acc = (i32)(*dFftBuf.i++);
*fBuf++ = (DATA)(acc >> scale);
}
break;
case 5: //---- CFFT with only real output from matlab -----------------
for( n = 0; n<FFT_LEN; n++ )
{
acc = (i32)(*dFftBuf.r++);
*fBuf++ = (DATA)(acc >> scale); // divide by len for FFT
*fBuf++ = 0;
}
break;
case 6: //---- CIFFT with complex output from matlab -----------------
for( n = 0; n<FFT_LEN; n++ )
{
acc = (i32)(*dFftBuf.r++);
*fBuf++ = (DATA)(acc << scale); // mult by len for IFFT
acc = (i32)(*dFftBuf.i++);
*fBuf++ = (DATA)(acc >> scale);
}
break;
case 7: //---- CIFFT with only real output from matlab -----------------
for( n = 0; n<FFT_LEN; n++ )
{
acc = (i32)(*dFftBuf.r++);
*fBuf++ = (DATA)(acc << scale); // mult by len for FFT
*fBuf++ = 0;
}
break;
default:
mexErrMsgTxt("unsupported FFT output task.");
}
mxDestroyArray(fftInArray[0]); // clean up mex array we created
mxDestroyArray(fftOutArray[0]); // clean up array mexCallMatlab created
return;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -