📄 predet.c
字号:
//==========================================================================================
// Filename: predet.c
//
// Description: Functions related to preamble detection for power line modem.
//
// Copyright (C) 2001 - 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"
#define FEQ_NORM_BIN 1 // use binary intervals to normalize in FEQ
#define FEQ_NORM_DIV 2 // divide by power to normalize in FEQ
#define FEQ_NORM_LOOKUP 3 // use lookup table for normalization in FEQ
#define FEQ_NORM_NONE 4 // don't normalize in FEQ
#define FEQ_NORM_TYPE FEQ_NORM_DIV
//==========================================================================================
// Function: frameAlign()
//
// Description: Main frame align and equalization function.
//
// Revision History:
//==========================================================================================
i16 *frameAlign(iCplx *freqEq, i16 *recSignal)
{
i16 numFramesAve; // count of frames averaged
i16 frameStart;
i16 frameStartFirst;
i16 worstPwr;
frameAligned = 1; // Assume frameAlignment will turn out good
//---- get average freq response until sync frame is received ---------
numFramesAve = ddAveFFT( symbolArray, recSignal );
//diagData(symbolArray, CARRIER_LEN, "avecar", diagICPLX);
// If we didn't see enough frames with reasonable-looking phase error,
// we're probably looking in the middle of a data packet, not a preamble,
// so treat this as a failed frame alignment.
if (numFramesAve < 3) //??? Make this into a defined constant
{
PostErrorCode(0xBAD7, "frameAlign", "preDet.c", "Insufficient number of frames averaged");
#if SAVETRACE == TRUE
SaveTraceData(0xBAD7); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)recSignal); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData(numFramesAve); //!!!DEBUG Put a marker in the trace buffer
#endif
frameAligned = 0; // Frame alignment failed
preambleDetCount = 0; // Restart the frame detection process
agcState = AgcIdle; // Reset the AGC mode
}
else
{
//---- Calculate the impulse response from the averaged frequency values.
frameStart = getFrameStartFromImpulse( symbolArray ); // The maximum point in the
// impulse response corresponds
// to the beginning of the frame.
//#if COMPILE_MODE == MEX_COMPILE
//frameStart += 1; // DEBUG!!!!
//mexPrintf("frameStart = %d\n",frameStart);
//#endif
frameStartFirst = frameStart;
//---- re-do FFT averages at correct starting point and find sync frame -------
recSignal = WrapRecPtr(recSignal, +frameStart*RX_SRC_INC); // Point to true start of a frame
numFramesAve = ddAveFFT( symbolArray, recSignal );
//diagData(symbolArray, CARRIER_LEN, "avecar2", diagICPLX);
frameStart = numFramesAve*FFT_LEN
+ (int)SYNC_FIELD_LEN
+ CYCLIC_PREFIX_LEN;
recSignal = WrapRecPtr(recSignal, +frameStart*RX_SRC_INC); // set first data frame starting point
worstPwr = getFreqEq( freqEq, symbolArray, numFramesAve );
//diagData(freqEq, CARRIER_LEN, "freqEq", diagICPLX);
#if SAVETRACE == TRUE
SaveTraceData(0xC000 + (numFramesAve<<8) + (frameStartFirst&0x00FF)); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)recSignal); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData(worstPwr); //!!!DEBUG Put a marker in the trace buffer
#endif
if( worstPwr < WORST_PWR_LIMIT )
{
#if COMPILE_MODE == MEX_COMPILE
char prtStr[80];
diagData(symbolArray, CARRIER_LEN, "feqSymbols", diagICPLX);
diagData(recSignalArray, RX_CIRC_BUFFER_LEN, "rxArray", diagI16);
sprintf(prtStr, "signal power too low to equalize : %d\n", worstPwr );
postError(prtStr);
#else
PostErrorCode(0xBAD2, "frameAlign", "preDet.c", "Signal power too low to equalize");
#if SAVETRACE == TRUE
SaveTraceData(0xBAD2); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)recSignal); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData(worstPwr); //!!!DEBUG Put a marker in the trace buffer
#endif
#endif
frameAligned = 0; // Frame alignment failed
preambleDetCount = 0; // Restart the frame detection process
agcState = AgcIdle; // Reset the AGC mode
}
}
return recSignal;
}
//==========================================================================================
// Function: aveFFT()
//
// Description: Get average FFT of the preamble frames.
//
// Revision History:
//==========================================================================================
i16 aveFFT( iCplx *aveCarrier, i16 *recSignal )
{
u16 n, frame; // loop counters
u16 phaseError = 0; // sum(abs(phase)) for first n subcarriers,
// used to determine end of preamble
iCplx *fftBuf; // pointer to fft array
iCplx *aveCar; // working pointer to ave data
//---- initialize array used to average frequency response ------
memset(aveCarrier, 0, CARRIER_LEN*sizeof(iCplx)); // set average to zero
//---- get average freq response for N frames -----------------------
for( frame = 0; frame < NUM_PRE_FRAMES+1; frame++ )
{
recSignal = circFFT( fftArray, recSignal );
//--------------------------------------------------------------------
// Compare the phase of this frame with the phase of the previous frame.
// If the phase difference is greater that criteria, we must have hit
// the sync frame. So don't incude this frame in the average and quit.
//
// Note that we want to use the lowest freq frames so that any phase
// shift due to sample rate error is as low as possible.
//---------------------------------------------------------------------
fftBuf = fftArray + CARRIER_LOW; // point to the carrier bins
aveCar = aveCarrier;
if( frame > 0 )
phaseError = AlignPhaseCompare(PHASE_MEAS_LEN, aveCar, fftBuf );
#if SAVETRACE == TRUE
SaveTraceData((u16)(0xAA00 + (frame<<4) + phaseError)); //!!!DEBUG Put a marker in the trace buffer (Shouldn't need to cast this, but Visual C++ complains)
SaveTraceData((u16)recSignal); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)ReadRxDMAPointer()); //!!!DEBUG Put a marker in the trace
#endif
if( phaseError >= ALIGN_DONE_CRITERIA )
break;
//---- otherwise continue processing fft data -----------------
for( n = 0; n < CARRIER_LEN; n++ )
{
aveCar->re += fftBuf->re;
if( abs(aveCar->re) > 0x7000)
{
PostErrorCode(0xBAD4, "aveFFT", "preDet.c", "Overflow of real part of average carrier in preamble");
}
aveCar->im += fftBuf->im;
if( abs(aveCar->im) > 0x7000)
{
PostErrorCode(0xBAD5, "aveFFT", "preDet.c", "Overflow of imag part of average carrier in preamble");
}
fftBuf++;
aveCar++;
}
//AVEFFT #if SAVETRACE == TRUE
//AVEFFT SaveTraceData((u16)(0x9800 + (frame<<4) + phaseError)); //!!!DEBUG Put a marker in the trace buffer (Shouldn't need to cast this, but Visual C++ complains)
//AVEFFT SaveTraceData((u16)symbolArray[5].re); //!!!DEBUG Put a marker in the trace buffer
//AVEFFT SaveTraceData((u16)symbolArray[5].im); //!!!DEBUG Put a marker in the trace buffer
//AVEFFT SaveTraceData((u16)(0x9900 + (frame<<4) + phaseError)); //!!!DEBUG Put a marker in the trace buffer (Shouldn't need to cast this, but Visual C++ complains)
//AVEFFT SaveTraceData((u16)fftArray[5+CARRIER_LOW].re); //!!!DEBUG Put a marker in the trace buffer
//AVEFFT SaveTraceData((u16)fftArray[5+CARRIER_LOW].im); //!!!DEBUG Put a marker in the trace buffer
//AVEFFT #endif
} // end of fft block
if( frame == NUM_PRE_FRAMES+1 )
{
PostErrorCode(0xBAD6, "aveFFT", "preDet.c", "Failed to find Sync frame");
}
return frame;
}
//==========================================================================================
// Function: ddAveFFT()
//
// Description: Get average FFT of the preamble frames.
//
// Revision History:
//==========================================================================================
i16 ddAveFFT( iCplx *aveCarrier, i16 *recSignal )
{
u16 n, frame; // loop counters
u16 phaseError = 0; // sum(abs(phase)) for first n subcarriers,
// used to determine end of preamble
iCplx *fftBuf; // pointer to fft array
iCplx *aveCar; // working pointer to ave data
//---- initialize array used to average frequency response ------
memset(aveCarrier, 0, CARRIER_LEN*sizeof(iCplx)); // set average to zero
memset(fftArray, 0, FFT_LEN*sizeof(iCplx)); // DEBUG!!!
//---- get average freq response for N frames -----------------------
for( frame = 0; frame < NUM_PRE_FRAMES+1; frame++ )
{
recSignal = circFFT( fftArray, recSignal );
//--------------------------------------------------------------------
// Compare the phase of this frame with the phase of the previous frame.
// If the phase difference is greater that criteria, we must have hit
// the sync frame. So don't incude this frame in the average and quit.
//
// Note that we want to use the lowest freq frames so that any phase
// shift due to sample rate error is as low as possible.
//---------------------------------------------------------------------
fftBuf = fftArray + CARRIER_LOW;
phaseError = ddphase(PreambleArray, fftBuf, CARRIER_LEN );
#if COMPILE_MODE == MEX_COMPILE
{
//char vnameStr[20];
//sprintf(vnameStr,"ddAve%d",frame);
//diagData(fftArray, FFT_LEN, vnameStr, diagICPLX);
mexPrintf("%d: phaseError %d\n", frame, phaseError );
}
#endif
//if( frame > 0 )
// phaseError = AlignPhaseCompare(PHASE_MEAS_LEN, aveCar, fftBuf );
#if SAVETRACE == TRUE
SaveTraceData((u16)(0xAA00 + phaseError)); //!!!DEBUG Put a marker in the trace buffer (Shouldn't need to cast this, but Visual C++ complains)
SaveTraceData((u16)recSignal); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)ReadRxDMAPointer()); //!!!DEBUG Put a marker in the trace
#endif
if( phaseError >= ALIGN_DONE_CRITERIA )
break;
//---- otherwise continue processing fft data -----------------
fftBuf = fftArray + CARRIER_LOW;
aveCar = aveCarrier;
for( n = 0; n < CARRIER_LEN; n++ )
{
aveCar->re += fftBuf->re;
if( abs(aveCar->re) > 0x7000)
{
PostErrorCode(0xBAD4, "aveFFT", "preDet.c", "Overflow of real part of average carrier in preamble");
}
aveCar->im += fftBuf->im;
if( abs(aveCar->im) > 0x7000)
{
PostErrorCode(0xBAD5, "aveFFT", "preDet.c", "Overflow of imag part of average carrier in preamble");
}
fftBuf++;
aveCar++;
}
//AVEFFT #if SAVETRACE == TRUE
//AVEFFT SaveTraceData((u16)(0x9800 + (frame<<4) + phaseError)); //!!!DEBUG Put a marker in the trace buffer (Shouldn't need to cast this, but Visual C++ complains)
//AVEFFT SaveTraceData((u16)symbolArray[5].re); //!!!DEBUG Put a marker in the trace buffer
//AVEFFT SaveTraceData((u16)symbolArray[5].im); //!!!DEBUG Put a marker in the trace buffer
//AVEFFT SaveTraceData((u16)(0x9900 + (frame<<4) + phaseError)); //!!!DEBUG Put a marker in the trace buffer (Shouldn't need to cast this, but Visual C++ complains)
//AVEFFT SaveTraceData((u16)fftArray[5+CARRIER_LOW].re); //!!!DEBUG Put a marker in the trace buffer
//AVEFFT SaveTraceData((u16)fftArray[5+CARRIER_LOW].im); //!!!DEBUG Put a marker in the trace buffer
//AVEFFT #endif
} // end of fft block
if( frame == NUM_PRE_FRAMES+1 )
{
PostErrorCode(0xBAD6, "aveFFT", "preDet.c", "Failed to find Sync frame");
}
return frame;
}
//==========================================================================================
// Function: AlignPhaseCompare()
//
// Description: Compare phase of carriers from the previous frame with the phase
// of carriers from the current frame. Decode to one of four phases
// (just like data decode) and sum the abs of the phase differences.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -