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

📄 tdma55.c

📁 TI OMAP5910(1510)的最简单测试程序,用于 硬件最初的调试,简要文档含环境配置
💻 C
字号:
//test dma
#ifndef _TDMA55_C
#define _TDMA55_C
/*readme.txt

1.如果需要同步触发dma,则ccr的fs比特必须为1(表示中断触发传送1frame),
否则为0(表示中断触发传送1个element)。
2.ti的csl代码和example程序竟然支持8bit操作,何故?
3.auto mode:0表示地址不变;1表示 8比特、16比特、或32比特操作(),取决于CSDP中的
	data_type值。
	由于dsp不支持8比特,而是16比特操作加1,32比特操作后加2---是否在程序设计
	时要考虑这一点?

4.DMA_GSCR的最低比特指示,
DMA destination indexing enhancement: Softwareincompatible control.
0: Destination element index = DMA_CSEI register,destination frame index = DMA_CSFI register
   This mode permits software compatibility with previous versions of the DMA controller 
   hardware.The source indexing registers are also used fordestination indexing. This is the
    power1–up default state.
    
1: Destination element index = DMA_CDEI register,destination frame index = DMA_CDFI register
  This mode of operation has separate destination element and frame indexes, which are 
  configured by the channel destination element index and the channel destination frame index,
   respectively.
	是否表示,0的时候dma_cdei/dma_cdfi的内容无效,直接使用源地址的设置。

5.检查csei/csfi/cdei/cdfi是否设置
6.csdp中的burst/pack比特是否需要设置?
7.!!!!CSL中关于8bit、16比特、32比特的操作很可能有bug,查看一下dat类的设置。
8.csdp的burst操作在dsp--》emif、arm-》fifo时不同,前者可以用16byte,后者1byte。内部拷贝
可以用16byte,但往外设比如mcbsp,可能只能用1byte。
9.CCR之end_prog比特用来dma的自动reload,步骤:
   清repeat比特为0(dma将等待end prog比特=1)--》
   清repeat bit比特为0
   开始写congfig寄存器
   置repeat bit为1
   
10.cicr用于中断控制(但同步中断触发的控制在ccr中)。设置以下比特为有效:
  传送完1frame 或 传送完1block、dma drop中断、time out中断.
  在缺省初始化时,设置一下dma drop和time out。
11.注意,往mc bsp等外设通过dma手法数据之src/dst可能是tipb。

12.tipb的控制
  cmr:
  	cpu prio=1时表示cpu总可以抢到tipb总线,应该用‘0’
  	strb1/strb2比特都设置成0..dsp以最快速度读取寄存器
 


13.idle控制比特全部设为无效,即不idle。
14.

*/

/*

This testcase is a basic testcase -32-bit , 1d to 1d , SDRAM to SDRAM transfers.

If the value of the variable testResult is 0xFACE, then the test case has passed.

*/
#include "includes.h"
#include "includes_async.h"
#include "dsp_includes.h"
//-******************************************************-//
//设置dma的流程:
//GlobalInitDma
//InitDma
//DmaSetSrcMem
//DmaSetDstMem
//.....
//DmaEndProg(1) ---表示设置完毕
//DmaStart
//-***********************************************************-//

void GlobalInitDma(void)
//dma设置为不支持"空闲时idle"
{
 	_PREG_SET(_DMA_DMAGCR_ADDR,0x00);
	/*GCR比特:
	  auto_idle: 0设置为free run.1设置为不用时idle。
	  free=0:emu中断dma的传送;1不中断
	  mpui_excel:0--mpui有权access dsp内所有的ram
	  mpui_prio:0--mpui优先级为低
	*/
	_PREG_SET(_DMA_DMAGTCR_ADDR,0 );//DARAM/SARAM之time out全部disable掉
	_PREG_SET(_DMA_DMAGSCR_ADDR,1 ); 
	//1:dma之源地址和目的地址使用各自的地址增加方式csei、csfi、cdei、cdfi
	//0:目的地址增长方式与源地址一样的:都是从csei、csfi得到
}

DMA_Handle InitDma(Uint16 dev_no,Uint16 prio,Uint16 sync_int,
		   Uint16 frm_len,Uint16 elem_len,Uint16 dat_type)
		  
//dev_no表示dma设备号
//auto:表示参数是否自动reload
//prio:1表示此dma在dma循环中为高优先级,0表示低优先级
//sync_int:表示同步触发中断号(eventId).0表示无同步触发中断
//本函数将src、dst地址自动增加方式设置为:src、dst独自依赖于csei/csfi、cdei/cdfi
//dat_type:表示8比特、16比特、还是32比特
//缺省设置仅在1个block传完后才中断
{
	DMA_Handle hDma;
	Uint16  i=0;
	
	hDma = DMA_open(1, DMA_OPEN_RESET);

	if(hDma==INV){
	   printf("open dma handle err:device no=%d\n",dev_no);
	   return(NULL);	
	 }
 
       
    
    
    //val=DMA_RGET_H(hDma,DMACFN);
    //val=DMA_RGET_H(hDma,DMACEN);
    
    while (DMA_FGET_H(hDma,DMACCR,EN));    /* wait if a previous transfer is pending */
    DmaEndProg(hDma,0);
    DmaFlushFifo(hDma,1);
    for(i=0;i<100;i++); //等待清空dma之fifo
    DmaFlushFifo(hDma,0);
    DMA_RSET_H(hDma,DMACFN, frm_len);
    DMA_RSET_H(hDma,DMACEN,elem_len);
    sync_int=sync_int&0x1f;
    
    	  DMA_RSET_H(hDma,DMACCR,DMA_DMACCR_RMK(
                      DMA_DMACCR_DSTAMODE_POSTINC,    /* Destination address mode is postincrement */
                      DMA_DMACCR_SRCAMODE_POSTINC,    /* Source address mode is postincrement      */
                      DMA_DMACCR_ENDPROG_OFF,         /* Registers will not be reloaded after end of current transfer */
                      DMA_DMACCR_FIFOFLUSH_OFF,       /* This is a reserved bit. Must always be 0  */
                      DMA_DMACCR_REPEAT_OFF,          /* Registers will not be reloaded after end of current transfer */
                      DMA_DMACCR_AUTOINIT_OFF,        /* Auto initialisation mode is turned off */
                      DMA_DMACCR_EN_STOP,             /* The channel is disabled */
                      prio,                           /* Channel priority is set from the corresponding bit in _CSL_DatChaPriority */
                      DMA_DMACCR_FS_DISABLE,          /* Frame synchronisation is disabled */
                      sync_int            /* DMA transfer does not start on any event */
                      ));
    
    
    DMA_RSET_H(hDma,DMACICR,DMA_DMACICR_RMK(
                      DMA_DMACICR_BLOCKIE_OFF,         /* Interrupt only on completion of the entire block */
                      DMA_DMACICR_LASTIE_OFF,
                      DMA_DMACICR_FRAMEIE_OFF,
                      DMA_DMACICR_FIRSTHALFIE_OFF,
                      DMA_DMACICR_DROPIE_OFF,
                      DMA_DMACICR_TIMEOUTIE_OFF
                      ));

    DMA_RSET_H(hDma,DMACSDP,DMA_DMACSDP_RMK(
                      DMA_DMACSDP_DSTBEN_NOBURST,      /* Single access at the destination */
		      DMA_DMACSDP_DSTPACK_OFF,         /* Turn off packing at the destination */
		      DMA_DMACSDP_DST_DARAM,                      /* The destination type may be one of SARAM, DARAM or EMIF as computed above */
                      DMA_DMACSDP_SRCBEN_NOBURST,      /* Single access at the source */
                      DMA_DMACSDP_SRCPACK_OFF,         /* Turn off packing at the source */
                      DMA_DMACSDP_SRC_DARAM,                      /* The source type may be one of SARAM, DARAM or EMIF as computed above */
                      dat_type        /* One element is 8-bit wide */
                      ));
                      
/*
_DMA_DMACSEI_ADDR(n)
*/                      
	DMA_RSET_H(hDma,DMACFI,0);  //这种方式不用,设置成任何值都可以
	DMA_RSET_H(hDma,DMACEI,2);
	
//-***************************************************-//	   
	 //  DMA_getConfig (hDma, &myconfig);
	   return(hDma);

}

void DmaSetSrcMem(DMA_Handle hDma,void* src_adr,Uint16 inc_mode,Uint16 burst_on_off)
//inc_mode:0--const;1--加1 
//
{

	Uint32 lsrc;

   	Uint16 DatSrcType ;/* whether the source is in SARAM, DARAM or EMIF */
   	
   	   lsrc=((Uint32)src_adr)<<1;
	
	   
//-***************************************************-//
       
    /* Calculate whether the source and destination lie in SARAM, DARAM or EMIF */
    DatSrcType = DMA_DMACSDP_SRC_DARAM; 
    if (lsrc>=(Uint32)EMIF_START_ADDRESS){
        DatSrcType = DMA_DMACSDP_SRC_EMIF;
    }
    else {
      if(lsrc>=(Uint32)SARAM_START_ADDRESS) 
             DatSrcType = DMA_DMACSDP_SRC_SARAM;
    }
    
    printf("DatSrcType =%d\n",DatSrcType);
    
    DMA_RSET_H(hDma,DMACSSAL,(Uint16)((Uint32)lsrc & 0xFFFFu));            /* Extracting lower 16 bits of source address      */
    DMA_RSET_H(hDma,DMACSSAU,(Uint16)(((Uint32)lsrc >> 16) & 0x00FFu));    /* Extracting upper 8 bits of source address       */
    
    //DMA_FSET_H(hDma,DMACCR,SRCAMODE,inc_mode);
    DMA_FSET_H(hDma,DMACSDP,SRC,DatSrcType);
    DMA_FSET_H(hDma,DMACCR,SRCAMODE,inc_mode);

    if(burst_on_off){
        //msk=;
    	DMA_FSET_H(hDma,DMACSDP,SRCBEN,DMA_DMACSDP_SRCBEN_BURST4); 
    }
	   
}

void DmaSetDstMem(DMA_Handle hDma,void* dst_adr,Uint16 inc_mode,Uint16 burst_on_off)
{

	Uint32 ldst;

   	Uint16 DatDstType;/* whether the source is in SARAM, DARAM or EMIF */
   	
	ldst=((Uint32)dst_adr)<<1;
	   
//-***************************************************-//
       
    /* Calculate whether the source and destination lie in SARAM, DARAM or EMIF */
    DatDstType = DMA_DMACSDP_DST_DARAM; /* Default source is in DARAM */
    if (ldst >= (Uint32)EMIF_START_ADDRESS){ /* Starting address of ASRAM */
        DatDstType = DMA_DMACSDP_DST_EMIF;
    }
    else if (ldst >= (Uint32)SARAM_START_ADDRESS){ /* Starting address of SARAM */
             DatDstType = DMA_DMACSDP_DST_SARAM;
    }
    
    DMA_RSET_H(hDma,DMACDSAL,(Uint16)((Uint32)ldst & 0xFFFFu));            /* Extracting lower 16 bits of source address      */
    DMA_RSET_H(hDma,DMACDSAU,(Uint16)(((Uint32)ldst >> 16) & 0x00FFu));    /* Extracting upper 8 bits of source address       */
    
    DMA_FSET_H(hDma,DMACCR,DSTAMODE,inc_mode);
    DMA_FSET_H(hDma,DMACSDP,DST,DatDstType);
    if(burst_on_off)
    	DMA_FSET_H(hDma,DMACSDP,DSTBEN,DMA_DMACSDP_DSTBEN_BURST4); 

}
void DmaFastSetSrcMem(DMA_Handle hDma,void* src_adr)
//不检查地址空间位置,直接设置
{ 	Uint32 lsrc;
	lsrc=((Uint32)src_adr)<<1;
    DMA_RSET_H(hDma,DMACSSAL,(Uint16)((Uint32)lsrc & 0xFFFFu));   
    DMA_RSET_H(hDma,DMACSSAU,(Uint16)(((Uint32)lsrc >> 16) & 0x00FFu));
}

void DmaFastSetDstMem(DMA_Handle hDma,void* dst_adr)
//不检查地址空间位置,直接设置
{ 	Uint32 ldst;
	ldst=((Uint32)dst_adr)<<1;
    DMA_RSET_H(hDma,DMACDSAL,(Uint16)((Uint32)ldst & 0xFFFFu));   
    DMA_RSET_H(hDma,DMACDSAU,(Uint16)(((Uint32)ldst >> 16) & 0x00FFu));
	
}
void DmaFastSetFrmElemLen(DMA_Handle hDma,Uint16 frm_len,Uint16 elem_len)
//不检查地址空间位置,直接设置
{
    DMA_RSET_H(hDma,DMACFN, frm_len);
    DMA_RSET_H(hDma,DMACEN,elem_len);
}

void DmaSetSrcMcBsp()
{
	
}

void DmaSetDstMcBsp()
{
	
}

void DmaSetSrcMcsi()
{
	
}

void DmaSetDstMcsi()
{
	
}

