2025-01-27 10:26 AM - edited 2025-01-27 10:33 AM
Hello,
on the NUCLEO-H723ZG I would like to initiate a DMA transfer (Memory to GPIO ODR) on every 300 ADC EOC events. I have a DMA channel set up for the ADC (DMA1 CH0) and a DMA channel for writing the ODR of a GPIO. Since a single request generator can only count up to 32 events before issuing a request, I would like to chain two request generators where request generator 0 requests are fed into request generator 1.
If I only use a single request generator everything works out fine (up to 32 requests of course). This is the code I used to setup the DMAMUX:
LL_DMAMUX_SetRequestSignalID(DMAMUX1, LL_DMAMUX_REQ_GEN_0, LL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT); // DMA1CH0 EVT as input to REQ_GEN0
LL_DMAMUX_SetRequestGenPolarity(DMAMUX1, LL_DMAMUX_REQ_GEN_0, LL_DMAMUX_REQ_GEN_POL_RISING); // request generation on rising edge of DMA1CH0 EVT
LL_DMAMUX_SetGenRequestNb(DMAMUX1, LL_DMAMUX_REQ_GEN_0, 1); // 1 DMA Request by REQ_GEN0
LL_DMAMUX_SetSyncRequestNb(DMAMUX1, LL_DMAMUX_CHANNEL_0, 30); // 30 Events before request is generated
LL_DMAMUX_EnableEventGeneration(DMAMUX1, LL_DMAMUX_CHANNEL_0); // enable event generation for CH0 (ADC1->EOC)
LL_DMAMUX_SetRequestID(DMAMUX1, LL_DMAMUX_CHANNEL_2, LL_DMAMUX1_REQ_GENERATOR0); // set REQ_GEN0 as DMAMUX1CH2 (DMA1CH2) request
LL_DMAMUX_EnableRequestGen(DMAMUX1, LL_DMAMUX_REQ_GEN_0); // enable generation by REQ_GEN0
Now, if I try to put an additional request generator in between, request generation on DMA 1CH2 stops working. This is the code I am using to set it up:
LL_DMAMUX_SetRequestSignalID(DMAMUX1, LL_DMAMUX_REQ_GEN_0, LL_DMAMUX1_REQ_GEN_DMAMUX1_CH0_EVT); // CH0 EVT as input to REQ_GEN0
LL_DMAMUX_SetRequestGenPolarity(DMAMUX1, LL_DMAMUX_REQ_GEN_0, LL_DMAMUX_REQ_GEN_POL_RISING); // request generation on rising edge of CH0 EVT
LL_DMAMUX_SetGenRequestNb(DMAMUX1, LL_DMAMUX_REQ_GEN_0, 1); // 1 DMA Request by REQ_GEN0
LL_DMAMUX_SetSyncRequestNb(DMAMUX1, LL_DMAMUX_CHANNEL_0, 30); // 30 Events before request is generated
LL_DMAMUX_EnableEventGeneration(DMAMUX1, LL_DMAMUX_CHANNEL_0); // enable event generation for CH0 (ADC1->EOC)
LL_DMAMUX_SetRequestID(DMAMUX1, LL_DMAMUX_CHANNEL_1, LL_DMAMUX1_REQ_GENERATOR0); // set REQ_GEN0 as DMAMUX1CH1 (DMA1CH1) request
LL_DMAMUX_SetRequestSignalID(DMAMUX1, LL_DMAMUX_REQ_GEN_1, LL_DMAMUX1_REQ_GEN_DMAMUX1_CH1_EVT); // DMA1CH1 EVT as input to REQ_GEN1
LL_DMAMUX_SetRequestGenPolarity(DMAMUX1, LL_DMAMUX_REQ_GEN_1, LL_DMAMUX_REQ_GEN_POL_RISING); // request generation on rising edge of CH1 EVT
LL_DMAMUX_SetGenRequestNb(DMAMUX1, LL_DMAMUX_REQ_GEN_1, 1); // 1 DMA Request by REQ_GEN1
LL_DMAMUX_SetSyncRequestNb(DMAMUX1, LL_DMAMUX_CHANNEL_1, 10); // 10 Events before request is generated
LL_DMAMUX_EnableEventGeneration(DMAMUX1, LL_DMAMUX_CHANNEL_1); // enable event generation for CH1 (dummy channel)
LL_DMAMUX_SetRequestID(DMAMUX1, LL_DMAMUX_CHANNEL_2, LL_DMAMUX1_REQ_GENERATOR1); // set REQ_GEN1 as DMAMUX1CH2 (DMA1CH2) request
LL_DMAMUX_EnableRequestGen(DMAMUX1, LL_DMAMUX_REQ_GEN_0); // enable generation by REQ_GEN0
LL_DMAMUX_EnableRequestGen(DMAMUX1, LL_DMAMUX_REQ_GEN_1); // enable generation by REQ_GEN1
I get a trigger overrun event flag for request generator channel 0 in the DMAMUX_RGSR, which indicates a new trigger event to the generator occurs before the request counter (GNBREQ) underrun happens. I don't understand what this means to be honest, aren't the triggers events meant to be counted by the request counter?! My trigger for request generator 0 (DMA1 CH2 event, triggered by ADC1->EOC) occurs every 20µs, so plenty of time for GNBREQ to count down.
Maybe my understanding of the DMAMUX isn't correct, thats why I've put a comment on every line of the code stating what the line does in my understanding. I am thankful for any help or pointers. I have also tried to enable DMA Channel1 which I am using as my "dummy" channel to be triggered by REQ_GEN0 and as event source for REQ_GEN1, without success. I have activated all 3 DMA channels using NVIC_EnableIRQ(DMA1_StreamX_IRQn);
Best,
Julius
2025-01-29 06:49 AM
Hello @JGiss.1
You are setting two request generators on the same channel.
Please try to implement a similar configuration as shown below:
LL_DMAMUX_SetRequestID(DMAMUX1, LL_DMAMUX_CHANNEL_1, LL_DMAMUX1_REQ_GENERATOR0);
LL_DMAMUX_SetRequestID(DMAMUX1, LL_DMAMUX_CHANNEL_2, LL_DMAMUX1_REQ_GENERATOR1);
2025-01-30 01:41 AM
No, I don't think I am setting two generators on the same channel. I am setting generator 0 to trigger channel 1 in line 7 and generator 1 to trigger channel 2 in line 15.
I have found a solution or workaround for my issue. The problem is, that the request from generator 0 on channel 1 is not acknowledged, since I don't have an actual transfer set up on channel 1. If I set up an actual transfer on channel 1, the trigger is acknowledged and I don't get the trigger overrun flag.
Ideally, I don't want channel 1 to actually move any data, so the question could be reformulated to ask if there is an option to acknowledge a dma request on a channel without actually invoking the dma controller to move data.
However, I understand that I am not using the dmamux in the typical way which would always involve moving data around.
2025-01-30 02:30 AM
Hello @JGiss.1
I reported your question internally.
Internal ticket number: 201851 (This is an internal tracking number and is not accessible or usable by customers).