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

📄 dsk_app.c

📁 详细的OFDM设计过程
💻 C
📖 第 1 页 / 共 3 页
字号:
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 + -