void DmaSetNtxtSrcDstMem(DMA_Handle hDma)
//此时dma应该已经设置为auto init
{
	DmaRepeat(hDma,0);  //当前dma完成后等待endprog比特=1才开始下一次发送
	DmaEndProg(hDma,0);
//-***************************************************-//
	
//-***************************************************-//
	DmaEndProg(hDma,1);
}
void DmaSetNtxtSrcMem(DMA_Handle hDma)
//此时dma应该已经设置为auto init
{
	DmaRepeat(hDma,0);  //当前dma完成后等待endprog比特=1才开始下一次发送
	DmaEndProg(hDma,0);
//-***************************************************-//
	
//-***************************************************-//
	DmaEndProg(hDma,1);
}
void DmaSetNtxtDstMem(DMA_Handle hDma)
//此时dma应该已经设置为auto init
{
	DmaRepeat(hDma,0);  //当前dma完成后等待endprog比特=1才开始下一次发送
	DmaEndProg(hDma,0);
//-***************************************************-//
	
//-***************************************************-//
	DmaEndProg(hDma,1);
	
}

void DmaSetNtxtDmaParaTipb(void)
{
	
}


void DmaSetInt(DMA_Handle hdma,Uint16 intmode,void (*func)(void) ,Uint16 prio)
//func:表示中断服务程序入口
//prio:优先级
//intmode表示是blk中断、frame中断,0.5frame中断等,各比特域定义如下.
/*bit5:				   bit0
 block_ie last_ie frame_ie half_ie drop_ie tout_ie 
#define DMA_INT_BLOCK		(1<<5)
#define DMA_INT_LAST_FRAME	(1<<4)
#define DMA_INT_FRAME		(1<<3)
#define DMA_INT_HALF_FRAME	(1<<2)
#define DMA_INT_DAT_DROP	(1<<1) //最后2个选项在初始化时设定
#define DMA_INT_TIME_OUT	(1<<0)
*/
{
	Uint16 int_no=0;
	//intmode=intmode|DMA_INT_DAT_DROP|DMA_INT_TIME_OUT;
	DMA_RSET_H(hdma,DMACICR,intmode);
	if(intmode==0)  //不响应任何中断
		return;
	int_no=DMA_getEventId(hdma);
	DMA_RGET_H(hdma,DMACSR);
	IRQ_clear(int_no);
	IRQ_plug(int_no,func,prio);
	IRQ_enable(int_no);
}

void DmaStart(DMA_Handle hDma)
{
	DMA_start(hDma);
}

Uint16 DmaRunning(DMA_Handle hDma)
{//如何知道dma正在传送????

	return(DMA_FGET_H(hDma,DMACCR,EN));	
}

void DmaRepeat(DMA_Handle hDma,Uint16 on_off)
//on_off=1 on;0 off.
{	
	DMA_FSET_H(hDma,DMACCR,REPEAT,on_off);
}

void DmaAutoInit(DMA_Handle hDma , Uint16 on_off)
//on_off=1 on;0 off.
{
	DMA_FSET_H(hDma,DMACCR,AUTOINIT,on_off);
}
void DmaFlushFifo(DMA_Handle hDma,Uint16 on_off)
//on_off=1 on;0 off
{
	DMA_FSET_H(hDma,DMACCR,FIFOFLUSH,on_off);
}
void DmaEndProg(DMA_Handle hDma,Uint16 yes_no)
{
	DMA_FSET_H(hDma,DMACCR,ENDPROG,yes_no);
}

void DmaStop(DMA_Handle hDma)
{
	DMA_stop(hDma);
	DmaFlushFifo(hDma,1);
} 

void DmaFs(DMA_Handle hDma,Uint16 fs_mode)
/*fs_mode:
#define FS_FRAME	0   //同步触发时一次读1帧
#define FS_ELEMENT	1   //同步触发时1次读1个element
*/
{

         if(fs_mode==FS_FRAME)
         	DMA_FSET_H(hDma,DMACCR,FS,DMA_DMACCR_FS_ENABLE);
         else
         	DMA_FSET_H(hDma,DMACCR,FS,DMA_DMACCR_FS_DISABLE);
}
extern DMA_Handle hdma;
void DmaIsr(void)
  //给dma中断写的一个中断服务程序 查询frame/last frame/block中断
  //blk中断后关闭dma并清空fifo。
{
    Uint16 i;
	i=DMA_RGET_H(hdma,DMACSR);
	i=0;
	puts("dma interrupt\n");
}
//-*********************************************************-//

#endif //_TDMA55_C

⌨️ 快捷键说明

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