我参考了如下两个网页:
http://www.seeddsp.com/service/bbs/archiver/?tid-46552.html
http://www.deyisupport.com/question_answer/dsp_arm/davinci_digital_media_processors/f/39/t/22375.aspx
他们都宣称qdma搬运成功。
我的代码写法如下:
#define EDMA_BASE 0x49000000
#define EDMA_QCHMAP(n) (EDMA_BASE + 0x0200 + ((n) << 2))
#define EDMA_QDMAQNUM (EDMA_BASE + 0x0260)
#define EDMA_IPR (EDMA_BASE + 0x1068)
#define EDMA_ICR (EDMA_BASE + 0x1070)
#define EDMA_QSECR (EDMA_BASE + 0x1094)
/* Paramentry Registers */
#define EDMA_PARAM_BASE (EDMA_BASE + 0x4000)
#define EDMA_PARAM_ENTRY_SIZE 0x20
#define EDMA_PARAM_SIZE EDMA_PARAM_ENTRY_SIZE * 512
#define EDMA_PARAM(offset, n) (EDMA_PARAM_BASE + offset + (n << 5))
#define EDMA_PARAM_OPT(n) EDMA_PARAM(0x00, n)
#define EDMA_PARAM_SRC(n) EDMA_PARAM(0x04, n)
#define EDMA_PARAM_A_B_CNT(n) EDMA_PARAM(0x08, n)
#define EDMA_PARAM_DST(n) EDMA_PARAM(0x0C, n)
#define EDMA_PARAM_SRC_DST_BIDX(n) EDMA_PARAM(0x10, n)
#define EDMA_PARAM_LINK_BCNTRLD(n) EDMA_PARAM(0x14, n)
#define EDMA_PARAM_SRC_DST_CIDX(n) EDMA_PARAM(0x18, n)
#define EDMA_PARAM_CCNT(n) EDMA_PARAM(0x1C, n)
void Init_Edma(void)
{
*(volatile unsigned int *)EDMA_QDMAQNUM=0x00000210; //QDMA0排列在Q0,QDMA1排列在Q1,QDMA2排列在Q2
// *(volatile unsigned int *)EDMA_QUEPRI=0x00000111; //Q0-Q2优先权为1级
// *(volatile unsigned int *)EDMA_QEMCR=0x0F; //QDMA事件缺失寄存器QEMR清零
// *(volatile unsigned int *)EDMA_CCERRCLR=0x00010007; //CC错误寄存器CCERR清零
// *(volatile unsigned int *)EDMA_ICR=0xFFFFFFFF; //中断未决寄存器IPR清零
// *(volatile unsigned int *)EDMA_ICRH=0xFFFFFFFF; //中断未决寄存器IPRH清零
// *(volatile unsigned int *)EDMA_QEECR=0x0F; //QDMA事件使能寄存器QEER清零
// *(volatile unsigned int *)EDMA_QSECR=0x0F; //QDMA事件寄存器QER清零
*(volatile unsigned int *)EDMA_QCHMAP(0)=0x0000001C; //QDMA0通道映射到PARAMSET0,写入CCNT触发QDMA0传送
// *(volatile unsigned int *)EDMA_QCHMAP(1)=0x0000003C; //QDMA1通道映射到PARAMSET1,写入CCNT触发QDMA1传送
// *(volatile unsigned int *)EDMA_QCHMAP(2)=0x0000005C; //QDMA2通道映射到PARAMSET2,写入CCNT触发QDMA2传送
// *(volatile unsigned int *)EDMA_QEESR=0x07; //QDMA事件使能寄存器QEER 0、1、2通道事件使能
}
void edma3_qdma0(unsigned int src_adr, unsigned int dst_adr) //原始图像数据传送 1024X32一个数据包
{
/*
*((volatile unsigned int *) (PaRAMEntryAddr + OPT)) = ((0) | // SAM
(0 << 1) | // DAM
(0 << 2) | // SYNCDIM
(1 << 3) | // STATIC
(0 << 8) | // FWID
(0 << 11) | // TCCMODE
(chId << 12) | // TCC,chId=0
(1 << 20) | // TCINTEN
(0 << 21) | // ITCINTEN
(0 << 22) | // TCCHEN
(0 << 23) | // ITCCHEN
(0 << 24)); // PRIVID
==0x00100008
*/
*(volatile unsigned int *)EDMA_PARAM_OPT(0)=0x00100008;
*(volatile unsigned int *)EDMA_PARAM_SRC(0)=src_adr;
*(volatile unsigned int *)EDMA_PARAM_A_B_CNT(0)=0x12000; //传送8k字节
*(volatile unsigned int *)EDMA_PARAM_DST(0)=dst_adr;
*(volatile unsigned int *)EDMA_PARAM_SRC_DST_BIDX(0)=0x00000000;
*(volatile unsigned int *)EDMA_PARAM_LINK_BCNTRLD(0)=0x0000FFFF;
*(volatile unsigned int *)EDMA_PARAM_SRC_DST_CIDX(0)=0x00000000;
*(volatile unsigned int *)EDMA_PARAM_CCNT(0)=0x00000001;
}
void qdma0_Clear()
{
while(((*(volatile unsigned int *)EDMA_IPR) & 0x1)==0x00)
{
}
*(volatile unsigned int *)EDMA_ICR=0xFFFFFFFF;
*(volatile unsigned int *)EDMA_QSECR=0xFF; //QDMA事件存器QER清零
*(volatile unsigned int *)EDMA_QSECR=0x00;
}
char srcbuf[0x2000], dstbuf[0x2000];
int main(void) {
printf("xxxx");
Init_Edma();
edma3_qdma0((unsigned int )srcbuf, (unsigned int )dstbuf);
qdma0_Clear();
printf("yyyy");
return 0;
}
结果一运行,程序就停在while(((*(volatile unsigned int *)EDMA_IPR) & 0x1)==0x00),不能往下走。
请问应该怎么做?谢谢。
gaohao wang:
我要实现的是最简单的那种,一次搬运8k字节。
gaohao wang:
回复 gaohao wang:
会的人请帮忙回答一下,此事非常紧急。
gaohao wang:
回复 gaohao wang:
没人知道怎么做吗?
comeback:
回复 gaohao wang:
请问LZ的程序是在什么环境中跑的?是在CCS中吗?问题是怎么解决的?
haisu yuan:
楼主,我也是卡在IPR寄存器那里不动了,我分析是因为传输方式不对,导致IPR寄存器不能置一,但是现在还没解决,不找我想的对不对?
楼主能说说当初你是怎么解决的么?