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
OSError 16 from time.sleep_ms()
Port, board and/or hardware
stm32
MicroPython version
MicroPython v1.25.0
Reproduction
This is on a custom board. Code during the boot process calls time.sleep_ms(1100)
- Hard reset the board
- boot/main code starts running fine
- Break out to a repl
- (at this point, I can run time.sleep_ms() without problem)
- soft reset the board
- during the boot process, call to sleep_ms() fails
I cannot replicate the issue on v1.24.0 (i.e. something has changed going to v1.25.0)
Expected behaviour
No response
Observed behaviour
Call to time.sleep_ms() raises OSError 16 in the above conditions
Additional Information
This is running on a custom board with an STM32H743 MCU.
Code of Conduct
Yes, I agree