cancel
Showing results for 
Search instead for 
Did you mean: 

DMA disable issue

My program collects data using DMA in circular buffer. I have following procedure to "start" collecting data.

 

// "reenable" measurment (enable results readout)
void restart_measurment(void){
run=1;
// DMA channel reset
CLEAR_BIT(TIM1->DIER, TIM_DIER_CC3DE | TIM_DIER_CC2DE); // disable DMA request in TIM1
LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_6); // disable both streams
LL_DMA_DisableStream(DMA2, LL_DMA_STREAM_2);
while(LL_DMA_IsEnabledStream(DMA2, LL_DMA_STREAM_6)); // wait until disabled
while(LL_DMA_IsEnabledStream(DMA2, LL_DMA_STREAM_2));
clear_snapshots(); // clear data buffers
LL_DMA_ClearFlag_HT6(DMA2); // clear flags
LL_DMA_ClearFlag_TC6(DMA2);
LL_DMA_ClearFlag_HT2(DMA2);
LL_DMA_ClearFlag_TC2(DMA2);
LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_6); // enable DMA streams
LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_2);
reset_flipflops(); // manage external HW
TIM1->DIER |= TIM_DIER_CC3DE | TIM_DIER_CC2DE; // enable DMA request from TIM
}

 

 

 Rarely program freezes in while loop on line "8". There is no any part of code which manipulates with DMA2 Enable bit (only read and clear HT and TC flags and they are not in IRQ). I have not inspected DMA registers yet, but does anyone have any idea what could be the reason to stuck in waiting for DMA disable ?

1 ACCEPTED SOLUTION

Accepted Solutions

> I am disabling Timers DMA request enable bits in IRQ routine to stop data collect.

> CLEAR_BIT(TIM1->DIER, TIM_DIER_CC3DE | TIM_DIER_CC2DE);

Don't.

The dual-port DMA can get stuck, if you pull the *request* amidst an ongoing transfer. Yes I know it's not documented.

What you should do, is, disable DMA, wait until it signals its disabled (btw. that sets transfer-complete flag, too), and only after then disable the request source (here TIMx_DIER.CCxDE).

---

I've written about this in thread named DMA (STM32F4xx) aborted transfers on Jul 24, 2017; thread became mangled during jive->salesforce transition and then got lost from the public space in the salesforce->khoros transition. ST probably does have this thread but apparently in a private space. @STOne-32 , can this thread please be resurfaced?

Here's another thread with the same problem, although the OP unfortunately never came back to confirm.

JW

 

View solution in original post

9 REPLIES 9
STOne-32
ST Employee

Dear @Michal Dudka ,

it might be the propagation delay of the instructions just before and the effective settings of the bits on the AHB bus . Look  to this errata  : https://www.st.com/resource/en/errata_sheet/es0206-stm32f427437-and-stm32f429439-device-errata-stmicroelectronics.pdf

IMG_9256.jpeg

You can insert a dummy instruction before just to explore this hypothesis.  Another one is to check if you have an on-going DMA transaction waiting an acknowledgment from previous part of the code so to check and dump DMA registers as you suggested.

Hope it helps ,

STOne-32


@STOne-32 wrote:

 Another one is to check if you have an on-going DMA transaction waiting an acknowledgment from previous part of the code...


Thanks for tip. I am disabling Timers DMA request enable bits in IRQ routine to stop data collect.

CLEAR_BIT(TIM1->DIER, TIM_DIER_CC3DE | TIM_DIER_CC2DE); 

That code can be executed any time. I am not sure how TIM and DMA behaves in case that TIM_DIER_CCxDE bit is cleared during DMA transaction.

Datasheet claims:
1. peripheral sends a request signal to the DMA controller.
2. As soon as the DMA controller accesses the peripheral, an Acknowledge signal is sent to the peripheral by the DMA controller.
3. The peripheral releases its request as soon as it gets the Acknowledge signal from the DMA controller.
4. Once the request has been deasserted by the peripheral, the DMA controller releases the Acknowledge signal.

What happen if DMA Enable bit is cleared between 1. and 4. ? Can that stuck DMA ?

 

> I am disabling Timers DMA request enable bits in IRQ routine to stop data collect.

> CLEAR_BIT(TIM1->DIER, TIM_DIER_CC3DE | TIM_DIER_CC2DE);

Don't.

The dual-port DMA can get stuck, if you pull the *request* amidst an ongoing transfer. Yes I know it's not documented.

What you should do, is, disable DMA, wait until it signals its disabled (btw. that sets transfer-complete flag, too), and only after then disable the request source (here TIMx_DIER.CCxDE).

---

I've written about this in thread named DMA (STM32F4xx) aborted transfers on Jul 24, 2017; thread became mangled during jive->salesforce transition and then got lost from the public space in the salesforce->khoros transition. ST probably does have this thread but apparently in a private space. @STOne-32 , can this thread please be resurfaced?

Here's another thread with the same problem, although the OP unfortunately never came back to confirm.

JW

 


@waclawek.jan wrote:

What you should do, is, disable DMA, wait until it signals its disabled (btw. that sets transfer-complete flag, too), and only after then disable the request source (here TIMx_DIER.CCxDE).


Thanks, that sounds promising. I will do and wait few days if problem dissapears.

MD.

@Lina_DABASINSKAITE please check with @STOne-32 if the thread mentioned by @waclawek.jan can be found and making visible again?

In order to give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hi @waclawek.jan  @Michal Dudka 

 

>> The dual-port DMA can get stuck, if you pull the *request* amidst an ongoing transfer. Yes I know it's not documented.

What you should do, is, disable DMA, wait until it signals its disabled (btw. that sets transfer-complete flag, too), and only after then disable the request source (here TIMx_DIER.CCxDE).

 

Here is a Application Note , Section 4  and further chapters 

Using the STM32F2, STM32F4 and STM32F7 Series DMA controller  

STOne32_0-1724167914219.png

 

Let me know if it helps on the right sequence to so before disabling DMA .

Ciao

STOne-32.

Hi @STOne-32 ,

1. I believe this is a core information and as such should be documented in RM, rather than as "Tips and tricks" in an AN;

2. the text says:

"To switch off a peripheral [...]"

and

"Only then can the peripheral be safely disabled".

So, it talks about "peripheral disable". For example, in context of e.g. DMA request originating in a TIM, this can be interpreted as "TIMx_CR1.CEN should be cleared only after DMA Stream has signalled it's disabled".

So that's badly formulated (it's there exactly in this form since this AN's rev.1).

The subsequent sequence ("DMA request enable bit in the peripheral control register... etc. ) suggests, that the *request enable bit* (which is clearly something different than *peripheral disable*) shall be cleared, but does not state, when. So, it can be quite well interpreted as "Clear request enable bit first, to avoid pending requests during the DMA disable process, then switch off the DMA stream, and only after that you can disable the peripheral."

---

Also, my post I've mentioned, talked about attempt of avoiding transfers during a certain period by disabling/reenabling the requests from the peripheral (SPI in that case); that DMA was circular and never had an intention to *disable* the DMA itself.

---

The problem is *not* related to DMA *disable* (even if the particular case @Michal Dudka  presented here is, but that's just one particular way how the problem demonstrates itself), but most probably to the fact that the request is not properly latched in the DMA during the whole transfer, and pulling it before the transfer end results in surprising behaviour. This could be confirmed by looking at the DMA's sources.

---

In other words, no, this is not an adequate wording, and not an adequate place for it.

I'd suggest, in RM, in DMA transactions subchapter of DMA chapter, adding this: "While DMA Stream is enabled, disabling the request enable bit in the peripheral is prohibited and leads to undefined behaviour".

Short, concise, complete.

JW

PS. If you are willing to improve the documentation:

- the sequence described in DMA transactions is incorrect, too

- the DMA transfer suspension subchapter is, to put it mildly, misleading. Streams can't be *suspended*, they can only be *disabled and re-enabled*, and the consequences are *very different* from what would be in case of suspended streams. That's why I experimented with disabling the *requests*.


@STOne-32 wrote:

Let me know if it helps on the right sequence to so before disabling DMA .


It helped.

Hello @Peter BENSCH , thanks pinging me. Both shared links are part of a group hub which currently not public. I am looking for a solution to provide the access to this type of content. Will keep you posted once there is an update. 


In order to give better visibility on the answered topics, please click on 'Accept as Solution' on the reply which solved your issue or answered your question.