📄 predet.c
字号:
//---- allocate a diagnostic array to pass to Matlab ----------
#if DEBUGIT == DEBUG_GETFEQ
diagArray = mxCreateDoubleMatrix(4, CARRIER_LEN, mxCOMPLEX);
mxSetName(diagArray, "feq_diag");
diag.r = mxGetPr(diagArray);
diag.i = mxGetPi(diagArray);
#endif
//-----------------------------------------------------------------
// calc the complex freq equalization value that is
// multiplied with each carrier in the data frames
//-----------------------------------------------------------------
preamble = (iCplx *)distanceArray; // get complex phase from txPhase data
getPrePhases( preamble, PreambleArray );
pwrScaleFactor = numFramesAve << PWR_SCALE_SHIFT;
for( n = 0; n < CARRIER_LEN; n++ )
{
//------------------------------------------------
// (1.15 * 1.15) >> 12 = 2.30 >> 12 = 14.18 ==> -2.18
// so carrierPwr is 15-PWR_SHIFT bigger than a 1.15 number
//-------------------------------------------------
carrierPwr = iSquare(aveCarrier->re, PWR_SHIFT)
+ iSquare(aveCarrier->im, PWR_SHIFT)
+ 1; // make it at least 1
if( carrierPwr < 0 )
{
PostErrorCode(0xBAE2, "getFreqEq", "preDet.c", "Overflowed carrier power");
}
if( carrierPwr < minPwr )
minPwr = carrierPwr;
#if DEBUGIT == DEBUG_GETFEQ
*diag.r++ = (double)preamble->re;
*diag.i++ = (double)preamble->im;
*diag.r++ = (double)aveCarrier->re;
*diag.i++ = (double)aveCarrier->im;
*diag.r++ = (double)carrierPwr;
#endif
//---------------------------------------------------------
// Ideally we would multiply FEQ by numFramesAve/carrierPwr.
// But this means dividing by carrierPwr. Instead, find the
// 2^k closest to numFramesAve/carrierPwr and do a shift
// instead of the divide.
//---------------------------------------------------------
for( k = PWR_SCALE_SHIFT; k > 1; k-- )
{
if( carrierPwr > pwrScaleFactor )
break;
carrierPwr <<= 1;
}
if( k <= 1 )
{
#if COMPILE_MODE == MEX_COMPILE
char prtStr[80];
//mexPrintf("aveCarrier = %d %+dj\ncarrierPwr = %d\npwrScaleFactor = %d\n",
// aveCarrier->re, aveCarrier->im, carrierPwr, pwrScaleFactor );
diagData(symbolArray, CARRIER_LEN, "feqSymbols", diagICPLX);
diagData(recSignalArray, RX_CIRC_BUFFER_LEN, "rxArray", diagI16);
sprintf(prtStr, "Failed doing power scale factor. numFramesAve = %d aveCarrier = %d, %d",
numFramesAve, aveCarrier->re, aveCarrier->im );
PostErrorCode(0xBAD1, "getFreqEq", "preDet.c", prtStr);
#endif
//uStatus = 0xBAD1;
PostErrorCode(0xBAD1, "getFreqEq", "preDet.c", "Failed doing power scale factor");
#if SAVETRACE == TRUE
SaveTraceData(0xBAD1); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData(n); //!!!DEBUG Put a marker in the trace buffer
SaveTraceData((u16)carrierPwr); //!!!DEBUG Put a marker in the trace buffer
#endif
}
shift = CARRIER_SCALE - (15-PWR_SHIFT) - k; // 13-15+12-k = 10-k
if( shift >= 0 )
{
carrierPwr = aveCarrier->re * preamble->re;
carrierPwr += aveCarrier->im * preamble->im;
freqEq->re = (i16)(carrierPwr << shift);
carrierPwr = aveCarrier->re * preamble->im;
carrierPwr -= aveCarrier->im * preamble->re;
freqEq->im = (i16)(carrierPwr << shift);
}
else
{
shift = -shift;
carrierPwr = aveCarrier->re * preamble->re;
carrierPwr += aveCarrier->im * preamble->im;
freqEq->re = (i16)(carrierPwr >> shift);
carrierPwr = aveCarrier->re * preamble->im;
carrierPwr -= aveCarrier->im * preamble->re;
freqEq->im = (i16)(carrierPwr >> shift);
}
#if DEBUGIT == DEBUG_GETFEQ
*diag.i++ = (double)shift;
*diag.r++ = (double)freqEq->re;
*diag.i++ = (double)freqEq->im;
#endif
aveCarrier++;
freqEq++;
preamble++;
}
#if DEBUGIT == DEBUG_GETFEQ
mexPutArray(diagArray, "caller");
#endif
return minPwr;
}
#endif
#if FEQ_NORM_TYPE == FEQ_NORM_LOOKUP // Use lookup table to normalize
//==========================================================================================
// Function: getFreqEq()
//
// Description: Frequency equalization calculation
// EQ = tx/rx = preamble / receive = Preamble / (aveCarrier/N) = N*P/A
// where N is the number of FFT averages
//
// complex math:
// EQ = N/(ar*ar + ai*ai) * ((ar*pr + ai*pi) + j*(ar*pi - ai*pr))
// = invPwr * ((ar*pr + ai*pi) + j*(ar*pi - ai*pr))
//
// Revision History:
//==========================================================================================
#define RES_LO 8
#define RES_HI 11
#define KSM_LO 9
#define KSM_HI 15
#define INV_SHIFT 10
i16 getFreqEq( iCplx *freqEq, iCplx *aveCarrier, i16 numFramesAve )
{
u16 n, c; // loop counter, return code
iCplx *preamble;
i32 carrierPwr, invPwr;
i16 minPwr = 0x7FFF; // init to a big number
static const i32 invLookupSlope[] = {
//-1024, -256, -85, -43, -26, -17, -12, -9 };
-8192, -2048, -683, -341, -205, -137, -98, -73 };
static const i32 invLookupOffLo[] = {
//1536, 768, 427, 299, 230, 188, 158, 137 };
6144, 3072, 1707, 1195, 922, 751, 634, 549 };
static const i32 invLookupOffHi[] = {
//192, 96, 53, 37, 29, 23, 20, 17 };
768, 384, 213, 149, 115, 94, 79, 69 };
//---- allocate a diagnostic array to pass to Matlab ----------
#if DEBUGIT == DEBUG_GETFEQ
diagArray = mxCreateDoubleMatrix(4, CARRIER_LEN, mxCOMPLEX);
mxSetName(diagArray, "feq_diag");
diag.r = mxGetPr(diagArray);
diag.i = mxGetPi(diagArray);
#endif
//-----------------------------------------------------------------
// calc the complex freq equalization value that is
// multiplied with each carrier in the data frames
//-----------------------------------------------------------------
preamble = (iCplx *)distanceArray; // get complex phase from txPhase data
getPrePhases( preamble, PreambleArray );
//---- calc frequency equalization for each carrier ---------------
for( n = 0; n < CARRIER_LEN; n++ )
{
carrierPwr = iSquare(aveCarrier->re, PWR_SHIFT) // get the signal power
+ iSquare(aveCarrier->im, PWR_SHIFT);
if( carrierPwr < 0 )
{
PostErrorCode(0xBAE2, "getFreqEq", "preDet.c", "Overflowed carrier power");
}
if( carrierPwr < minPwr )
minPwr = carrierPwr;
//---- calculate 1/carrierPwr using a table lookup -----------
if( carrierPwr < (1<<RES_HI) )
{
c = carrierPwr >> RES_LO;
invPwr = (invLookupSlope[c]*carrierPwr) >> KSM_LO;
invPwr += invLookupOffLo[c];
}
else
{
c = carrierPwr >> RES_HI;
invPwr = (invLookupSlope[c]*carrierPwr) >> KSM_HI;
invPwr += invLookupOffHi[c];
}
invPwr *= numFramesAve;
//---- now to the complex math to get FEQ values -------------
freqEq->re = aveCarrier->re * preamble->re;
freqEq->re += aveCarrier->im * preamble->im;
freqEq->re = (i16)(( invPwr * (i32)freqEq->re ) >> INV_SHIFT );
freqEq->im = aveCarrier->re * preamble->im;
freqEq->im -= aveCarrier->im * preamble->re;
freqEq->im = (i16)(( invPwr * (i32)freqEq->im ) >> INV_SHIFT );
#if DEBUGIT == DEBUG_GETFEQ
*diag.r++ = (double)preamble->re;
*diag.i++ = (double)preamble->im;
*diag.r++ = (double)aveCarrier->re;
*diag.i++ = (double)aveCarrier->im;
*diag.r++ = (double)carrierPwr;
*diag.i++ = (double)invPwr;
*diag.r++ = (double)freqEq->re;
*diag.i++ = (double)freqEq->im;
#endif
aveCarrier++;
freqEq++;
preamble++;
}
#if DEBUGIT == DEBUG_GETFEQ
mexPutArray(diagArray, "caller");
#endif
return minPwr;
}
#endif
#if FEQ_NORM_TYPE == FEQ_NORM_NONE // don't normalize
//==========================================================================================
// Function: getFreqEq()
//
// Description: Frequency equalization calculation
//
// Revision History:
//==========================================================================================
i16 getFreqEq( iCplx *freqEq, iCplx *aveCarrier, i16 numFramesAve )
{
u16 n; // loop counter, return code
iCplx *preamble;
//---- allocate a diagnostic array to pass to Matlab ----------
#if DEBUGIT == DEBUG_GETFEQ
diagArray = mxCreateDoubleMatrix(4, CARRIER_LEN, mxCOMPLEX);
mxSetName(diagArray, "feq_diag");
diag.r = mxGetPr(diagArray);
diag.i = mxGetPi(diagArray);
#endif
//-----------------------------------------------------------------
// calc the complex freq equalization value that is
// multiplied with each carrier in the data frames
//-----------------------------------------------------------------
preamble = (iCplx *)distanceArray; // get complex phase from txPhase data
getPrePhases( preamble, PreambleArray );
//pwrScaleFactor = numFramesAve << PWR_SCALE_SHIFT;
for( n = 0; n < CARRIER_LEN; n++ )
{
freqEq->re = 1024;
freqEq->im = 0;
#if DEBUGIT == DEBUG_GETFEQ
{
i32 carrierPwr;
*diag.r++ = (double)preamble->re;
*diag.i++ = (double)preamble->im;
*diag.r++ = (double)aveCarrier->re;
*diag.i++ = (double)aveCarrier->im;
carrierPwr = iSquare(aveCarrier->re, PWR_SHIFT)
+ iSquare(aveCarrier->im, PWR_SHIFT);
*diag.r++ = (double)carrierPwr;
*diag.i++ = (double)FEQ_SHIFT;
*diag.r++ = (double)freqEq->re;
*diag.i++ = (double)freqEq->im;
}
#endif
aveCarrier++;
freqEq++;
preamble++;
}
#if DEBUGIT == DEBUG_GETFEQ
mexPutArray(diagArray, "caller");
#endif
return 0x2000;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -