Other Parts Discussed in Thread: HALCOGEN
I have observed some very strange behavior when resetting (via writing to it) a DMA control packet immediately after it finishes. I have observed this with multiple peripherals so I do not think it is related to which one. Specifically, it seems to put the last element of the transfer where the first one should go and doesn't write anything in the last element's memory location.
A short delay in between observing the DMA peripheral indicating the transfer is done and writing to the control packet makes the symptom go away. However, I do not see any mention of this requirement in the TRM, so I do not know how long a delay guarantees correct behavior (and how it depends on clock speeds etc). Could you clarify the timing requirements around this use case?
The rest of this post summarizes various things I have tried with no effect if you're wondering. I've tried everything I can think of, but feel free to suggest something else.
I have observed this with both the DCAN and MIBSPI peripherals.
The following forms of waiting for the DMA channel to finish all give the same result:
- Waiting for the bit in FTCFLAG to set
- Waiting for the bit in BTCFLAG to set (I have minimized my test case to a single frame per block)
- Waiting for the bit in FIFOASTAT to clear (My test is minimal enough it always ends up FIFO A)
- Waiting for the bit in PEND to clear
The following forms of "short wait" all seem to make the problem go away when inserted between seeing the DMA channel is done and writing to the control packet:
- 4 peripheral reads (but not 3)
- 3 peripheral reads + dsb (but not 2)
- 4 peripheral reads + a branch (but not 3)
- 12 reads from normal memory (but not 11)
The following forms of writing to the channel descriptor all have the same result:
- Writing the same value back to IDADDR
- Writing a different value to IDADDR
- Writing the same value to ITCOUNT
- Writing a different value to ITCOUNT
Setting or clearing AIM doesn't make a difference.
I can reliably reproduce this either with the DMA buffer in writeback-mapped memory or with the caches disabled entirely. Note that to reproduce it with the caches disabled, I had to put all of the relevant code into RAM. I assume this is because executing from FLASH without the cache is too slow to hit the problem. I suspect the above timings for how long of a "short wait" is long enough are also different in this situation. I disabled both the i-cache and d-cache because it was easiest; I see no way the i-cache is relevant besides changing how long the code takes to run.
I eagerly await some clarification about what the DMA hardware is doing.