Stuck with DMA between a FIFO in a UDB and memory

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
AlFr_4739666
Level 1
Level 1

What I'm trying to do is to transfer 80 bytes from a buffer to a FIFO. It kind of works, but not right. I'm using bursts of 4 bytes and a setting to have a DREQ on every burst. So I set the size of 80 and burst size of 4.

CyDmaChSetConfiguration(dmaCh,4, 1, 0,0,0); // avf 4 per burst, req every time

CyDmaTdSetConfiguration(dmaTd, X_BYTES , dmaTd, DMA__TD_TERMOUT_EN | TD_INC_SRC_ADR);

So it loops to the same Td.

My custom UDB gets triggered by a hardware signal every 30 usec and starts sending requests when the FIFO is empty. The DMA sends the data and I get an interrupt on NRQ after (what looks on the scope as) 20 bursts, that is 80 bytes as it should.  I change the pointer to the start of the new buffer to wait for the next trigger event. But I can see that the number of bytes sent is not always 80, so the data is being sent from wrong addresses.  It's possible that my UDB has a bug. If so I'll find it, Verilog is not a problem. The question is it possible that the misalignment happens elsewhere  and more importantly how can I make sure a new set of data will start from the right place?  In another thread I have seen an advice to disable, release and enable again the DMA channel. But will that not hit performance? Is there a way to just reset the address? Also am I right to chain the td to itself or should it be terminated and a new one started after one full set of 80 bytes?

Thanks.

0 Likes
1 Solution

There are several kinds of 16-bit register window concatenating two 8-bit registers as follows.

GS004834.png

The register address is declared in the cyfitter.h file like following.

GS004836.png

You can use the register declaration in your API functions.

Regards,

Noriaki

View solution in original post

0 Likes
2 Replies
AlFr_4739666
Level 1
Level 1

OK, have to reply myself. Setting DMA_DISABLE_TD and then doing

  CyDmaChSetInitialTd(dmaCh, dmaTd);

  CyDmaChEnable(dmaCh, 1);

before the next block helped. Next question: PSoC5 doesn't seem to have the "DMA channel" primitive to edit. How can I set up the DMA to transfer 16 bits at a time? Both to F0 and F1 in a single cycle?

0 Likes

There are several kinds of 16-bit register window concatenating two 8-bit registers as follows.

GS004834.png

The register address is declared in the cyfitter.h file like following.

GS004836.png

You can use the register declaration in your API functions.

Regards,

Noriaki

0 Likes