📄 rxmain.c
字号:
}
// post a semaphore to resume the receiver task
SEM_post(&rxsem);
break;
default:
#ifdef _DEBUGLOG
LOG_error("processBuffer: RxState = %d not allowed. No matching state found.", RxState);
#endif
exit(EXIT_INVALID_RXSTATE);
break;
}
/* Switch off LED #0 */
//DSK6713_LED_off(0);
#ifdef _DEBUG
BufferLock--;
}
else
{
#ifdef _DEBUGLOG
LOG_printf(&trace,"fatal error: buffers still in use (line %d, %s)",__LINE__,__FILE__);
LOG_error("fatal error: buffers still in use (line %d)",__LINE__);
#endif
}
#endif
}
/****************************************************************************
Function : tskReceiver()
****************************************************************************
Description : Task containing the state machine for the receiver and
calling the computation functions.
Inputs : none (accesses the global/local variables directly)
Outputs : none (accesses the global/local variables directly)
By : 2005-05-16 Adrian Schumacher
****************************************************************************/
void tskReceiver(Arg id_arg)
{
int iTemp;
//unsigned int uiTemp;
static unsigned int uiIndex, uiLen;
static int iBytesWritten, iBytesPerFrame;
while(1)
{
if (ReceiverState.RcvState != eRX_RCVIDLE)
DSK6713_LED_on(0);
switch(ReceiverState.RcvState){
case eRX_RCVIDLE:
// do nothing
// suspend task
SEM_pend(&rxsem,SYS_FOREVER);
TSK_sleep(1);
break;
case eRX_RUNPLL:
#ifdef _DEBUG
if (BufferLock <= 0) {
BufferLock++;
#endif
#ifdef _DEBUGLOG
LOG_printf(&trace,"tskReceiver: eRX_RUNPLL");
#endif
/* call the pll function (shorten the length since the start index will be after the
start of the sinusoid and we do not want to let the pll run over the following symbols)*/
lock_phase(&PLLparam,pfWorkingBuffer,IFSYNCSAMP-2*ENERGYBLOCK);
// update the parameters in DownConvState
DownConvState.fInterFreq = INTERFREQ + (SAMPFREQ*(PLLparam.delta)/(2*PI));
//DownConvState.unPhaseIndex = (unsigned int)(COS_TAB_SIZE*(PLLparam.theta/(2*PI))) - 12 + COS_TAB_SIZE/2;
// compute start of frame (will probably include the guardinterval)
uiIndex = (ReceiverState.uiStartIndex + IFSYNCSAMP*2) - ((uiBuffCount-1)*BUFFSIZE) - 4*ENERGYBLOCK;
// copy at least enough samples to run the filter once
uiLen = ((BUFFSIZE-uiIndex)/2 < MFFILTLEN+3 ? (MFFILTLEN+3)*2 : BUFFSIZE-uiIndex);
// update the index so that it indicates the start of the sync. in the working buffer
uiIndex = ((BUFFSIZE-uiIndex) - uiLen)/2 + ENERGYBLOCK;
// downconvert the remaining samples after the pilot using the corrected frequency
downconvert(&pBufferRcv[BUFFSIZE-uiLen],&fCplxTempBufferFilt1,&fCplxTempBufferFilt2,&DownConvState,uiLen);
// preset the switch start index to be synchron with the working buffer
SwitchState.iStartIndex = (BUFFSIZE-uiLen)/2 + MFFILTLEN-1;
// make sure that the filter output is written from the beginning of the buffer
MFDemodStat1.pfCplxOutBuff->pIBuffer = pfWorkBuf1;
MFDemodStat1.pfCplxOutBuff->pQBuffer = pfWorkBuf2;
MFDemodStat2.pfCplxOutBuff->pIBuffer = pfWorkBuf3;
MFDemodStat2.pfCplxOutBuff->pQBuffer = pfWorkBuf4;
// number of filter output values
uiLen = uiLen/2 - MFFILTLEN + 1;
// run matched filter on channel 1
MFDemodStat1.uiRcvSigLen = uiLen;
MFDemodStat1.uiSamplesProcessed = 0;
matchedFilter(&MFDemodStat1);
// run matched filter on channel 2
MFDemodStat2.uiRcvSigLen = uiLen;
MFDemodStat2.uiSamplesProcessed = 0;
matchedFilter(&MFDemodStat2);
// update the pointers to append data to the buffers
MFDemodStat1.pfCplxOutBuff->pIBuffer = &pfWorkBuf1[uiLen];
MFDemodStat1.pfCplxOutBuff->pQBuffer = &pfWorkBuf2[uiLen];
MFDemodStat2.pfCplxOutBuff->pIBuffer = &pfWorkBuf3[uiLen];
MFDemodStat2.pfCplxOutBuff->pQBuffer = &pfWorkBuf4[uiLen];
// initialize some states
ReceiverState.uFrameNo = 0;
iSyncCtrl = 0;
// change to the next state
#ifdef _DEBUGLOG
LOG_printf(&trace,"change state to eRX_RCVSYNC (line %d)",__LINE__);
#endif
ReceiverState.RcvState = eRX_RCVSYNC;
#ifdef _DEBUG
BufferLock--;
}
else
{
#ifdef _DEBUGLOG
LOG_printf(&trace,"fatal error: buffers still in use (line %d, %s)",__LINE__,__FILE__);
LOG_error("fatal error: buffers still in use (line %d)",__LINE__);
#endif
}
#endif
DSK6713_LED_off(0);
// suspend task
SEM_pend(&rxsem,SYS_FOREVER);
TSK_sleep(1);
break;
case eRX_RCVSYNC:
// process synchronization
#ifdef _DEBUGLOG
LOG_printf(&trace,"tskReceiver: eRX_RCVSYNC");
#endif
// check if enough samples are available
if (MFDemodStat1.uiSamplesProcessed-uiIndex > SYNCLEN*OVERSAMPLING)
{
// set the correct length for the synchronization
//SyncState.uiRcvBuffLen = (MFFILTLEN-1)*OVERSAMPLING+SYNCLEN*OVERSAMPLING;
SyncState.uiRcvBuffLen = MFDemodStat1.uiSamplesProcessed-uiIndex;
SyncState.pfRcv1I = &pfWorkBuf1[uiIndex];
SyncState.pfRcv1Q = &pfWorkBuf2[uiIndex];
SyncState.pfRcv2I = &pfWorkBuf3[uiIndex];
SyncState.pfRcv2Q = &pfWorkBuf4[uiIndex];
// synchronize using the synchronization sequence
synchronization(&SyncState);
if (SyncState.iSyncIndex < 0)
{
// could not synchronize
// with the current sync. implementation this will never occure
// (there will always be a maximum in the crosscorrelation)
#ifdef _DEBUGLOG
LOG_printf(&trace,"tskReceiver: SyncIndex = %d, exit on line %d",SyncState.iSyncIndex,__LINE__);
LOG_error("processBuffer: SyncIndex = %d.", SyncState.iSyncIndex);
#endif
exit(EXIT_NEG_SYNC_IDX);
}
// initialize the start index
MFDemodStat1.iStartIndex = SyncState.iSyncIndex+uiIndex;
MFDemodStat2.iStartIndex = SyncState.iSyncIndex+uiIndex;
// update the start index for the switch manager
if (ReceiverState.iSyncStarted == FALSE)
{
SwitchState.iStartIndex -= MFFILTLEN/2; // account for the filter delay
SwitchState.iStartIndex += SyncState.iSyncIndex+uiIndex; // start of the sync. seq.
SwitchState.iStartIndex -= GUARDSYMBOLS*OVERSAMPLING-OVERSAMPLING/2; // start of the frame
SwitchState.iNextStartIndex = SwitchState.iStartIndex + FRAMESAMPLENGTH;
switch_cntrl_init(&SwitchState,ReceiverState.iSyncRep);
}
else
{
iSampIdxError -= (MFDemodStat1.iStartIndex - OVERSAMPLING);
}
ReceiverState.iSyncStarted = TRUE;
//MFDemodStat1.uiNoOfSamp = MFDemodStat1.uiSampProcessed;
// restore the pointers to the beginning of the buffers
MFDemodStat1.pfCplxOutBuff->pIBuffer = pfWorkBuf1;
MFDemodStat1.pfCplxOutBuff->pQBuffer = pfWorkBuf2;
MFDemodStat2.pfCplxOutBuff->pIBuffer = pfWorkBuf3;
MFDemodStat2.pfCplxOutBuff->pQBuffer = pfWorkBuf4;
MFDemodStat1.uiNextReadSymb = 50;
MFDemodStat2.uiNextReadSymb = 50;
MFDemodStat1.uiNextWriteSymb = 50;
MFDemodStat2.uiNextWriteSymb = 50;
MFDemodStat1.uiNoOfSymb = 0;
MFDemodStat2.uiNoOfSymb = 0;
// demodulate/downsample channel 1
downsampling(&MFDemodStat1);
// demodulate/downsample channel 2
downsampling(&MFDemodStat2);
// demodulated symbols are now available in the symbol buffer
// skip the sync. sequence (the first guard interval is already skiped by the syncronization)
IncCircIndex(&(MFDemodStat1.uiNextReadSymb), SYMBOLBUFFLEN, SYNCLEN);
//MFDemodStat1.uiNextReadSymb += SYNCLEN;
//MFDemodStat1.uiNextReadSymb %= SYMBOLBUFFLEN;
MFDemodStat1.uiNoOfSymb -= SYNCLEN;
IncCircIndex(&(MFDemodStat2.uiNextReadSymb), SYMBOLBUFFLEN, SYNCLEN);
//MFDemodStat2.uiNextReadSymb += SYNCLEN;
//MFDemodStat2.uiNextReadSymb %= SYMBOLBUFFLEN;
MFDemodStat2.uiNoOfSymb -= SYNCLEN;
RxState = eRX_RECEIVE;
ReceiverState.RcvState = eRX_CHANNELEST1;
}
else
{ // not enough samples, wait for more
DSK6713_LED_off(0);
// suspend task
SEM_pend(&rxsem,SYS_FOREVER);
TSK_sleep(1);
}
break;
case eRX_CHANNELEST1:
// estimate the channels using the first training sequence
// check first if enough symbols are available
if (MFDemodStat1.uiNoOfSymb > TRAINLEN)
{
// initialize the pointers/states with the correct values
/* ChannelState.pfCplxSymbBuff1->pIBuffer = &pfSymbolBuffer1I[MFDemodStat1.uiNextReadSymb];
ChannelState.pfCplxSymbBuff1->pQBuffer = &pfSymbolBuffer1Q[MFDemodStat1.uiNextReadSymb];
ChannelState.pfCplxSymbBuff2->pIBuffer = &pfSymbolBuffer2I[MFDemodStat2.uiNextReadSymb];
ChannelState.pfCplxSymbBuff2->pQBuffer = &pfSymbolBuffer2Q[MFDemodStat2.uiNextReadSymb];
*/ ChannelState.ioffset = MFDemodStat1.uiNextReadSymb;
ChannelState.Ch1Switch = SwitchState.uiPos1SetSwitch1;
ChannelState.Ch2Switch = SwitchState.uiPos1SetSwitch2;
// call the estimation function
channelestimation(&ChannelState);
// update the counters/indices
MFDemodStat1.uiNoOfSymb -= TRAINLEN;
MFDemodStat2.uiNoOfSymb -= TRAINLEN;
IncCircIndex(&(MFDemodStat1.uiNextReadSymb), SYMBOLBUFFLEN, TRAINLEN);
//MFDemodStat1.uiNextReadSymb += TRAINLEN;
IncCircIndex(&(MFDemodStat2.uiNextReadSymb), SYMBOLBUFFLEN, TRAINLEN);
//MFDemodStat2.uiNextReadSymb += TRAINLEN;
ReceiverState.RcvState = eRX_CHANNELEST2;
}
else
{ // not enough samples, wait for more
DSK6713_LED_off(0);
// suspend task
SEM_pend(&rxsem,SYS_FOREVER);
TSK_sleep(1);
}
break;
case eRX_CHANNELEST2:
// estimate the channels using the first training
// demodulate/downsample channel 1
//downsampling(&MFDemodStat1);
// demodulate/downsample channel 2
//downsampling(&MFDemodStat2);
// check again if enough symbols are available
if (MFDemodStat1.uiNoOfSymb > GUARDSYMBOLS+TRAINLEN)
{
// skip the guard interval
MFDemodStat1.uiNoOfSymb -= GUARDSYMBOLS;
MFDemodStat2.uiNoOfSymb -= GUARDSYMBOLS;
IncCircIndex(&(MFDemodStat1.uiNextReadSymb), SYMBOLBUFFLEN, GUARDSYMBOLS);
//MFDemodStat1.uiNextReadSymb += GUARDSYMBOLS;
IncCircIndex(&(MFDemodStat2.uiNextReadSymb), SYMBOLBUFFLEN, GUARDSYMBOLS);
//MFDemodStat2.uiNextReadSymb += GUARDSYMBOLS;
// initialize the pointers/states with the correct values
/* ChannelState.pfCplxSymbBuff1->pIBuffer = &pfSymbolBuffer1I[MFDemodStat1.uiNextReadSymb];
ChannelState.pfCplxSymbBuff1->pQBuffer = &pfSymbolBuffer1Q[MFDemodStat1.uiNextReadSymb];
ChannelState.pfCplxSymbBuff2->pIBuffer = &pfSymbolBuffer2I[MFDemodStat2.uiNextReadSymb];
ChannelState.pfCplxSymbBuff2->pQBuffer = &pfSymbolBuffer2Q[MFDemodStat2.uiNextReadSymb];
*/ ChannelState.ioffset = MFDemodStat1.uiNextReadSymb;
ChannelState.Ch1Switch = SwitchState.uiPos2SetSwitch1;
ChannelState.Ch2Switch = SwitchState.uiPos2SetSwitch2;
// call the estimation function
channelestimation(&ChannelState);
// update the counters/indices
MFDemodStat1.uiNoOfSymb -= TRAINLEN;
MFDemodStat2.uiNoOfSymb -= TRAINLEN;
IncCircIndex(&(MFDemodStat1.uiNextReadSymb), SYMBOLBUFFLEN, TRAINLEN);
//MFDemodStat1.uiNextReadSymb += TRAINLEN;
IncCircIndex(&(MFDemodStat2.uiNextReadSymb), SYMBOLBUFFLEN, TRAINLEN);
//MFDemodStat2.uiNextReadSymb += TRAINLEN;
ReceiverState.RcvState = eRX_ANTENNASEL;
}
else
{ // not enough samples, wait for more
DSK6713_LED_off(0);
// suspend task
SEM_pend(&rxsem,SYS_FOREVER);
TSK_sleep(1);
}
break;
case eRX_ANTENNASEL:
// set the LEDs according to the antenna selection for the following data
if (SwitchState.uiPosSwitch1 == eSWITCH1)
DSK6713_LED_off(2);
else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -