首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Zynq7000 PS DMA“完成”信号太快

Zynq7000 PS DMA“完成”信号太快
EN

Stack Overflow用户
提问于 2016-05-18 20:44:07
回答 1查看 645关注 0票数 1

TL;DR: Zynq7000 PS内置DMA太快返回一个“完成”信号。当它(我想)已经填充了它的内部"MFIFO“并且不再需要访问数据源时,它似乎就发出了信号。但是我的SW需要知道它什么时候完成了数据的传输。

PS是否有一个状态位来指示传输是否已经完成?Xilinx文档在其中几个DMA寄存器上不清楚(guides/ug585-Zynq-7000-TRM.pdf,第276页)

我使用DMA将数据块从DDR内存泵到PL IP,使用以下C代码:

代码语言:javascript
运行
复制
// Allocate memory in DDR, 1600 bytes PLZ.
char *mem_block = malloc(1600*sizeof(char));

// Fill memory with data (not shown)

// Configure the DMA command
memset(&dmaCmd, 0, sizeof(XDmaPS_Cmd));
dmaCmd.ChanCtrl.SrcBurstSize = 1;
dmaCmd.ChanCtrl.SrcBurstLen = 4;
dmaCmd.ChanCtrl.SrcInc = 1;
dmaCmd.ChanCtrl.DstBurstSize = 1;
dmaCmd.ChanCtrl.DstBurstLen = 4;
dmaCmd.ChanCtrl.DstInc = 0; // Do not increment, (Fixed DST Addr.)
dmaCmd.BD.SrcAddr = (u32)mem_block;
dmaCmd.BD.DstAddr = (u32)0x43c10000; // Destination address (in PL)
dmaCmd.BD.Length  = 1600; // Bytes

然后开始DMA传输..。

代码语言:javascript
运行
复制
status = XDmaPs_Start(&dmaInst, 0, &dmaCmd, 0);
if (status != XST_SUCCESS) {
    printf("ERROR, could not start DMA Txfer.");
    return XST_FAILURE;
}

等待它完成,然后再读回我的IP的结果。

代码语言:javascript
运行
复制
while (!(Xil_In32(XPAR_PS7_DMA_S_BASEADDR + XDMAPS_INTSTATUS_OFFSET) & 0x00000001)) {
   i++; // Waiting for DMA to finish...
}
result = Xil_In32(0x43c10004); // read result from my IP 
// Result is available as soon as DMA is finished--on the very next 100MHz fabric clock.

我遇到的问题是,在数据传输完成之前,这个结果往往会被很快地读取回来。显然,DMA有时说它是在DMA传输仍在进行的时候完成的(我可以从chipscope中看出,在写脉冲仍在发生时,我可以看到读取发生)。

如何将软件设置为等待DMA实际完成数据传输?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-05-18 20:44:07

文件伪装得很好,但我找到了我要找的东西。

当我输入这个问题时,我意识到这些DMA通道寄存器中一定有一些状态位。实际上,每个通道都有一个信道状态寄存器,其中较低的4位表示信道的状态。(我不得不翻查他们文件的附录B,即问题中链接的文件的第1201页)。这个4位状态是1001 (“完成”),当DMA已经触发一个完成,但仍在传输数据,并进入0000 (“停止”),当信道是实际完成。

Xilinx甚至在其自动生成的BSP中提供了一个方便的宏来获取每个通道的状态寄存器地址的偏移量:XDmaPs_CSn_OFFSET(n),在我的例子中,n是通道号-0。

我的修复只是改变我的时间循环,以检查通道的状态去“停止”,发出信号完成传输。

代码语言:javascript
运行
复制
while (!(Xil_In32(XPAR_PS_DMA_S_BASEADDR + XDmaPs_CSn_OFFSET(0) & 0x0000000F) != 0x00000000) {
    // Wait until done
    i++;
}
// Now DMA is truly, really done transferring data.
// get real result
result = Xil_In32(0x43C10004); // Read from my IP

希望这能节省一些时间和挫折感!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37309789

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档