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

📄 main_edma1.c

📁 关于DM642的EDMA一个例程
💻 C
字号:

/*
 *---------main_edma1.c---------
 *
 * This program uses the timer to trigger EDMA events. These events in turn 
 * trigger linked EDMA parameter tables to fill a ping pong buffer structure.
 * On running the program you'll note that the program bounces between the ping 
 * and pong buffers filling each with a value that comes from the source.  
 *
 * Click on View->Memory to view following locations:
 * &ping_data, &pong_data, ping, pong and outbuff
 * By putting breakpoint at the closing brace of ISR, correct DMA transfers
 * can be viewed in the memory window. 
 */

#include <stdio.h>

#include <csl.h>
#include <csl_cache.h>
#include <csl_edma.h>
#include <csl_timer.h>
#include <csl_irq.h>

//---------Global constants---------

//Pick which EDMA transfer completion interrupt we want to use
#define TCCINTNUM   	11

//Ping-pong buffer sizes in no. of ints
#define BUFF_SZ      	256

 

//Transfer count
#define TRANSFER_CNT 	20

//---------Global data definition---------

//Create the buffers. We want to align the buffers to be cache friendly
//  by aligning them on an L2 cache line boundary.
//#pragma DATA_SECTION(ping, ".buffers");
//#pragma DATA_SECTION(pong, ".buffers");
//#pragma DATA_SECTION(outbuff, ".buffers");

//#pragma DATA_ALIGN(ping,128);
//#pragma DATA_ALIGN(pong,128);
//#pragma DATA_ALIGN(outbuff,128);
int ping[BUFF_SZ];
int pong[BUFF_SZ];
int outbuff[BUFF_SZ];


static int ping_data;
static int pong_data;

//Global variable used to track the ping-pong'ing
static int pingpong = 0;

volatile int transferCount = 0;

//Declare the CSL objects
TIMER_Handle hTimer;   //Handle for the timer device               
EDMA_Handle hEdma;     //Handle for the EDMA channel               
EDMA_Handle hEdmaPing; //Handle for the ping EDMA reload parameters
EDMA_Handle hEdmaPong; //Handle for the pong EDMA reload parameters
EDMA_Config cfgEdma;   //EDMA configuration structure              

//Create the EDMA configuration structure for ping transfers
EDMA_Config cfgEdmaPing =
{  
    //Making Options parameter register - EDMA_OPT
    EDMA_OPT_RMK
    (          
		EDMA_OPT_PRI_LOW,
   		EDMA_OPT_ESIZE_32BIT,
   		EDMA_OPT_2DS_NO,
   		EDMA_OPT_SUM_NONE,
   		EDMA_OPT_2DD_NO,
   		EDMA_OPT_DUM_INC,
   		EDMA_OPT_TCINT_YES,
   		EDMA_OPT_TCC_OF(TCCINTNUM),
    	EDMA_OPT_TCCM_OF(TCCINTNUM >> 4),
    	EDMA_OPT_ATCINT_NO,
    	EDMA_OPT_ATCC_OF(0),
    	EDMA_OPT_PDTS_DISABLE,
    	EDMA_OPT_PDTD_DISABLE,
        EDMA_OPT_LINK_YES,
    	EDMA_OPT_FS_NO
    ),
    EDMA_SRC_OF(&ping_data),//Source address register 
    EDMA_CNT_OF(BUFF_SZ),   //Transfer count parameter
    EDMA_DST_OF(ping),      //Destination address parameter
    EDMA_IDX_OF(0x00000004),//Index parameter
    EDMA_RLD_OF(0x00000000) //Count reload/link parameter
};                         

//Create the EDMA configuration structure for pong transfers
EDMA_Config cfgEdmaPong = 
{
    //Making Options parameter register - EDMA_OPT
    EDMA_OPT_RMK
    (      
		EDMA_OPT_PRI_LOW,        
		EDMA_OPT_ESIZE_32BIT,
    	EDMA_OPT_2DS_NO,     
    	EDMA_OPT_SUM_NONE,
    	EDMA_OPT_2DD_NO,    
    	EDMA_OPT_DUM_INC,
    	EDMA_OPT_TCINT_YES, 
    	EDMA_OPT_TCC_OF(TCCINTNUM),
    	EDMA_OPT_TCCM_OF(TCCINTNUM >> 4),
    	EDMA_OPT_ATCINT_NO,
    	EDMA_OPT_ATCC_OF(0),
    	EDMA_OPT_PDTS_DISABLE,
    	EDMA_OPT_PDTD_DISABLE,
        EDMA_OPT_LINK_YES,
    	EDMA_OPT_FS_NO
    ),
    EDMA_SRC_OF(&pong_data),//Source address register 
    EDMA_CNT_OF(BUFF_SZ),   //Transfer count parameter
    EDMA_DST_OF(pong),      //Destination address parameter
    EDMA_IDX_OF(0x00000004),//Index parameter
    EDMA_RLD_OF(0x00000000) //Count reload/link parameter
};                         

//---------Function prototypes---------
extern far void vectors();
void setupInterrupts(void);

//Function used to stop EDMA
void stopEdma(void); 
    
