On i.MXRT1176 we are using FLEXCAN with EDMA. (SDK 26.03)
We have a callback defined for DMA transfer complete.
This is our flow:
1. Call `FLEXCAN_TransferReceiveFifoEDMA()` to start the transfer.
2. On DMA transfer completion, user-defined callback is called.
3. Data is copied from DMA buffers, and `FLEXCAN_TransferReceiveFifoEDMA()` is called to continue receiving messages.
4. Repeat Steps 2-4
We noticed that when we transmit messages from another node in a burst with just the bare minimum Inter-Frame Space, we see an increase in number of ACK errors - the iMX is unable to ACK the messages.
Going through the flow, it appears that every time there is a DMA transfer complete callback, DMA is disabled on FLEXCAN. It is re-enabled again when `FLEXCAN_TransferReceiveFifoEDMA()` is called. This is done by calling `FLEXCAN_EnableRxFifoDMA()`. The enabling/disabling DMA updates the DMA bit in FLEXCAN's MCR register, and it can only be done in Freeze mode. As we are receiving messages in a burst, it is possible that a transmission is actively in progress when FLEXCAN is put it freeze mode. And it is unable to ACK the incoming message.
Hi @r-uv ,
Thank you for the detailed analysis. Your observation is consistent with the SDK implementation.
FLEXCAN_TransferReceiveFifoEDMA() is a finite-length transactional API. After each DMA completion, the driver disables the Rx FIFO DMA request, and the next call enables it again. Because changing MCR[DMA] requires Freeze mode, the next frame in minimum-IFS traffic may arrive before FlexCAN returns to Normal mode, resulting in a missed ACK.
This also explains why removing the repeated DMA enable/disable operation eliminates the ACK errors but still causes dropped frames: the Freeze-related ACK gap is removed, but the eDMA transfer is not continuously rearmed.
For continuous burst traffic, we recommend keeping the Rx FIFO DMA request enabled and using hardware-chained ping-pong/scatter-gather TCDs so that the next buffer is activated automatically. This requires a continuous DMA receive path rather than repeatedly restarting FLEXCAN_TransferReceiveFifoEDMA().
Best regards,
Gavin
Thanks for the response. Are there any plans of adding this support in the SDK? A continuous DMA based implementation instead of just the current transactional API implementation?