此例为对csl的直接调用。 实现功能:打开并初始化EDMA_CHA_GPINT11通道,使用寄存器配置方式从src到dst数据表格的拷贝。 传输数据量:16个16位单字。 myhedma=EDMA_open(EDMA_CHA_GPINT11,EDMA_OPEN_RESET); //open edma . EDMA_config(myhedma,&myconfig); //configure edma. EDMA_enableChannel(myhedma); 打开并配置edma。 因edma与dma不同,他基于事件触发,所以我们手工写edma事件置位寄存器让其工作。如下 EDMA_setChannel(myhedma); 等待EVMDM642_wait(1000); 最后检验是否被正确搬移并关闭edma for(I=0;I<=N-1;I++){ if(dst[I]!=0xBEEFu) {++err;} EDMA_close(myhedma); 点击ccs的view菜单的watch window,打开watch window窗口,运行程序,在watch1下输入src及dst可以看到已正确拷贝。
TIMER程序 本程序从dsp/bios图形配置工具中静态设置timer。首先在dsp/bios中右击TIMER Configuration Manager,创建一timer配置
然后在下的tmer resource manager下选择timer1,(timer0已被dspbios使用,不可再使用)右击,选属性, Open Timer Device Handle hTimer1 Enable pre-Initialization pre-Initialize timerCfg0 到此,即配置好timer1.在程序中打开timer1,首先对中断进行必要的处理,然后打开timer1工作。在由dspbios自动生成的文件Config1cfg_c.c中可以看到相应的代码 TIMER_Config timerCfg0 = { 0x00000305, /* Control Register (CTL) */ 0x00000080, /* Period Register (PRD) */ 0x00000000 /* Counter Register (CNT) */ }; void CSL_cfgInit() { hTimer1 = TIMER_open(TIMER_DEV1, TIMER_OPEN_RESET); TIMER_config(hTimer1, &timerCfg0); } void timer_isr(void)为中断处理函数,每运行一次,timer_int_cnt自加1.运行程序,打断点,在watch window可以看到timer_int_cnt一直在增加,直至20。
IRQ模块 IRQ模块为cpu提供一个用于管理外设中断的控制接口。其配置参数如下: IRQ_Config myConfig = { myIsr, 0x00000000, IRQ_CCMASK_DEFAULT, IRQ_IEMASK_DEFAULT }; 第一个为中断函数地址,This is the address of the interrupt service routine to be called when the interrupt happens. This function must be C-callable and must NOT be declared using the interrupt keyword. 第二个为函数传递参数。第3个为Cache control mask: 决定DSP/BIOS dispatcher处理cache 设置,可选模式具体见csl文档。 。第4个Interrupt enable mask。决定处理中断时how interrupts are masked。有三种选择 Use IRQ_IEMASK_ALL to mask out all interrupts including self,屏蔽所有中断,use IRQ_IEMASK_SELF to mask self (prevent an ISR from preempting itself), or use the default which is the same as IRQ_IEMASK_SELF。 IRQ_setVecs(myIvtTable); 设置中断向量基地址 eventId=TIMER_getEventId(hTimer1); 获取timer1的irq 事件id号。 IRQ_config(eventId,&myConfig); 配置该irq。 IRQ_enable(eventId); IRQ_globalEnable(); 使能中断。 该程序中的timer1在dsp/bios中的配置如上一程序。 interrupt void myIsr() 上面指定的中断函数。注意前面应加上interrupt。程序中为空,可以根据需要加上相关代码。
mian.c代码 #include <csl.h> #include <csl_irq.h> #include <csl_timer.h> #include "Config1cfg.h" #define NVECTORS 256 #pragma DATA_SECTION(myIvtTable,".myvec") int myIvtTable[NVECTORS]; interrupt void myIsr(); IRQ_Config myConfig = { myIsr, 0x00000000, IRQ_CCMASK_DEFAULT, IRQ_IEMASK_DEFAULT };
main(){ Uint16 eventId; int old_intm; old_intm=IRQ_globalDisable(); IRQ_setVecs(myIvtTable); eventId=TIMER_getEventId(hTimer1); IRQ_config(eventId,&myConfig); IRQ_clear(eventId); IRQ_enable(eventId); IRQ_globalRestore(old_intm); TIMER_start(hTimer1); IRQ_globalEnable(); } interrupt void myIsr() { }
Config1cfg.h代码 /* Do *not* directly modify this file. It was */ /* generated by the Configuration Tool; any */ /* changes risk being overwritten. */
/* INPUT Config1.cdb */
#define CHIP_DM642 1
/* Include Header Files */ #include <std.h> #include <hst.h> #include <swi.h> #include <tsk.h> #include <log.h> #include <sts.h>
#ifdef __cplusplus extern "C" { #endif
extern far HST_Obj RTA_fromHost; extern far HST_Obj RTA_toHost; extern far SWI_Obj KNL_swi; extern far SWI_Obj SWI0; extern far TSK_Obj TSK_idle; extern far LOG_Obj LOG_system; extern far STS_Obj IDL_busyObj; extern far void CSL_cfgInit();
#ifdef __cplusplus } #endif /* extern "C" */
Config1cfg_c.c代码 /* Do *not* directly modify this file. It was */ /* generated by the Configuration Tool; any */ /* changes risk being overwritten. */
/* INPUT Config1.cdb */
/* Include Header File */ #include "Config1cfg.h"
#ifdef __cplusplus #pragma CODE_SECTION(".text:CSL_cfgInit") #else #pragma CODE_SECTION(CSL_cfgInit,".text:CSL_cfgInit") #endif
#ifdef __cplusplus #pragma FUNC_EXT_CALLED() #else #pragma FUNC_EXT_CALLED(CSL_cfgInit) #endif
/* Config Structures */ /* Handles */
/* * ======== CSL_cfgInit() ======== */ void CSL_cfgInit() { }
main.c代码 #include <csl.h> #include <csl_edma.h> #define N 16 #pragma DATA_SECTION(src,".damMem") //PUT SRC IN DMAMEM SECTION #pragma DATA_ALIGN(src,256) //align src Uint16 src[N]={ 0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu, 0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,0xBEEFu,}; #pragma DATA_SECTION(dst,".dmaMem") Uint16 dst[N]; EDMA_Config myconfig={ EDMA_OPT_RMK( EDMA_OPT_PRI_LOW,//edma privilege EDMA_OPT_ESIZE_16BIT,// EDMA_OPT_2DS_NO, EDMA_OPT_SUM_INC, EDMA_OPT_2DD_NO, EDMA_OPT_DUM_INC, EDMA_OPT_TCINT_NO, EDMA_OPT_TCC_OF(0), EDMA_OPT_TCCM_OF(0), EDMA_OPT_ATCINT_NO, EDMA_OPT_ATCC_OF(0), EDMA_OPT_PDTS_DEFAULT, EDMA_OPT_PDTD_DEFAULT, EDMA_OPT_LINK_NO, EDMA_OPT_FS_YES ), EDMA_SRC_OF(&src[0]), EDMA_CNT_OF(N), EDMA_DST_OF(&dst[0]), EDMA_IDX_OF(0x00000002), EDMA_RLD_OF(0x00000000) }; //parameter of edma
void taskFunc(void); //announce of task void main(){
CSL_init(); //if you want to use csl modules ,csl_init() function must be called first. taskFunc();
//start taskfunc() }
void taskFunc(void){ Uint16 err=0; //the number of wrong member Uint16 I; EDMA_Handle myhedma; //edma handle
myhedma=EDMA_open(EDMA_CHA_GPINT11,EDMA_OPEN_RESET); //open edma . EDMA_config(myhedma,&myconfig); //configure edma. EDMA_enableChannel(myhedma);
EDMA_setChannel(myhedma); //soft trigger an EDMA channel EVMDM642_wait(1000); //wait for(I=0;I<=N-1;I++){ if(dst[I]!=0xBEEFu) {++err;} //judge } EDMA_close(myhedma);//close the edma }
|