//---------main routine---------
void main()
{
    //Initialise CSL
    CSL_init();


    //Initialize the input source data
    ping_data=0x00000000;
    pong_data=0x80000000;
  
    

    //Let's disable/clear related interrupts just in case they are pending
    //  from a previous run of the program.
    setupInterrupts();
    
    //Although not required, let's clear all of the EDMA parameter RAM.
    //This makes it easier to view the RAM and see the changes as we
    //  configure it.
    EDMA_clearPram(0x00000000);
   
  	//Let's open up a timer device, we'll use this to simulate input events
  	//  at a given sample rate.
  	hTimer = TIMER_open(TIMER_DEV1, TIMER_OPEN_RESET);

  	//Lets open up the EDMA channel associated with timer #1.
  	hEdma = EDMA_open(EDMA_CHA_TINT1, EDMA_OPEN_RESET);
  
  	//We also need two EDMA reload parameter sets so let's allocate them
  	//  here. Notice the -1, this means allocate any availale table.
  	hEdmaPing = EDMA_allocTable(0);
  	hEdmaPong = EDMA_allocTable(-1);

  	//Let's copy the ping reload configuration structure to an
  	//  intermediate configuration structure.
  	cfgEdma = cfgEdmaPing;
  
  	//Let's initialize the link fields of the configuration structures
  	cfgEdmaPing.rld = EDMA_RLD_RMK(0,hEdmaPing);
  	cfgEdmaPong.rld = EDMA_RLD_RMK(0,hEdmaPong);
  	cfgEdma.rld     = EDMA_RLD_RMK(0,hEdmaPong);

  	//Now let's program up the EDMA channel with the configuration structure
  	EDMA_config(hEdma, &cfgEdma);
  
  	//Let's also configure the reload parameter tables in the EDMA PRAM
  	//  with the values in the configuration structures.
  	EDMA_config(hEdmaPing, &cfgEdmaPing);
  	EDMA_config(hEdmaPong, &cfgEdmaPong);   

  	//Configure up the timer
  	TIMER_configArgs(	hTimer, 
    					TIMER_CTL_OF(0x00000200), 
    					TIMER_PRD_OF(0x100), //Timer period
    					TIMER_CNT_OF(0)
  					);   

  	//Enable the related interrupts
  	IRQ_enable(IRQ_EVT_EDMAINT);
  	EDMA_intDisable(TCCINTNUM);
  	EDMA_intClear(TCCINTNUM);  
  	EDMA_intEnable(TCCINTNUM);        
  
  	//Enable the EDMA channel
  	EDMA_enableChannel(hEdma);   
  
  	//Finally, enable the timer which will drive everything
  	TIMER_start(hTimer);
	
	//Waiting for interrupts
  	while(transferCount <= TRANSFER_CNT); 
}

void processbuff(int arg)
{
	int *inbuff;
	int x;
  	printf("\n %2d -",transferCount); 
  	if (pingpong)
  	{
  		//If pingpong is 0, then we own the ping input buffer
    	inbuff = ping;
    	printf(" Ping ");
  	}
  	else
  	{
  		//If pingpong is 1, then we own the pong input buffer
    	inbuff = pong;
    	printf(" Pong " );
  	}  
  
  	transferCount++;
  	
  	//Now let's process the input buffer, for simplicity, we'll
  	//  just copy it to the output buffer.
  	for (x=0; x<BUFF_SZ; x++)
  		outbuff[x] = inbuff[x];
  

}

// Function to sets up interrupts to service EDMA transfers
void setupInterrupts(void)
{
	//Point to the IRQ vector table
    IRQ_setVecs(vectors);
    IRQ_nmiEnable();
    IRQ_globalEnable();
    IRQ_map(IRQ_EVT_EDMAINT, 8);
    IRQ_reset(IRQ_EVT_EDMAINT);
}

//Interrupt Service Routine c_int08 : ISR to service EDMAINT. 
//vecs_edma1.asm must be modified to include c_int08 entry.
interrupt void    
c_int08(void)    
{
  	//Clear the pending interrupt from the EDMA interrupt pending register
  	EDMA_intClear(TCCINTNUM);
  
  	//Perform ping-pong
  	pingpong = (pingpong + 1) & 1;

    //Exit from the program if certain no of transfres are done
    if (transferCount >= TRANSFER_CNT)
    {
		TIMER_pause(hTimer);
      	stopEdma();
      	TIMER_close(hTimer);
      	printf ("\nDone.....");
      	exit(0);    
    }
  
  	//Based on if we ping'ed or pong'ed, we need to set the EDMA channel
  	//  link address for the NEXT frame.
	if (pingpong)
	{
    	//Currently doing pong so setup next frame for ping  
    	//Modify the input data source, this just simulates
    	//  the input data changing.
    	ping_data++;


    
    	//Now filling pong so set link to ping
    	EDMA_link(hEdma,hEdmaPing);
  	}
  	else
  	{
    	//Currently doing ping so setup next frame for pong
    	//Modify the output data source, this just simulates
    	//  the input data changing.
    	pong_data++;
    

    	 
    	//Now filling ping so set link to pong
        EDMA_link(hEdma,hEdmaPong);
  	}  
  	processbuff(0);
  	return;
}

//Stops the EDMA service.
void stopEdma(void)
{
    //Disable interrupts, close EDMA channel before exit of the program
    IRQ_disable(IRQ_EVT_EDMAINT);
    EDMA_RSET(CCER,0x00000000);
    EDMA_disableChannel(hEdma);
    EDMA_intDisable(TCCINTNUM);
    EDMA_intClear(TCCINTNUM);

 	EDMA_close(hEdma);
 	EDMA_resetAll();
 	EDMA_RSET(CIPR,0xFFFFFFFF);
 	EDMA_RSET(ECR,0xFFFFFFFF);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -