📄 txmain.c
字号:
/*****************************************************************************
Module : Main Transmitter Application
******************************************************************************
Function : Contains the main processes for the transmitter
Procedures : main()
processSISO()
processMIMO()
processBuffer()
checkDIPswitch()
Old History: 2005-04-18 AS created
2005-04-27 AS version 0.2
2005-05-08 AS version 0.3, processMIMO/SISO added.
Author : $Author: Adrian $
Revision : $Revision: 7 $
Modified : $Modtime: 05-05-30 19:12 $
File : $Workfile: txmain.c $
******************************************************************************
KTH, Royal Institute of Technology, S3, Stockholm
*****************************************************************************/
/*--- Include files --------------------------------------------------------*/
/* import */
#include "transmittercfg.h"
#include "../common/commondef.h"
#include "txinit.h"
#include "txfunctions.h"
#include "txhostcomm.h"
/*
* These are include files that support interfaces to BIOS and CSL modules
* used by the program.
*/
#include <std.h>
#include <swi.h>
#include <log.h>
#include <c6x.h>
#include <csl.h>
#include <tsk.h>
//#include <math.h>
#include "dsk6713.h"
#include "dsk6713_led.h"
#include "dsk6713_dip.h"
#include "dsk6713_aic23.h"
/* export */
#include "txmain.h"
/*=== End of include files =================================================*/
/*--- Global variables definition ------------------------------------------*/
/*=== End of global variables definition ===================================*/
/*--- Global constants definition ------------------------------------------*/
/*=== End of global constants definition ===================================*/
/*--- Local defines --------------------------------------------------------*/
/*=== End of local defines =================================================*/
/*--- Local types declaration ----------------------------------------------*/
/*=== End of local types declaration =======================================*/
/*--- Local variables definition -------------------------------------------*/
/*
* Data buffer declarations - the program uses four logical buffers of size
* BUFFSIZE, one ping and one pong buffer on both receive and transmit sides.
*/
#pragma DATA_ALIGN(gBufferXmtPing,32);
Int16 gBufferXmtPing[BUFFSIZE]; // Transmit PING buffer
#pragma DATA_ALIGN(gBufferXmtPong,32);
Int16 gBufferXmtPong[BUFFSIZE]; // Transmit PONG buffer
#pragma DATA_ALIGN(gBufferRcvPing,32);
Int16 gBufferRcvPing[BUFFSIZE]; // Receive PING buffer
#pragma DATA_ALIGN(gBufferRcvPong,32);
Int16 gBufferRcvPong[BUFFSIZE]; // Receive PONG buffer
// Buffer for the delay introduced by the pulse shapeing filter (only used once for the end of the pilot sequence)
Int16 pDelayBuffer[(RRCLEN*OVERSAMPLING)/2];
#pragma DATA_ALIGN(pBufferTemp1I,32);
float pBufferTemp1I[BUFFSIZE/2];
#pragma DATA_ALIGN(pBufferTemp1Q,32);
float pBufferTemp1Q[BUFFSIZE/2];
#pragma DATA_ALIGN(pBufferTemp2I,32);
float pBufferTemp2I[BUFFSIZE/2];
#pragma DATA_ALIGN(pBufferTemp2Q,32);
float pBufferTemp2Q[BUFFSIZE/2];
#pragma DATA_ALIGN(pFrameBufferTot1I,32);
float pFrameBufferTot1I[RRCLEN-1+FRAMEBUFFSIZE]; // Buffer to assemble frames for channel 1I
#pragma DATA_ALIGN(pFrameBufferTot1Q,32);
float pFrameBufferTot1Q[RRCLEN-1+FRAMEBUFFSIZE]; // Buffer to assemble frames for channel 1Q
#pragma DATA_ALIGN(pFrameBufferTot2I,32);
float pFrameBufferTot2I[RRCLEN-1+FRAMEBUFFSIZE]; // Buffer to assemble frames for channel 2I
#pragma DATA_ALIGN(pFrameBufferTot2Q,32);
float pFrameBufferTot2Q[RRCLEN-1+FRAMEBUFFSIZE]; // Buffer to assemble frames for channel 2Q
typCOM_fCPLXBUFF cplxBuffer1,cplxBuffer2;
typCOM_fCPLXBUFF cplxFiltStat1,cplxFiltStat2;
typCOM_fCPLXBUFF cplxTempOut1, cplxTempOut2;
Uint8 pDataFrameBuff[DATABUFFSIZE];// data buffer for one frame
/* state variable for transmitter states */
typTX_TRANSMITSTATE TxStates;
// place the pDataBuff in SDRAM
#pragma DATA_SECTION(pDataBuff, ".file")
char pDataBuff[FILEBUFF]; // File buffer for the data to send (host writes data here)
extern DSK6713_AIC23_Config AIC23config;
extern typTXHST_HOSTCOMMSTATE HostCommState;
/*=== End of local variables definition ====================================*/
/*--- Local constants definition -------------------------------------------*/
/*=== End of local constants definition ====================================*/
/*--- Local functions definition -------------------------------------------*/
/*=== End of local functions definition ====================================*/
/*--- Global functions definition ------------------------------------------*/
/****************************************************************************
Function : main()
****************************************************************************
Description : The main user task. Performs application initialization and
starts the data transfer.
Inputs : none
Outputs : none
By : 2005-04-18 Adrian Schumacher / source by Texas Instruments
****************************************************************************/
void main()
{
/* Initialize Board Support Library */
DSK6713_init();
/* Initialize LEDs and DIP switches */
DSK6713_LED_init();
DSK6713_DIP_init();
/* Initialize RTDX */
tskHostCommInitialize();
/* Clear buffers */
memset((void *)gBufferXmtPing, 0, BUFFSIZE * sizeof(Int16));
memset((void *)gBufferXmtPong, 0, BUFFSIZE * sizeof(Int16));
memset((void *)gBufferRcvPing, 0, BUFFSIZE * sizeof(Int16));
memset((void *)gBufferRcvPong, 0, BUFFSIZE * sizeof(Int16));
memset((void *)pBufferTemp1I, 0, BUFFSIZE/2 * sizeof(float));
memset((void *)pBufferTemp1Q, 0, BUFFSIZE/2 * sizeof(float));
memset((void *)pBufferTemp2I, 0, BUFFSIZE/2 * sizeof(float));
memset((void *)pBufferTemp2Q, 0, BUFFSIZE/2 * sizeof(float));
memset((void *)pFrameBufferTot1I, 0, (RRCLEN-1+FRAMEBUFFSIZE) * sizeof(float));
memset((void *)pFrameBufferTot1Q, 0, (RRCLEN-1+FRAMEBUFFSIZE) * sizeof(float));
memset((void *)pFrameBufferTot2I, 0, (RRCLEN-1+FRAMEBUFFSIZE) * sizeof(float));
memset((void *)pFrameBufferTot2Q, 0, (RRCLEN-1+FRAMEBUFFSIZE) * sizeof(float));
/* Initialize variables */
TxStates.TxState = eTX_IDLE;
TxStates.iSyncRep = 2;
TxStates.uFileSize = 0;
TxStates.uNoOfBlocks = 0;
TxStates.TxMethod = eCOM_MIMO;
TxStates.uFrameNbr = 0;
HostCommState.pTxState = &(TxStates.TxState);
HostCommState.pDataBuff = pDataBuff;
HostCommState.puiFileSize = &(TxStates.uFileSize);
HostCommState.pTxMode = &(TxStates.TxMethod);
HostCommState.puiFrameNbr = &(TxStates.uFrameNbr);
HostCommState.piSyncRep = &(TxStates.iSyncRep);
HostCommState.piuNoOfBlocks = &(TxStates.uNoOfBlocks);
HostCommState.puiFrameNbr = &(TxStates.uFrameNbr);
cplxFiltStat1.pIBuffer = pFrameBufferTot1I;
cplxFiltStat1.pQBuffer = pFrameBufferTot1Q;
cplxFiltStat2.pIBuffer = pFrameBufferTot2I;
cplxFiltStat2.pQBuffer = pFrameBufferTot2Q;
cplxBuffer1.pIBuffer = &pFrameBufferTot1I[RRCLEN-1];
cplxBuffer1.pQBuffer = &pFrameBufferTot1Q[RRCLEN-1];
cplxBuffer2.pIBuffer = &pFrameBufferTot2I[RRCLEN-1];
cplxBuffer2.pQBuffer = &pFrameBufferTot2Q[RRCLEN-1];
cplxTempOut1.pIBuffer = pBufferTemp1I;
cplxTempOut1.pQBuffer = pBufferTemp1Q;
cplxTempOut2.pIBuffer = pBufferTemp2I;
cplxTempOut2.pQBuffer = pBufferTemp2Q;
#ifdef _DEBUGLOG
LOG_printf(&trace,"Initialization finished");
#endif
}
/****************************************************************************
Function : processMIMO()
****************************************************************************
Description : State machine for the MIMO transmission.
Inputs : pointer to the transmit buffer
Outputs : none
By : 2005-05-08 Adrian Schumacher
****************************************************************************/
void processMIMO(Int16 *pBufferXmt)
{
int n; // can be used as a general purpose variable/counter
unsigned int un; // can be used as a general purpose variable/counter
unsigned int uiOffset;
Int16 *pSrc, *pDst;
// static unsigned int uiFrameCounter;
static int iSyncFrameCntrl;
static unsigned int uiDataOffset;
static unsigned int uiFracFrame;
static unsigned int uTimeIndex;
switch(TxStates.TxState){
case eTX_IDLE:
// do nothing
#ifdef _DEBUGLOG
LOG_printf(&trace,"state eTX_IDLE");
#endif
break;
case eTX_STARTTX: // send pilot first
#ifdef _DEBUGLOG
LOG_printf(&trace,"state eTX_STARTTX");
#endif
// set the time index according to the start in the frame (used in the formula 2*pi*fc/fs*n)
uTimeIndex = createPilot(&cplxTempOut1,&cplxTempOut2,pBufferXmt,BUFFSIZE/2);
UpConvert(&cplxTempOut1,&cplxTempOut2,pBufferXmt,BUFFSIZE,&uTimeIndex);
// store the last 70 (half the filter lenght) values
pSrc = &pBufferXmt[BUFFSIZE-(RRCLEN*OVERSAMPLING)];
for (n = 0; n < (RRCLEN*OVERSAMPLING)/2; n++)
pDelayBuffer[n] = pSrc[2*n];
// move the pilot 70 samples forth
pSrc = &pBufferXmt[(BUFFSIZE-(IFSYNCSAMP*2))];
pDst = &pBufferXmt[BUFFSIZE-(IFSYNCSAMP*2)+(RRCLEN*OVERSAMPLING)];
memmove(pDst,pSrc,((IFSYNCSAMP*2)-(RRCLEN*OVERSAMPLING))*sizeof(Int16));
// clear the beginning of the buffer
memset(pBufferXmt,0,(BUFFSIZE-(IFSYNCSAMP*2)+(RRCLEN*OVERSAMPLING))*sizeof(Int16));
TxStates.TxState = eTX_STARTFRAME;
#ifdef _DEBUGLOG
LOG_printf(&trace,"change to state eTX_STARTFRAME (line %d)",__LINE__);
#endif
break;
case eTX_STARTFRAME: // assemble and process start frame (similar to sync frame but contains control data)
#ifdef _DEBUGLOG
LOG_printf(&trace,"state eTX_STARTFRAME");
LOG_printf(&trace,"uFileSize set to %d",TxStates.uFileSize);
#endif
// compute the number of blocks/frames to transmit
TxStates.uNoOfBlocks = 0;
uiFracFrame = 0;
if (TxStates.iSyncRep > 0)
{
un = TxStates.uFileSize;
n = 0;
while (un >= DATABUFFSIZE)
{
TxStates.uNoOfBlocks += 1;
n = (n < TxStates.iSyncRep-1 ? n+1 : 0);
un -= (n == 0 ? DATASYMBSYNC : DATABUFFSIZE);
}
// check if the last part can be sent in one frame
n = (n < TxStates.iSyncRep-1 ? n+1 : 0);
if (un > 0)
{
if (n == 0)
{
if (un >= DATASYMBSYNC)
{
TxStates.uNoOfBlocks += 1;
un -= DATASYMBSYNC;
if (un > 0)
{
// still a few bytes left
TxStates.uNoOfBlocks += 1;
uiFracFrame = un;
}
}
else
{
// not all data fits in a sync frame, add one to make room for the rest of the data
TxStates.uNoOfBlocks += 1;
uiFracFrame = un;
}
}
else
{
// not all data fits in a data frame, add one to make room for the rest of the data
TxStates.uNoOfBlocks += 1;
uiFracFrame = un;
}
}
}
else
{
TxStates.uNoOfBlocks = TxStates.uFileSize / DATABUFFSIZE;
if (TxStates.uNoOfBlocks*DATABUFFSIZE < TxStates.uFileSize)
{
uiFracFrame = TxStates.uFileSize - TxStates.uNoOfBlocks*DATABUFFSIZE;
TxStates.uNoOfBlocks += 1;
}
}
TxStates.uNoOfBlocks += 1; // for the first frame
#ifdef _DEBUGLOG
LOG_printf(&trace,"number of blocks = %d",TxStates.uNoOfBlocks);
#endif
HostCommState.cTransReady = 1;
SEM_post(&sem); // to resume the host comm task
// start with the first frame which is frame 0
//uiFrameCounter = 0;
TxStates.uFrameNbr = 0;
// offset for reading out data from the data buffer
uiDataOffset = 0;
// test if there is really a something to send
if (TxStates.uNoOfBlocks == 0)
{
// reset, since there are no frames to send
TxStates.TxState = eTX_TERMINATION;
#ifdef _DEBUGLOG
LOG_printf(&trace,"uNoOfBlocks = 0, change to state eTX_TERMINATION (line %d)",__LINE__);
#endif
break;
}
// assemble data for first frame (start frame)
createStartFrame(pDataFrameBuff,DATABUFFSIZE,&TxStates);
// reset the filter states (used in upsampPulseShape() by the polyphase implementation)
//050508_AS: removed "+FRAMEBUFFSIZE" for the length, since only the states have to be cleared
memset(cplxFiltStat1.pIBuffer,0,(RRCLEN-1)*sizeof(float));
memset(cplxFiltStat1.pQBuffer,0,(RRCLEN-1)*sizeof(float));
memset(cplxFiltStat2.pIBuffer,0,(RRCLEN-1)*sizeof(float));
memset(cplxFiltStat2.pQBuffer,0,(RRCLEN-1)*sizeof(float));
// add the guard intervalls and training sequences
uiOffset = initOverhead(&cplxBuffer1,CH1,eCOM_SYNCFRAME); // channel 1
uiOffset = initOverhead(&cplxBuffer2,CH2,eCOM_SYNCFRAME); // channel 2
// do the 16-QAM mapping for the data
qamMapping(&pDataFrameBuff[0],&cplxBuffer1,uiOffset,(DATASYMBSYNC/2)); // channel 1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -