cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 DACs enabling inconsistently upon powerup

Auhv
Associate II

Using STM32F765VG6TR, every time I power on the MCU, the two DACs are supposed to be set to constant output voltages of 2.4V and 0.8V. This happens inconsistently - sometimes it works, about 50/50 success rate. A few notes:

  • If it isn't working, an MCU reset does not fix it.
  • There seems to be a correlation between how long I wait after power-down and power up and the DACs enabling properly. Waiting not too long and not too short seems to be the sweet spot (about 1.5s)
  • This would lead me to believe it's a power sequencing issue with VDDA/VDD, but can't seem to correlate a specific start-up waveform with bad DAC behavior
  • Have reproduced the issue on two separate processors with different PCBAs
  • Either both DAC channels work, or both do not work. Haven't seen one work and not the other.

It didn't work on this try (DAC voltage in yellow):

0693W00000QKcDbQAL.pngIt did work on this try (see DAC voltage rise in yellow):

0693W00000QKcDWQA1.pngI have tried waiting 100ms in the code before trying to run the DAC, no luck - which kind of makes sense since MCU reset doesn't fix it. Stepping over the DAC enable line with the debugger doesn't affect the voltage no matter what voltage value is passed.

It almost seems like sometimes the clock for that peripheral doesn't enable sometimes - just my guess at this point. Here's the clock configuration in CubeMX (v5.3.0):

0693W00000QKcANQA1.png 

Any ideas? This DAC output is critical to the board function in this case, so it's gotta work.

Thanks!

1 ACCEPTED SOLUTION

Accepted Solutions
Auhv
Associate II

No, it wasn't, so the question is why:

DAC wouldn't enable because DACEN bit in RCC APB1 Enable Register wasn't set

RCC DACEN bit isn't set because DAC is in the ERROR state at that section

DAC goes from the RESET state to the ERROR state upon running the content of the content between the breakpoints shown in the HAL_InitTick function for TIM6 (TIM6 is used as the timebase source).

0693W00000QKmhCQAT.png 

I can see the contents of the hdac register change as we execute the code between the two breakpoints. Interesting to note that there is no changes to hdac in memory if the code is stepped over, only happens when I run the code from one break point to the other.

The changes are DAC_ERROR being set in hdac->State, and the HAL_DAC_ERROR_DMAUNDERRUNCH1 errorcode being set in hdac->ErrorCode. Weird since I'm not even using DMA with the DAC.

I noticed something about this is present in the STM32F765 errata - maybe it's related to this known issue with the DAC DMA underrun flag?

0693W00000QKmhbQAD.pngThis fixes it in the MX_DAC_INIT function, unsure if there's any caveats in doing this.

0693W00000QKmjmQAD.pngThanks for the help!

View solution in original post

7 REPLIES 7

Read out and check/compare DAC and relevant GPIO content between working and non-working states.

If you use Cube/HAL, make sure all fields of init structs are filled in.

JW​

Auhv
Associate II

Good call. It seems like __HAL_DAC_ENABLE is not setting the enable bit in the DAC control register?

After __HAL_DAC_ENABLE when it doesn’t work:

0693W00000QKioEQAT.pngAfter __HAL_DAC_ENABLE when it works:

0693W00000QKioJQAT.pngThis seems pretty strange - what would prevent memory from being changed in one register set line?

__HAL_DAC_ENABLE is only setting the DAC_CR_EN1 bit:

0693W00000QKioYQAT.png 

I think the most convincing way to show the problem is trying to directly edit the register by evaluating the assignment expression with the debugger:

0693W00000QKir3QAD.pngThis only results in CR = 1 when it's "working", otherwise CR = 0 after evaluating that

Any more ideas?

Thanks

Is DAC clock enabled in RCC?

JW​

Auhv
Associate II

No, it wasn't, so the question is why:

DAC wouldn't enable because DACEN bit in RCC APB1 Enable Register wasn't set

RCC DACEN bit isn't set because DAC is in the ERROR state at that section

DAC goes from the RESET state to the ERROR state upon running the content of the content between the breakpoints shown in the HAL_InitTick function for TIM6 (TIM6 is used as the timebase source).

0693W00000QKmhCQAT.png 

I can see the contents of the hdac register change as we execute the code between the two breakpoints. Interesting to note that there is no changes to hdac in memory if the code is stepped over, only happens when I run the code from one break point to the other.

The changes are DAC_ERROR being set in hdac->State, and the HAL_DAC_ERROR_DMAUNDERRUNCH1 errorcode being set in hdac->ErrorCode. Weird since I'm not even using DMA with the DAC.

I noticed something about this is present in the STM32F765 errata - maybe it's related to this known issue with the DAC DMA underrun flag?

0693W00000QKmhbQAD.pngThis fixes it in the MX_DAC_INIT function, unsure if there's any caveats in doing this.

0693W00000QKmjmQAD.pngThanks for the help!

This is something intimately Cube/HAL rrelated. I doubt the erratum is involved.

> Interesting to note that there is no changes to hdac in memory if the code is stepped over,

> only happens when I run the code from one break point to the other.

Then th​is happens in interrupt.

> DAC_ERROR being set in hdac->State, and the HAL_DAC_ERROR_DMAUNDERRUNCH1

> errorcode being set in hdac->ErrorCode

Place a data breakpoint (a.k.a. watchpoint​) on some of these variables to see, where are they changed.

JW

Auhv
Associate II

hdac is indeed modified during an interrupt as you suggested - TIM6_DAC_IRQHandler , which seems to handle DAC DMA underrun errors. I suppose the question is why the DAC sets the DMA underrun flag in the first place.

0693W00000QKnTQQA1.png0693W00000QKnTVQA1.png 

> I suppose the question is why the DAC sets the DMA underrun flag in the first place.

You've said that DAC at this point does not have enabled clock in RCC, and in that case reading it may return unexpected values. In other words, you are not supposed to read DAC until you enable its clock.

What probably happens here is, that you enable the TIM6 interrupt and it fires for whatever reason (probably this reason), but as DAC and TIM6 share interrupt, Cube/HAL calls also the DAC handler portion which reads the yet-not-enabled DAC registers and makes false conclusions.

I am not going to investigate Cube/HAL's mess. I don't recommend using Cube/HAL for anything beyond what can be simply clicked in CubeMX.

JW