📄 dsk_app.c
字号:
void main()
{
TARGET_INITIALIZE();
/* Initialize Board Support Library */
DSK6713_init();
/* Initialize LEDs and DIP switches */
DSK6713_LED_init();
DSK6713_DIP_init();
state_r = 1;
state_temp = 7;
lambda = 0.5;
RefIndex=0;
loopIndex=0;
treshold = 100000;
error_report[0] = 1;
/* Clear buffers */
memset((void *)gBufferXmtPing, 0, BUFFSIZE * 4 * 2); // sets both ping and pong to zero by defining double size.
memset(alpha, 0, 2*SUBCARSIZE*sizeof(float));
memset(beta, 0, 2*SUBCARSIZE*sizeof(float));
// compute pilots.*conj(pilots)
prod_element_conj(pilots, pilots, pilots_prod,2*SUBCARSIZE);
b2 = 0;
b3 = 0;
memset((void *)finalData, 0, INTS_IN_FILE * sizeof(unsigned int));
AIC23_setParams(&config); // Configure the codec
initMcbsp(); // Initialize McBSP1 for audio transfers
IRQ_globalDisable(); // Disable global interrupts during setup
initEdma(); // Initialize the EDMA controller
initIrq(); // Initialize interrupts
IRQ_globalEnable(); // Re-enable global interrupts
}
/* ------------------------Helper Functions ----------------------------- */
/*
* initMcbsp() - Initialize the McBSP for codec data transfers using the
* configuration define at the top of this file.
*/
void initMcbsp()
{
/* Open the codec data McBSP */
hMcbsp1 = MCBSP_open(MCBSP_DEV1, MCBSP_OPEN_RESET);
/* Configure the codec to match the AIC23 data format */
MCBSP_config(hMcbsp1, &mcbspCfg1);
/* Start the McBSP running */
MCBSP_start(hMcbsp1, MCBSP_XMIT_START | MCBSP_RCV_START |
MCBSP_SRGR_START | MCBSP_SRGR_FRAMESYNC, 220);
}
/*
* initIrq() - Initialize and enable the DMA receive interrupt using the CSL.
* The interrupt service routine for this interrupt is edmaHwi.
*/
void initIrq(void)
{
/* Enable EDMA interrupts to the CPU */
IRQ_clear(IRQ_EVT_EDMAINT); // Clear any pending EDMA interrupts
IRQ_enable(IRQ_EVT_EDMAINT); // Enable EDMA interrupt
}
/*
* initEdma() - Initialize the DMA controller. Use linked transfers to
* automatically transition from ping to pong and visa-versa.
*/
void initEdma(void)
{
/* Configure transmit channel */
hEdmaXmt = EDMA_open(EDMA_CHA_XEVT1, EDMA_OPEN_RESET); // get hEdmaXmt handle and reset channel
hEdmaReloadXmtPing = EDMA_allocTable(-1); // get hEdmaReloadXmtPing handle
hEdmaReloadXmtPong = EDMA_allocTable(-1); // get hEdmaReloadXmtPong handle
gEdmaConfigXmt.dst = MCBSP_getXmtAddr(hMcbsp1); // set the desination address to McBSP1 DXR
gXmtChan = EDMA_intAlloc(-1); // get an open TCC
gEdmaConfigXmt.opt |= EDMA_FMK(OPT,TCC,gXmtChan); // set TCC to gXmtChan
EDMA_config(hEdmaXmt, &gEdmaConfigXmt); // then configure the registers
EDMA_config(hEdmaReloadXmtPing, &gEdmaConfigXmt); // and the reload for Ping
gEdmaConfigXmt.src = EDMA_SRC_OF(gBufferXmtPong); // change the structure to have a source of Pong
EDMA_config(hEdmaReloadXmtPong, &gEdmaConfigXmt); // and configure the reload for Pong
EDMA_link(hEdmaXmt,hEdmaReloadXmtPong); // link the regs to Pong
EDMA_link(hEdmaReloadXmtPong,hEdmaReloadXmtPing); // link Pong to Ping
EDMA_link(hEdmaReloadXmtPing,hEdmaReloadXmtPong); // and link Ping to Pong
/* Configure receive channel */
hEdmaRcv = EDMA_open(EDMA_CHA_REVT1, EDMA_OPEN_RESET); // get hEdmaRcv handle and reset channel
hEdmaReloadRcvPing = EDMA_allocTable(-1); // get hEdmaReloadRcvPing handle
hEdmaReloadRcvPong = EDMA_allocTable(-1); // get hEdmaReloadRcvPong handle
gEdmaConfigRcv.src = MCBSP_getRcvAddr(hMcbsp1); // and the desination address to McBSP1 DXR
gRcvChan = EDMA_intAlloc(-1); // get an open TCC
gEdmaConfigRcv.opt |= EDMA_FMK(OPT,TCC,gRcvChan); // set TCC to gRcvChan
EDMA_config(hEdmaRcv, &gEdmaConfigRcv); // then configure the registers
EDMA_config(hEdmaReloadRcvPing, &gEdmaConfigRcv); // and the reload for Ping
gEdmaConfigRcv.dst = EDMA_DST_OF(gBufferRcvPong); // change the structure to have a destination of Pong
EDMA_config(hEdmaReloadRcvPong, &gEdmaConfigRcv); // and configure the reload for Pong
EDMA_link(hEdmaRcv,hEdmaReloadRcvPong); // link the regs to Pong
EDMA_link(hEdmaReloadRcvPong,hEdmaReloadRcvPing); // link Pong to Ping
EDMA_link(hEdmaReloadRcvPing,hEdmaReloadRcvPong); // and link Ping to Pong
/* Enable interrupts in the EDMA controller */
EDMA_intClear(gXmtChan);
EDMA_intClear(gRcvChan); // clear any possible spurious interrupts
EDMA_intEnable(gXmtChan); // enable EDMA interrupts (CIER)
EDMA_intEnable(gRcvChan); // enable EDMA interrupts (CIER)
EDMA_enableChannel(hEdmaXmt); // enable EDMA channel
EDMA_enableChannel(hEdmaRcv); // enable EDMA channel
/* Do a dummy write to generate the first McBSP transmit event */
MCBSP_write(hMcbsp1, 0);
}
/*
* copyData() - Copy one buffer with length elements to another.
*/
void copyData(const short *inbuf, short *outbuf, const short length)
{
short i = 0;
for (i = 0; i < length; i++) {
outbuf[i] = inbuf[i];
}
}
/* ---------------------- Interrupt Service Routines -------------------- */
/*
* edmaHwi() - Interrupt service routine for the DMA transfer. It is
* triggered when a complete DMA receive frame has been
* transferred. The edmaHwi ISR is inserted into the interrupt
* vector table at compile time through a setting in the DSP/BIOS
* configuration under Scheduling --> HWI --> HWI_INT8. edmaHwi
* uses the DSP/BIOS Dispatcher to save register state and make
* sure the ISR co-exists with other DSP/BIOS functions.
*/
void edmaHwi(void)
{
static Uint32 pingOrPong = PING; // Ping-pong state variable
static short xmtdone = 0, rcvdone = 0;
/* Check CIPR to see which transfer completed */
if (EDMA_intTest(gXmtChan))
{
EDMA_intClear(gXmtChan);
xmtdone = 1;
}
if (EDMA_intTest(gRcvChan))
{
EDMA_intClear(gRcvChan);
rcvdone = 1;
}
/* If both transfers complete, signal processBufferSwi to handle */
if (xmtdone && rcvdone)
{
if (pingOrPong==PING)
{
SWI_or(&processBufferSwi, PING);
pingOrPong = PONG;
} else
{
SWI_or(&processBufferSwi, PONG);
pingOrPong = PING;
}
rcvdone = 0;
xmtdone = 0;
}
}
/* ------------------------------- Threads ------------------------------ */
/*
* processBuffer() - Process audio data once it has been received.
*/
void processBuffer(void)
{
Uint32 pingPong;
/* Get contents of mailbox posted by edmaHwi */
pingPong = SWI_getmbox();
/* Copy data from transmit to receive, could process audio here */
if (pingPong == PING) {
/* Toggle LED #3 as a visual cue */
DSK6713_LED_toggle(3);
copy2Data(gBufferRcvPing, ProcessBuffer, procBUFFSIZE);
transmit_Handle = gBufferXmtPing;
processData(ProcessBuffer, procBUFFSIZE);
} else {
/* Toggle LED #2 as a visual cue */
DSK6713_LED_toggle(2);
/* Copy receive PONG buffer to transmit PONG buffer */
copy2Data(gBufferRcvPong, ProcessBuffer, procBUFFSIZE);
transmit_Handle = gBufferXmtPong;
processData(ProcessBuffer, procBUFFSIZE);
}
}
/*
* Process the recieved data
*/
void processData(short *databuf, short length)
{
// Find beginning of first frame:
short startindex[2], done = 0;
while(!done) // done is the semaphore to check if the buffer is processed
{
if(b2 >= INTS_IN_FILE) // Are we done?
state_r=5;
// Is the received data a training frame?
if(loopIndex==5){
state_temp = state_r;
state_r = 7;
loopIndex = 0;
error_report[error_report[0]] = RefIndex;
error_report[0]++;
}
// Switch over the states for training, data receiving, waiting during feedback and rtdx host transmission.
switch(state_r){
case 1: // Wait for first synchronizing signal
framesync(databuf, startindex, length);
DSK6713_LED_toggle(1);
if(startindex[0] != 0)
{
DSK6713_LED_toggle(0);
// Initialize processing of first frame!
if((startindex[0]+48)<(procBUFFSIZE-FRAMELEN)){
copyData(&databuf[startindex[0]+48], framebuffer, FRAMELEN);
trainingRun(framebuffer);
nextFrame = startindex[0]+48+FRAMELEN;
frameNumber = 1;
train_count = -3;
done = 1;
state_r = 7;
} else { // The frame overlaps the buffer borders..
copyData(&databuf[startindex[0]+48], framebuffer, (procBUFFSIZE-startindex[0]-48));
nextFrame = FRAMELEN-(procBUFFSIZE-startindex[0]-48);
state_r = 2;
done = 1;
}
break;
} else { // Wait for sync in next buffer
DSK6713_LED_off(1);
DSK6713_LED_off(0);
noise_h = noise_estimation(databuf); // Empty frame! Do noise estimation while waiting.
done = 1; // if noise_h is over 4000 this might cause a false synchronization! Adjust with framesync treshold.
}
break;
case 2: // Still recieving TrainingData
DSK6713_LED_toggle(1);
copyData(databuf, &framebuffer[FRAMELEN-nextFrame], (nextFrame));
trainingRun(framebuffer);
frameNumber = 1;
train_count = -3;
state_r = 7;
break;
case 3: // What's next data to be processed..
DSK6713_LED_toggle(0);
if(nextFrame<(procBUFFSIZE-RECIEVELEN)){
copyData(&databuf[nextFrame], framebuffer, RECIEVELEN);
extractFrame(framebuffer, RECIEVELEN);
nextFrame = nextFrame+RECIEVELEN;
frameNumber++;
// state_r = 3; // state should remain, does not need to be changed.
} else { // The frame overlaps the buffer borders, save this part and wait for next buffer.
copyData(&databuf[nextFrame], framebuffer, (procBUFFSIZE-nextFrame));
nextFrame = RECIEVELEN-(procBUFFSIZE-nextFrame);
state_r = 4;
done = 1;
}
break;
case 4: // Buffer begins with a half frame, assemble and process.
DSK6713_LED_toggle(1);
copyData(databuf, &framebuffer[RECIEVELEN-nextFrame], (nextFrame));
extractFrame(framebuffer, RECIEVELEN);
frameNumber++;
state_r = 3;
break;
case 5: // All frames are recieved.. Send data to host
//done = 1;
state_r=1;
rtdx_send_result(); //finalData);
frameNumber = 1;
break;
case 6:
// Delay while training is processed.
frameNumber++;
if(frameNumber>4) { // How long the receiver has to wait for the feedback to be processed
state_r = 3;
}
done = 1;
break;
case 7: // Training data overlaps buffer boarder
copyData(&databuf[nextFrame], framebuffer, (procBUFFSIZE-nextFrame));
nextFrame = RECIEVELEN-(procBUFFSIZE-nextFrame);
state_r = 8;
done = 1;
break;
case 8: // Buffer begins with a half training frame..
DSK6713_LED_toggle(1);
copyData(databuf, &framebuffer[RECIEVELEN-nextFrame], (nextFrame));
if(train_count!=0)
trainingRun(framebuffer);
else {
trainingFrame(framebuffer); // Train and send feedback
state_temp = 6;
done = 1;
lambda = 0.2; // Set forgettingfactor for the channel est. during transmission
}
train_count++;
state_r = state_temp;
break;
default : // Something wrong..
done = 1;
exit(-1);
break;
}
}
}
void trainingRun(short *framebuffer)
{
// Do the traning on the 1280 elements long training sequence.
int i;
// you receive rx : size upfactor*buffsize+(filter_length-1)
memset(temp,0,(RECIEVELEN+80)*sizeof(float));
for(i=0;i<RECIEVELEN;i++)
temp[i+40] = (float)framebuffer[i];
DSPF_sp_convol(temp, cos_filter, rx, FILTER_LENGTH-1, RECIEVELEN+(FILTER_LENGTH-1));
RefIndex = sync(rx, training);
for (i=0;i<256;i++)
{
temp[i*2]=rx[RefIndex+i*UPFACTOR+32*UPFACTOR];
temp[i*2+1] = 0;
}
// Run FFT
dft_DSP(temp, workbuffer); // workbuffer contains 254 values now.
// Do channel estimation
filter_estimation(pilots, workbuffer, pilots_prod, lambda, alpha, beta, h_hat, temp);
}
void trainingFrame(short *framebuffer)
{
// Do the traning on the 1280 elements long training sequence.
int i;
// you receive rx : size upfactor*buffsize+(filter_length-1)
memset(temp,0,(RECIEVELEN+80)*sizeof(float));
for(i=0;i<RECIEVELEN;i++)
temp[i+40] = (float)framebuffer[i];
DSPF_sp_convol(temp, cos_filter, rx, FILTER_LENGTH-1, RECIEVELEN+(FILTER_LENGTH-1));
// Synchronize for fine extraction index
RefIndex = sync(rx, training);
for (i=0;i<256;i++)
{
temp[i*2]=rx[RefIndex+i*UPFACTOR+32*UPFACTOR];
temp[i*2+1] = 0;
}
// Run FFT
dft_DSP(temp, workbuffer); // workbuffer contains 254 values now.
// Estimate the channel
filter_estimation(pilots, workbuffer, pilots_prod, lambda, alpha, beta, h_hat, temp);
// Calculate bit allocation
waterfill_simple(h_hat, noise_h, b, rx, gn); //, int *btot)
for(i=0; i<3; i++) // the first channels can't handle higher modulation.
b[i] = 0;
// Send the bit allocation to the transmitter
memset(temp,0,(RECIEVELEN+40)*sizeof(float));
qpsk(temp, b);
createTrig(transmit_Handle, FRAMELEN);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -