LSE Startup on STM32H563ZI fails
Port, board and/or hardware
STM32 H563ZI custom board
MicroPython version
MicroPython v1.26.0-preview.527.g593ae04ee.dirty on 2025-08-08; Custom Board
Reproduction
I have a custom board based on the STM32H563ZI which has a V-BAT connection to keep the RTC running while main VCC is off.
A 32 kHz crystal is used as LSE.
That is defined in mpconfigboard.h as
#define MICROPY_HW_RTC_USE_LSE (1)
// #define MICROPY_HW_RTC_USE_BYPASS (0)
So no bypass is used here because we have a crystal.
The RTC is running while VCC is connected but stops when disconnected without forgetting the last date time value.
Problem: The LSE is not started and no voltage is present on the LSE pins.
Expected behaviour
LSE starts up, voltage can be measured on LSE crystal pins
Observed behaviour
The LSE is not running
Additional Information
Probable Reason: Apparently the LSE crystal needs a drive strength higher than the LOW default.
The drive strength can be set for this controller - and probably for many others, by setting e.g.:
LL_PWR_EnableBkUpAccess();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH);
I have created the following entries in mpconfigboard.h:
// Configure the code running at startup
#define MICROPY_BOARD_STARTUP myboard_startup
void myboard_startup(void);
#define MICROPY_BOARD_EARLY_INIT myboard_early_init
void myboard_early_init(void);
With the corresponding board_init.c file.
// Apparently the LSE needs extra strength to be driven from battery
#include "py/mphal.h"
void LSE_Setup() {
LL_PWR_EnableBkUpAccess();
LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH);
LL_RCC_LSE_Enable();
/* Wait till LSE is ready */
while(LL_RCC_LSE_IsReady() != 1)
{
}
}
void myboard_early_init() {
HAL_InitTick(0);
uint32_t ticks_ms = HAL_GetTick();
// Wait for LSE
while ((HAL_GetTick() - ticks_ms < 5000) && (LL_RCC_LSE_IsReady() != 1));
// Check if LSE is running
if (LL_RCC_LSE_IsReady() != 1) {
// Force LSE init here resetting time and date
LSE_Setup();
}
}
void myboard_startup() {
LL_RCC_LSE_Enable();
}
This works as expected. The voltage on the LSE can be measured, the RTC keeps running from battery.
I suggest an extension of the available macros like:
#define MICROPY_HW_LSE_DRIVE_CAPABILITY (LL_RCC_LSEDRIVE_HIGH)
Which is only applied during setup if defined.
This would retain compatibility with all board setups but allow one to get a more demanding crystal running.
I am not sure I fully understand the setup logic in MicroPython here but since I do not measure any voltage on the 32 kHz crystal pins in the unmodified code there may even be another issue with the LSE setup.
Interestingly enough it works on the NUCLEO_H563ZI board with the provided MicroPython configuration but of corse this cannot be tested running from battery since the board does not allow to connect a backup battery easily on V-BAT.
Any hints or suggestions?
Best, Roland
Code of Conduct
Yes, I agree
stm32/rtc: Allow overriding startup timeouts from mpconfigboard.
This PR Simply exposes the startup timeouts via #ifdef to allow overriding for particular boards.
On our custom stm32f765 based board, the external crystal for RTC was not being used with the default 1000ms timeout (unit was falling back to LSI, took a while to figure out why our clock was drifting).
After increasing the timeout to 2000 the crystal works, with a reported startup time between 1200 and 1600ms over a few hard cold boots (RTC backup battery off/on).