/*===================================================
NAME: dma.c
DESC: DMA memory2memory test
HISTORY:
2001.03.31:purnnamu: draft ver 0.0
====================================================*/
#include "dma.h"
static void __irq Dma0Done(void);
static void __irq Dma1Done(void);
static void __irq Dma2Done(void);
static void __irq Dma3Done(void);
//ch->DMA 通道数; srcAddr->源地址; dstAddr->目的地址; tc->传输数据的大小
//dsz->Data size to be transferred; burst->Initial transfer count
void DMA_M2M(int ch,int srcAddr,int dstAddr,int tc,int dsz,int burst);
typedef struct tagDMA
{
volatile U32 DISRC; //0x0 DMA initial source register
volatile U32 DISRCC; //0x4 DMA initial source control register
volatile U32 DIDST; //0x8 DMA initial destination register
volatile U32 DIDSTC; //0xc DMA initial destination control register
volatile U32 DCON; //0x10 DMA control register
volatile U32 DSTAT; //0x14 DMA count register
volatile U32 DCSRC; //0x18 DMA current Source Register
volatile U32 DCDST; //0x1c DMA current destination register
volatile U32 DMASKTRIG; //0x20 DMA mask trigger register
}DMA;
static volatile int dmaDone;
/*===================================================
function: DMA_Done_Check(DMA *pDMA)
DESC: indicate DMA done, is reading receive the next DMA
HISTORY:
====================================================*/
static void DMA_Done_Check(DMA *pDMA)
{
while(1)
{
if(!(pDMA->DSTAT&(0x3<<20)))
break;
}
}
/*===================================================
function: DMA_Chanel_Selecte(DMA *pDMA, int ch)
DESC: TO special DMA struct address, and load DMA interrup
====================================================*/
static DMA *DMA_Chanel_Selecte(DMA *pDMA, int ch)
{
switch(ch)
{
case 0:
pISR_DMA0=(int)Dma0Done;
rINTMSK&=~(BIT_DMA0); // unmask corresponding interrupt
pDMA=(void *)0x4b000000;
break;
case 1:
pISR_DMA1=(int)Dma1Done;
rINTMSK&=~(BIT_DMA1);
pDMA=(void *)0x4b000040;
break;
case 2:
pISR_DMA2=(int)Dma2Done;
rINTMSK&=~(BIT_DMA2);
pDMA=(void *)0x4b000080;
break;
case 3:
pISR_DMA3=(int)Dma3Done;
rINTMSK&=~(BIT_DMA3);
pDMA=(void *)0x4b0000c0;
break;
}
return pDMA; //return DMA struct pointer
}
/*===================================================
function: DMA_RG_CONFIG(DMA *pDMA, int srcAddr, int dstAddr, int tc, int dsz, int burst)
DESC: some DCONn parameter also need config in function
HISTORY:
====================================================*/
static DMA *DMA_RG_CONFIG(DMA *pDMA, int srcAddr, int dstAddr, int tc, int dsz, int burst)
{
pDMA->DISRC = srcAddr;
pDMA->DISRCC = (LOC_AHB|INC_INC); //LOG_AHB OR LOG_APB INC_INC OR INC_FIXED
pDMA->DIDST = dstAddr;
pDMA->DIDSTC = (LOC_AHB|INC_INC); //like above
// need config for special DMA require
//need config in function term:HWSRCSEL, SWHW_SEL
pDMA->DCON = (tc|DSZ(dsz)|TSZ_BURST(burst));
pDMA->DCON |= DMD_HS; //DMD_HS(handleshake) OR DMD_DM(demand mode)
pDMA->DCON |= SYNC_HCLK; //SYNC_HCLK OR SYNC_PCLK
pDMA->DCON |= RELOAD_N; //RELOAD_Y OR RELOAD_N
pDMA->DCON |= SERVMOD_ALL; //SERVMOD_ALL OR SERVMOD_SIG
//for SW interrupt source
pDMA->DCON |= SWHW_SEL_SW;
//if HW interrupt source need below set
// pDMA->DCON |= SWHW_SEL_HW;
// pDMA->DCON |= HWSRCSEL(num); //num is the source number
// for SW_TRIG
pDMA->DMASKTRIG = (DMA_ON|SW_TRIG_Y); //DMA on,SW_TRIG_Y OR SW_TRIG_N
return pDMA;
}
/*===================================================
void DMA_M2M(int ch,int srcAddr,int dstAddr,int tc,int dsz,int burst)
DESC:
Parameter: dsz:0-byte, 1-half_word, 2-word
burst: 0-signal(byte), 1-burst(word)
HISTORY:
====================================================*/
void Test_DMA(void)
{
//DMA Ch 0
DMA_M2M(0,0x31000000,0x30000000+0x800000,0x30,2,0); //byte,single
}
/*===================================================
function: DMA_M2M(int ch,int srcAddr,int dstAddr,int tc,int dsz,int burst)
DESC:
Parameter: dsz:0-byte, 1-half_word, 2-word
burst: 0-signal(byte), 1-burst(word)
the actual transfer bytes=tc X dsz X burst
HISTORY:
====================================================*/
void DMA_M2M(int ch,int srcAddr,int dstAddr,int tc,int dsz,int burst)
{
int i;
volatile U32 memSum0=0,memSum1=0;
DMA *pDMA;
int length;
length=tc*(burst ? 4:1)*((dsz==0)+(dsz==1)*2+(dsz==2)*4);
Uart_Printf("GEC2440 DMA CH%d MEM-MEM Test\n",ch);
pDMA = DMA_Chanel_Selecte(pDMA,ch);
Uart_Printf("DMA%d %8xh->%8xh,size=%xh(tc=%xh),dsz=%d,burst=%d\n",ch,
srcAddr,dstAddr,length,tc,dsz,burst);
Uart_Printf("Initialize the src.\n");
for(i=srcAddr;i<(srcAddr+length);i+=4)
{ //write data to srcAddr for test
// *((U32 *)i)=i^0x55aa5aa5;
*((int *)i) = 0xaaaaaaaa;
// memSum0+=i^0x55aa5aa5;
}
Uart_Printf("DMA%d start\n",ch);
dmaDone=0;
pDMA = DMA_RG_CONFIG(pDMA, srcAddr, dstAddr, tc, dsz, burst);
DMA_Done_Check(pDMA); //indicate DMA done ,is readying next DMA REQUIRE
Uart_Printf("DMA transfer done\n");
// rINTMSK=BIT_ALLMSK; // mask all interrupt
for(i=dstAddr;i<dstAddr+length;i++) //for examine
{
// memSum1+=*((U32 *)i)=i^0x55aa5aa5;
Uart_Printf("%d\n",*(char *)i);
}
Uart_Printf("\n");
Uart_Printf("i=%x\n", i);
Uart_Printf("GEC2440 DMA CH%d MEM-MEM Test Finished\n",ch);
}
static void __irq Dma0Done(void)
{
ClearPending(BIT_DMA0);
dmaDone=1;
}
static void __irq Dma1Done(void)
{
ClearPending(BIT_DMA1);
dmaDone=1;
}
static void __irq Dma2Done(void)
{
ClearPending(BIT_DMA2);
dmaDone=1;
}
static void __irq Dma3Done(void)
{
ClearPending(BIT_DMA3);
dmaDone=1;
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
DMA.rar (2个子文件)
DMA
dma.h 1KB
Dma.c 6KB
共 2 条
- 1
资源评论
- xijan2013-05-01在搞2440查询SPI0的DMA,一直有问题。下载来看都是三星DMA中断例程,对我没参考。
- snoweyemilkshake2014-04-01作为刚接触的测试demo觉得很受用,谢谢楼主
- air_washaway2013-11-03程序是使用DMA在内存内交换数据,参考价值不大
zhuomun
- 粉丝: 2
- 资源: 9
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功