cancel
Showing results for 
Search instead for 
Did you mean: 

DMAMUX: Chaining of request generators

JGiss.1
Associate II

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

3 REPLIES 3
Saket_Om
ST Employee

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);

 

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar

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. 

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).

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar