2025-03-27 4:08 AM
This is a long and weird one.
My boss gave me a board with an STM32L433 that wouldn't communicate or do anything after power-on. After a lot of debugging and code tracing, I discovered that the function HAL_RTC_WaitForSynchro returns a HAL_TIMEOUT error code. The auto-generated code then jumps to the error handler with the infinite loop.
I have checked the RTC registers, and found an anomaly that may back this up. On a functioning board, the RTC_ISR register reads 0x00000037. On the bad board, the same register reads 0x00001017. Bit 5 (RSF) being 0 on the defective board indicates that shadow registers are not synchronized.
So, what can keep the RTC from synchronizing its shadow registers?
I found this line in the reference manual:
"The RSF bit must be cleared after wakeup and not before entering low-power mode."
Now, this board distributes 24 V to some other boards. In this particular case, the supply wires to one of these other boards were swapped, nearly shorting the supply voltage. I don't know if the fuse blew, as I wasn't there. But the SMPS may have gone into hiccup mode due to this.
My faint hypothesis is that the voltage has been high enough for the microcontroller to start up, but then right after the RSF bit was cleared, the supply voltage was cut off. I don't know if this is enough to wreak havoc in the RTC.
I can measure an RTC clock on the crystal, and the battery voltage is fine. It also seems that the rest of the MCU is okay, and it doesn't seem to be warm or use excessive power. After I added some code to exit the error handler in case of an RTC error, I can communicate just fine with the board. But, of course, the RTC isn't working.
I have considered powering off the board and removing the battery to see if that solves the problem. But I am reluctant to do so, as I would rather have my code solve it, If possible. The customers will not have access to the battery.
This is the HAL_RTC_WaitForSynchro function (unused lines removed; comments added):
HAL_StatusTypeDef HAL_RTC_WaitForSynchro(RTC_HandleTypeDef *hrtc)
{
uint32_t tickstart;
/* Clear RSF flag */
hrtc->Instance->ISR &= (uint32_t)RTC_RSF_MASK; // Clears bits 5 (RSF) and 7 (INIT)
tickstart = HAL_GetTick();
/* Wait the registers to be synchronised */
while ((hrtc->Instance->ISR & RTC_ISR_RSF) == 0U)
{
if ((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE) // RTC_TIMEOUT_VALUE = 1000
{
return HAL_TIMEOUT;
}
}
return HAL_OK;
}
Any help will be greatly appreciated.
Solved! Go to Solution.
2025-03-27 6:12 AM
Update:
Resetting the backup domain has solved the problem.
RCC->BDCR |= RCC_BDCR_BDRST;
Of course, this also resets date and time, but that can be set by the customers. The most important thing is that the device isn't bricked.
So now, if the error handler is invoked, and it is the RTC's fault, the backup domain will be reset automatically.
2025-03-27 6:12 AM
Update:
Resetting the backup domain has solved the problem.
RCC->BDCR |= RCC_BDCR_BDRST;
Of course, this also resets date and time, but that can be set by the customers. The most important thing is that the device isn't bricked.
So now, if the error handler is invoked, and it is the RTC's fault, the backup domain will be reset automatically.