2022-07-06 09:38 PM
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:
It didn't work on this try (DAC voltage in yellow):
It did work on this try (see DAC voltage rise in yellow):
I 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):
Any ideas? This DAC output is critical to the board function in this case, so it's gotta work.
Thanks!
Solved! Go to Solution.
2022-07-08 08:23 PM
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).
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?
This fixes it in the MX_DAC_INIT function, unsure if there's any caveats in doing this.
Thanks for the help!
2022-07-07 12:49 AM
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
2022-07-07 09:09 PM
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:
After __HAL_DAC_ENABLE when it works:
This 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:
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:
This only results in CR = 1 when it's "working", otherwise CR = 0 after evaluating that
Any more ideas?
Thanks
2022-07-07 10:48 PM
Is DAC clock enabled in RCC?
JW
2022-07-08 08:23 PM
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).
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?
This fixes it in the MX_DAC_INIT function, unsure if there's any caveats in doing this.
Thanks for the help!
2022-07-09 12:38 AM
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 this 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
2022-07-09 01:41 PM
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.
2022-07-10 12:17 AM
> 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