📄 datadet.c
字号:
currSymbol.re = symbols->re;
currSymbol.im = (symbols++)->im;
}
return;
}
//==========================================================================================
// Function: dataFFT()
//
// Description: Calculate the FFT of the data frame.
//
// Revision History:
//==========================================================================================
i16 *dataFFT( iCplx *symbols, i16 *recPtr, iCplx *freqEq )
{
i16 n; // loop counter, return code
i32 acc; // temp 32 bit value
iCplx *fftBuf; // pointer to fft buffer
#if COMPILE_MODE == DSP_COMPILE
i16 delta; // difference between recPtr and rxDMA
i16* rxDMA;
#endif
#if COMPILE_MODE == DSP_COMPILE
//---------------------------------------------------------------------------------
// The frameAlign() function and the cyclic prefix calculation both move recPtr
// ahead of the rx DMA pointer. Wait here for the DMA pointer to start filling
// data before we try reading it. Several cases, depending on whether recPtr or
// DMA pointer have wrapped, and if DMA pointer is already past recPtr or not.
SetXF();
rxDMA = ReadRxDMAPointer();
delta = recPtr - rxDMA;
if (delta > (RX_CIRC_BUFFER_LEN/2))
{ // Huge positive value due to DMA wrap: No delay needed
DebugDelay(); // Flush C54x if in debug mode.
}
else if (delta > 0)
{
// Small positive value: Wait a little bit
WaitForRxBufferFree(rxDMA, delta);
DebugDelay(); // Flush C54x if in debug mode.
}
else if (delta > -(RX_CIRC_BUFFER_LEN/2) )
{ // Small negative or Zero value: No delay needed
DebugDelay(); // Flush C54x if in debug mode.
}
else
{ // Huge negative value due to recPtr wrap: Two short delays needed
WaitForRxBufferFree(rxDMA, (u16)(recSignalArray + RX_CIRC_BUFFER_LEN-rxDMA));
DebugDelay(); // Flush C54x if in debug mode.
WaitForRxBufferFree(recSignalArray, (u16)(recPtr-recSignalArray));
DebugDelay(); // Flush C54x if in debug mode.
}
DebugDelay(); // Flush C54x if in debug mode.
ClearXF();
#endif
//----get the FFT of the frame samples -------------------------------------
recPtr = circFFT( fftArray, recPtr );
recPtr = WrapRecPtr(recPtr, +CYCLIC_PREFIX_LEN*RX_SRC_INC); // Move recPtr ahead to skip cyclic prefix
//-------------------------------------------------------
// Frequency Equalization
// symbol = carrier*equal = (cr+jci)*(er+jei)
// sr = cr*er - ci*ei
// si = cr*ei + ci*er
//--------------------------------------------------------
fftBuf = fftArray + CARRIER_LOW; // point to the carrier bins
for( n = 0; n < CARRIER_LEN; n++ )
{
acc = (i32)fftBuf->re * (i32)freqEq->re
- (i32)fftBuf->im * (i32)freqEq->im;
symbols->re = (i16)(acc >> FEQ_SHIFT);
acc = (i32)fftBuf->re * (i32)freqEq->im
+ (i32)fftBuf->im * (i32)freqEq->re;
symbols->im = (i16)(acc >> FEQ_SHIFT);
#if (SAVESYMBOLS == TRUE) // Save the symbol array for debug
SaveTraceData(symbols->re);
SaveTraceData(symbols->im);
#endif
#if DEBUGIT == DEBUG_DATAFFT
*diag.r++ = (double)fftBuf->re;
*diag.i++ = (double)fftBuf->im;
*diag.r++ = (double)symbols->re;
*diag.i++ = (double)symbols->im;
#endif
fftBuf++;
freqEq++;
symbols++;
}
return recPtr;
}
//==========================================================================================
// Function: compareParityCheckBytes()
//
// Description: Calculate parity check bytes for outer RS code and append
//
// Revision History:
//==========================================================================================
u16 compareParityCheckBytes(u16 *pUserData, i16 numBytes)
{
i16 byteCount = 0;
u16 dataByte;
u16 reg;
//---- init parity table ----------------------
if( CRCtableArray[1] == 0 )
initCRCtable( CRCtableArray );
//--------------------------------------------------------------
// Read through the data to calculate the CRC word. Compare it
// to the CRC appended at transmit.
//--------------------------------------------------------------
reg = CRC_REG_INIT;
for( byteCount = 0; byteCount < (numBytes+2); byteCount +=2 )
{
dataByte = (*pUserData) >> BYTE_LEN;// high data byte
reg = (reg << BYTE_LEN)
^ CRCtableArray[ (reg >> (CRC_LEN-BYTE_LEN)) ] ^ dataByte;
dataByte = (*pUserData++) & 0x00FF; // low data byte
reg = (reg << BYTE_LEN)
^ CRCtableArray[ (reg >> (CRC_LEN-BYTE_LEN)) ] ^ dataByte;
}
return reg;
}
//==========================================================================================
// Function: countErrors()
//
// Description: Count number of error bits
//
// Revision History:
//==========================================================================================
i16 countErrors(u16 *pUserData)
{
i16 n, b;
i16 errorCount = 0;
u16 word;
for( n = 0; n < NUM_USER_BYTES/2; n++ )
{
if( *pUserData++ > 0 )
{
word = *(pUserData-1);
for( b = 0; b < WORD_LEN; b++ )
{
errorCount += word & 0x0001;
word >>= 1;
}
}
}
return errorCount;
}
#if COMPILE_MODE == MEX_COMPILE
//==========================================================================================
// Function: readDataFramesFrom Matlab()
//
// Description: Diagnostic data detection function.
// Here symbol data has been collected somewhere else and is feed into the
// distance metric and viterbi algorithms
//
// Revision History:
//==========================================================================================
u16 readDataFramesFromMatlab( u16 *pUserData, dCplxPtr drec )
{
u16 block, frame, n;
u16 parityGood;
MetricType *distance;
iCplx *sym;
//---- allocate a diagnostic array to pass to Matlab ----------
#if DEBUGIT == DEBUG_VITERBI_STATES
diagArray = mxCreateDoubleMatrix(2, NUM_SYMBOLS*VITERBI_NUM_STATES, 1, mxREAL);
mxSetName(diagArray, "vStates");
diag.r = mxGetPr(diagArray);
#endif
#if DEBUGIT == DEBUG_DISTANCE2
diagArray = mxCreateDoubleMatrix(8, NUM_SYMBOLS*DATA_FRAMES_PER_BLOCK, mxREAL);
mxSetName(diagArray, "vDist2");
diag.r = mxGetPr(diagArray);
#endif
distance = distanceArray;
prevCarrier1.re = VITERBI_CAR1_RE*DATA_FRAMES_PER_BLOCK; // init for first carrier
prevCarrier1.im = VITERBI_CAR1_IM*DATA_FRAMES_PER_BLOCK;
initPathMemory(pUserData); // init path memory and path metrics
//---- process each data frame ----------------------------
for( block = 0; block < NUM_DATA_BLOCKS; block++ )
{
memset( distance, 0, 2*CARRIER_LEN*sizeof(MetricType) ); // reset distance array
for( frame = 0; frame < DATA_FRAMES_PER_BLOCK; frame++ )
{
//recPtr = dataFFT( symbolArray, recPtr, freqEq ); // read a frame and adv the pointer
sym = symbolArray;
for( n = 0; n < CARRIER_LEN; n++ )
{
sym->re = *drec.r++;
sym->im = *drec.r++;
sym++;
}
aveDistance( distance + frame*2*SYMBOL_OFFSET, symbolArray ); //store Matlab diag in here
}
viterbiDecodeFrame( distance, CARRIER_LEN );
}
flushPathMemory();
scramble(pUserData, DATA_BUFFER_LEN); // unscramble the whole buffer
parityGood = compareParityCheckBytes(pUserData, NUM_USER_BYTES);
#if ( ( DEBUGIT == DEBUG_VITERBI_STATES ) \
|| ( DEBUGIT == DEBUG_DISTANCE2 ) )
mexPutArray(diagArray, "caller");
#endif
return parityGood;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -