Hi Paul,
I made some tests to investigate the behavior of the DMA API. The API documentation (24.3.4.3) says that the external request base address “contains an address value used for the compare that determines a hit for the external acknowledge signal DACK. But it seems to do a lot more than that.
If you use edge triggered DREQ, then you better have your registers programmed so that the address compare match occurs. If you do not, the external DMA request is not cleared and the transfer continues through the subsequent buffer descriptors.
I’m posting the code of a DMA test. It triggers by asserting the initiator, goes through a series of buffer descriptors organized in ring, and stops at the first buffer descriptor ready for the next triggering. No intervention of the processor is expected to make the task ready:
1. Buffer descriptors bd[0] and bd[1] read a 32-bit value from a memory location and copy it to two 16-bit values. There is no address match so the transfer continues.
2. Buffer descriptor bd[2] makes buffer descriptor bd[3] ready by copying the MCD_BUF_READY to bd[3].flags. No address match.
3. Buffer descriptor bd[3] makes bd[0] to bd[2] ready by copying the “MCD_BUF_READY” to bd[0].flags through bd[2].flags. The destination address increments by 32 (set in “MCD_startDma()”) to match the “.flags” fields. Write to address “setReady” matches and the DMA task stops at the ready buffer descriptor bd[0]. The DMA task will respond to the next triggering by DREQ0.
The problem is the DMA is not working as expected. The “xferSize” parameter of “MCD_startDma()”is set to four bytes, necessary for reading the “lword” data and writing “MCD_BUF_READY” to the bd.flags. This way when copy to a 16-bit value, the DMA writes to wrong address in the memory as well. If I set “xferSize” to two bytes to match the 16-bit values, I need to set appropriate increments of the source and destination addresses, which affects the transfer of 32-bit variables.
I made also a test for another DMA, which will be necessary in our application: read two 16-bit variables and combine them as a full 32-bit values. It works even worse based on the necessity to be always ready for triggering.
Paul, do you if there ia a better way to implement a DMA transfer with the expected functionality?
Thank you,
Ivan