⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rxmain.c

📁 MIMO 2x2接收端选择全系统仿真代码
💻 C
📖 第 1 页 / 共 4 页
字号:
            }
			// 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 + -