2016-05-18 2 views
1

TL; DR: встроенный DMA Zynq7000 PS возвращает сигнал «Готово» слишком рано. Кажется, это сигнал, как только он (я полагаю) заполнил его внутренний «MFIFO» и больше не нуждается в доступе к источнику данных. Но мой SW должен знать, когда он действительно закончил передачу данных.Zynq7000 PS DMA «Done» Сигналы слишком скоро

Имеет ли PS DMA бит состояния, указывающий, завершена ли передача? Документации Xilinx неясно на некоторых из этих DMA регистрирует (http://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf, стр 276)

Я использую DMA накачать порцию данных из памяти DDR над к IP PL, используя следующий код C:

// 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 ...

status = XDmaPs_Start(&dmaInst, 0, &dmaCmd, 0); 
if (status != XST_SUCCESS) { 
    printf("ERROR, could not start DMA Txfer."); 
    return XST_FAILURE; 
} 

И ждать его завершения, прежде чем читать назад результат моего IP.

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 все еще продолжается (я могу сказать, потому что из чипсцока я вижу, что чтение происходит, пока пакеты записи все еще происходят).

Как я могу установить мое программное обеспечение для ожидания до тех пор, пока DMA не будет на самом деле выполнен с передачей данных?

ответ

2

Документация была хорошо замаскирована, но я нашел именно то, что искал.

Как я набрал этот вопрос, я понял, что в этих регистрах канала DMA должны быть бит состояния. Оказывается, на каждом канале есть регистр состояния канала, нижние 4-биты которого представляют собой состояние канал. (Мне пришлось вставить в Приложение B их документацию, чтобы найти его, стр. 1201 документа, связанного в вопросе). Это 4-битное состояние 1001 («Завершение»), когда DMA инициирует DONE, но все еще передает данные, и переходит на 0000 («Остановлен»), когда канал действительно выполнен.

Xilinx даже предоставляет удобный макрос в их автогенерированном BSP, чтобы получить смещение для адреса регистра состояния каждого канала: XDmaPs_CSn_OFFSET(n) где n - номер канала - 0 в моем случае.

My Fix - это просто изменить мой цикл while, чтобы проверить состояние канала, чтобы перейти к «Stopped», сигнализируя о завершенной передаче.

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 

Надеется, что это может спасти кому-то какое-то время & разочарования! : D

+1

спасибо. Столкнувшись с той же проблемой, и ваш ответ делает все ясно –

Смежные вопросы