Hi everyone,
I'm working on a project with a Teensy 4.1 (i.MX RT1060) and I'm trying to set up a hardware chain:
PIT -> XBAR -> ADC_ETC -> ADC1 -> DMAMUX -> eDMA (Channel 16) -> Memory
The goal is to have the PIT periodically trigger the ADC_ETC, which in turn controls ADC1 to perform a single conversion. The result of this conversion should then be transferred to a memory buffer by eDMA Channel 16, ideally with one DMA interrupt per ADC_ETC event.
Current Status & What Works:
(1) PIT & XBAR: The PIT (Channel 0) is correctly configured for periodic triggers (e.g., 100 Hz), and XBAR (XBARA1_SEL51) correctly routes `PIT_TRIGGER0` (Input 56) to `ADC_ETC_TRIG00` (Output 103).
(2) ADC_ETC:
- ADC_ETC (Trigger 0) is successfully triggered by the XBAR.
- It reliably generates its DONE0 interrupts (`adc_etc_isr_count` increments).
- Key ADC_ETC settings include: `ADC_ETC_CTRL.DMA_MODE_SEL = 1` (pulsed DMA req), `TRIG0_CHAIN_1_0.B2B0 = 1` (links to ADC1 COCO), `TRIG0_CHAIN_1_0.IE0 = 1` (DONE0 IRQ enable), `ADC_ETC_DMA_CTRL.TRIG0_ENABLE = 1` (enable DMA request from TRIG0).
(3) ADC1:
- ADC1 is configured for hardware trigger mode (`ADC1_CFG = 0x2000` -> `ADTRG=1`).
- `ADC1_HC0` is set for the desired analog channel.
- `ADC1_GC = 0` (DMAEN=0 for ADC1 itself, as ADC_ETC is intended to trigger the eDMA transfer from ADC_ETC's result registers).
- Note: ADC calibration currently fails (`CALF=1`) with these ADC1_CFG settings, but this is a secondary issue for now.
(4) eDMA Channel 16 & DMAMUX:
- We are using eDMA Channel 16 (to avoid conflicts with Teensy core channels 0-15).
- DMAMUX Channel 16 is correctly configured to use Source 23 (ADC_ETC DMA Request).
- The TCD for Channel 16 is set up for a single 2-byte transfer from `ADC_ETC_TRIG0_RESULT_1_0` to a `DMAMEM` buffer, with `CITER=1`, `BITER=1`.
(5) DMA Interrupts & Data Transfer:
- Data *is* being transferred from `ADC_ETC_TRIG0_RESULT_1_0` to the memory buffer.
- A custom ISR for DMA Channel 16 (manually registered to IRQ 0, which is shared by DMA CH0 & CH16) is being called.
- The `DMA_INT` register correctly shows Bit 16 set when a transfer completes (if `TCD16_CSR.INTMAJOR=1`), and the ISR clears this with `DMA_CINT = 16;`.
- Crucially, a persistent "Destination Bus Error on Channel 2" (`DMA_ES=0x80001001`) that plagued earlier tests is now GONE since removing Scatter/Gather configurations from TCD16_CSR. `DMA_ES` is now `0x00000000`.
The Core Problem: DMA Channel 16 Misses Every Other Request (2:1 Ratio)
Despite the above working, DMA Channel 16 only services every other DMA request from the ADC_ETC.
- For example: If ADC_ETC generates 96 DONE0 interrupts (and thus 96 DMA requests), our DMA Channel 16 ISR (`dma_ch16_actual_isr_count`) only increments 48 times.
- This 2:1 ratio (ADC_ETC events : DMA transfers) is consistent even when the PIT trigger frequency is significantly reduced (e.g., from 100 Hz down to 10 Hz).
- The `DMA_TCD16_CSR` shows after the ISR re-activation a correct "waiting for hardware request" state (e.g., `0x0002`).
- The ISR for DMA CH16 currently includes `DMA_CINT = 16; DMA_CDNE = 16; DMA_SERQ = 16;`.
Key Debugging Steps & Findings Related to the 2:1 Issue:
- Correct DMAMUX sources have been confirmed.
- The correct IRQ vector (IRQ 0) for DMA CH16 is manually enabled in NVIC.
- The `DMAChannel.h` library's limitation for channels >= 16 regarding interrupts was bypassed by manual ISR handling.
- A previous `DMA_ES` error on Channel 2 was found to be caused by Scatter/Gather bits in `TCD16_CSR`; removing them resolved this error.
- Various ISR re-activation logics (with/without `DMA_CDNE`, with/without `DMA_SERQ` in ISR, or using `CSR[DREQ]=1`) have not resolved the 2:1 issue.
- Changing interrupt priorities (e.g., DMA ISR higher than ADC_ETC ISR) did not resolve the 2:1 issue.
(a) Has anyone encountered a similar "eDMA misses every other hardware request" scenario on i.MX RT106x, especially when a channel (`CITER=1`) is re-activated via ISR for continuous single transfers?
(b) Is there a known minimum latency or a specific eDMA/DMAMUX behavior that could explain why a channel, despite appearing "ready" (`CSR=0x0002`), would miss an immediately following hardware request?
(c) Could the way ADC_ETC issues its DMA request (`DMA_MODE_SEL=1`, pulsed) be a factor if the eDMA channel isn't perfectly ready?
(d) Are there any other TCD settings or `DMA_CR` configurations we should consider to make the eDMA channel more responsive to back-to-back hardware requests?
We seem to be very close, but this 2:1 request handling is a persistent blocker. Any insights or suggestions would be greatly appreciated! We can provide relevant code snippets if needed.
Thanks!
Chris
Solved! Go to Solution.
Hi @RhodesLover ,
Thank you so much for your interest in our products and for using our community.
Could you please explain the following description.
- The TCD for Channel 16 is set up for a single 2-byte transfer from `ADC_ETC_TRIG0_RESULT_1_0` to a `DMAMEM` buffer, with `CITER=1`, `BITER=1`.
Please check the param of the function EDMA_PrepareTransferConfig.
In SDK demo , srcWidth and destWidth are both 4.
Please try set param of the function EDMA_PrepareTransferConfig as the SDK demo did.
Wish it helps you.
If you still have question about it, please kindly let me know.
Wish you a nice day!
Best Regards
MayLiu
Hi @RhodesLover ,
Thank you so much for your interest in our products and for using our community.
Could you please explain the following description.
- The TCD for Channel 16 is set up for a single 2-byte transfer from `ADC_ETC_TRIG0_RESULT_1_0` to a `DMAMEM` buffer, with `CITER=1`, `BITER=1`.
Please check the param of the function EDMA_PrepareTransferConfig.
In SDK demo , srcWidth and destWidth are both 4.
Please try set param of the function EDMA_PrepareTransferConfig as the SDK demo did.
Wish it helps you.
If you still have question about it, please kindly let me know.
Wish you a nice day!
Best Regards
MayLiu