cancel
Showing results for 
Search instead for 
Did you mean: 

FIFO Error from DMA to DAC caused by CubeMX - when can it be fixed?

design23
Associate II
Posted on March 14, 2017 at 05:01

Fellow Programmers, STMicro Staff, and CubeMX Coding Team:

After a whole day of debugging, I found an error in CubeMX code generation that results in FIFO errors from DMA when streaming to DAC.  How soon can CubeMX be corrected?  It is a nuisance to edit the generated C file to fix the bug every time after CubeMX is used to generate new code again.

Here are the details:

(1)  DMA -> DAC normal trigger from any timer, with Interrupts enabled for DAC errors.

(2)  CubeMX generates file 'STM32F7xx_HAL_DMA.C' file, with line 486 setting the FIFO Error Interrupt Enable (which is a mistake) even though FIFO Mode is supposed to be disabled.

(3)  CubeMX Generated code looks like this ...

    /* Enable Common interrupts*/

    hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;

    hdma->Instance->FCR |= DMA_IT_FE; // Mistake - Always enable FIFO Error contradicting FIFOMode setting

(4)  Generated code should be like this ...

    /* Enable Common interrupts*/

    hdma->Instance->CR  |= DMA_IT_TC | DMA_IT_TE | DMA_IT_DME;

    if (hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)  // If FIFOMode enabled

    {

        hdma->Instance->FCR |= DMA_IT_FE;  // Only enable FIFO Errors if FIFOMode enabled

    }

(5)  With this CubeMX code-generation error, I have to ask why is the hardware even generating an error since the FIFOMode has been set to disabled? Where does this FIFOMode change the hardware operation?

(6)  Does this mean that FIFO errors will always occur when FIFOMode is required to be enabled? 

I think there is a hardware problem here as well.  Please confirm what is going on.

Thanks,

Garry Anderson.

12 REPLIES 12
Posted on May 06, 2018 at 02:05

I would agree the answer doesn't really address the issue you posed.

A Validation Engineer needs to review the issue, and a CubeMX Engineer needs to understand why the code doesn't behave in a normative manner as generated, and limit the options or code generation to things that are going to work properly and consistently. We need significantly more rigour to what is tested and released. The CubeMX software should be aware of all the nuances described in the Reference Manual.

Does the DMA to DAC work properly?

Does it generate a FIFO Error Flag in normal operation, if so why?

Does ignoring the FIFO Error mask a deeper underlying issue?

Is there an issue with the address of the source data?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 18, 2018 at 14:23

Hi

Anderson.Garry

‌,

Let's study the following:

TIMER6 is used as triggering event to start a DAC conversion (DHRx[11:0] bits value).

DAC IP is master for the DMA transfer in order to prepare following data for DAC (feeding DHRx with data following DMA request by DAC IP due to the triggering event).

If TIMER6 is used as trigger for DAC and

if the number of data previously set for the associated DMA transfer from memory to the peripheral has been reached

thenthere is a DMA underrun condition for the next TIMER6 event.

It means that HAL_DAC_DMAUnderrunCallbackCh1() is called.

I share a log from the application running on NUCLEO-L476RG:

Data to send are 10 32bits words [0xBBBBB111, ..., 0xBBBBBBAAA] for DAC 12bits data with DMA set as 'Normal'

I didn t observe DAC_OUT signal but simply read DORx value of DAC register.

The data logged are value of DORx

Starting using DAC

HAL_DAC_Init(): done

HAL_DAC_Start_DMA(): done for 10 data

HAL_TIM_Base_Start_IT() going to be called

...

2 HAL_TIM_PeriodElapsedCallback()

...

00000516- DOR1: 0x00000111

...

3 HAL_TIM_PeriodElapsedCallback()

00000611- DOR1: 0x00000222

...

5 HAL_TIM_PeriodElapsedCallback()

6 HAL_DAC_ConvHalfCpltCallbackCh1()

00000869- DOR1: 0x00000444

...

00001251- DOR1: 0x00000888

11 HAL_TIM_PeriodElapsedCallback()

12 HAL_DAC_ConvCpltCallbackCh1()

00001354- DOR1: 0x00000999

...

14 HAL_TIM_PeriodElapsedCallback()

15

HAL_DAC_DMAUnderrunCallbackCh1()

00001555- DOR1: 0x00000aaa

16 HAL_TIM_PeriodElapsedCallback()

00001622- DOR1: 0x00000aaa

...

17 HAL_TIM_PeriodElapsedCallback()

00001719- DOR1: 0x00000aaa

Note that if DMA is configured as 'Circular' there is no more underrun due to DMA reloading the data.

This example is not your exact use-case, but shows that underrun condition is managed.

Hopping it gives more details.

Regards.

Cyril

Synthetech
Associate II

I am so glad I found this!

I am just now tinkering around with these uC's...

I was trying for a few days to get a simple DMA triggered DAC project going with either a F407VET6 or a H7 Nucleo board.

Using STM32CubeMX Version 4.27.0

used this fella's example

http://elastic-notes.blogspot.com/p/blog-page_1.html

I had no luck getting DMA to work with just Direct DMA transfer (FIFO disabled in the Cube..)

I could get the DACs to work with the basic HAL_DAC_SetValue usage, but everytime I tried to use DMA/TIM6 and HAL_DAC_Start_DMA with it it, would sit and do nothing. No output.

I am very new to debugging as well and perhaps it would have indicated to me long ago this issue.

Anyway, to make things short.. I ended up ENABLING the FIFO("Use Fifo"), "Full" Threshold, "Single" Burst options on the cubeMx DAC/DMA configuration window and BAM!

It suddenly started to create Sinewaves from the preconfig'd array.

I tried the OP's fix, but all it did was cause a severe Make error in the DMA.o file (I guess that's what it was indicating to me..)

So I figured, if you cant beat them, join them and enabled the FIFO instead of fighting it.

Now I can move on with some tinkering.

But I figured I would drop my findings in here in case some other poor soul out there is frustrated like me.