diff --git a/os/hal/ports/STM32/STM32F0xx/hal_lld.c b/os/hal/ports/STM32/STM32F0xx/hal_lld.c index 30115033c4..09ae204eac 100644 --- a/os/hal/ports/STM32/STM32F0xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F0xx/hal_lld.c @@ -68,6 +68,7 @@ static void hal_lld_backup_domain_init(void) { /* If enabled then the LSE is started.*/ #if STM32_LSE_ENABLED + int fomeLseCounter = 0; #if defined(STM32_LSE_BYPASS) /* LSE Bypass.*/ RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; @@ -75,8 +76,10 @@ static void hal_lld_backup_domain_init(void) { /* No LSE Bypass.*/ RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; #endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; #endif #if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK @@ -84,7 +87,11 @@ static void hal_lld_backup_domain_init(void) { initialization.*/ if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else RCC->BDCR |= STM32_RTCSEL; +#endif /* RTC clock enabled.*/ RCC->BDCR |= RCC_BDCR_RTCEN; diff --git a/os/hal/ports/STM32/STM32F0xx/hal_lld.h b/os/hal/ports/STM32/STM32F0xx/hal_lld.h index 696479d9ed..3217c44fb4 100644 --- a/os/hal/ports/STM32/STM32F0xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F0xx/hal_lld.h @@ -376,6 +376,25 @@ #define STM32_LSE_ENABLED FALSE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief Main clock source selection. * @note If the selected clock source is not the PLL then the PLL is not diff --git a/os/hal/ports/STM32/STM32F1xx/hal_lld.c b/os/hal/ports/STM32/STM32F1xx/hal_lld.c index 2e8ecc8d22..764df160c5 100644 --- a/os/hal/ports/STM32/STM32F1xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F1xx/hal_lld.c @@ -66,6 +66,7 @@ static void hal_lld_backup_domain_init(void) { /* If enabled then the LSE is started.*/ #if STM32_LSE_ENABLED + int fomeLseCounter = 0; #if defined(STM32_LSE_BYPASS) /* LSE Bypass.*/ RCC->BDCR |= RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; @@ -73,8 +74,10 @@ static void hal_lld_backup_domain_init(void) { /* No LSE Bypass.*/ RCC->BDCR |= RCC_BDCR_LSEON; #endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; #endif /* STM32_LSE_ENABLED */ #if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK @@ -82,7 +85,11 @@ static void hal_lld_backup_domain_init(void) { initialization.*/ if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else RCC->BDCR |= STM32_RTCSEL; +#endif /* Prescaler value loaded in registers.*/ rtc_lld_set_prescaler(); diff --git a/os/hal/ports/STM32/STM32F1xx/hal_lld.h b/os/hal/ports/STM32/STM32F1xx/hal_lld.h index 408e2f46e7..0e6e97988d 100644 --- a/os/hal/ports/STM32/STM32F1xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F1xx/hal_lld.h @@ -177,6 +177,25 @@ #if !defined(STM32_LSE_ENABLED) || defined(__DOXYGEN__) #define STM32_LSE_ENABLED FALSE #endif + +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif /** @} */ /*===========================================================================*/ diff --git a/os/hal/ports/STM32/STM32F37x/hal_lld.c b/os/hal/ports/STM32/STM32F37x/hal_lld.c index 725de2f6a5..b41bdc6334 100644 --- a/os/hal/ports/STM32/STM32F37x/hal_lld.c +++ b/os/hal/ports/STM32/STM32F37x/hal_lld.c @@ -65,6 +65,7 @@ static void hal_lld_backup_domain_init(void) { /* If enabled then the LSE is started.*/ #if STM32_LSE_ENABLED + int fomeLseCounter = 0; #if defined(STM32_LSE_BYPASS) /* LSE Bypass.*/ RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; @@ -72,8 +73,10 @@ static void hal_lld_backup_domain_init(void) { /* No LSE Bypass.*/ RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; #endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; #endif #if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK @@ -81,7 +84,11 @@ static void hal_lld_backup_domain_init(void) { initialization.*/ if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else RCC->BDCR |= STM32_RTCSEL; +#endif /* RTC clock enabled.*/ RCC->BDCR |= RCC_BDCR_RTCEN; diff --git a/os/hal/ports/STM32/STM32F37x/hal_lld.h b/os/hal/ports/STM32/STM32F37x/hal_lld.h index acb439a9f3..dba8e772c8 100644 --- a/os/hal/ports/STM32/STM32F37x/hal_lld.h +++ b/os/hal/ports/STM32/STM32F37x/hal_lld.h @@ -347,6 +347,25 @@ #define STM32_LSE_ENABLED FALSE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief Main clock source selection. * @note If the selected clock source is not the PLL then the PLL is not diff --git a/os/hal/ports/STM32/STM32F3xx/hal_lld.c b/os/hal/ports/STM32/STM32F3xx/hal_lld.c index cde7bd7773..34e4ffbffb 100644 --- a/os/hal/ports/STM32/STM32F3xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F3xx/hal_lld.c @@ -65,6 +65,7 @@ static void hal_lld_backup_domain_init(void) { /* If enabled then the LSE is started.*/ #if STM32_LSE_ENABLED + int fomeLseCounter = 0; #if defined(STM32_LSE_BYPASS) /* LSE Bypass.*/ RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; @@ -72,8 +73,10 @@ static void hal_lld_backup_domain_init(void) { /* No LSE Bypass.*/ RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; #endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; #endif #if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK @@ -81,7 +84,11 @@ static void hal_lld_backup_domain_init(void) { initialization.*/ if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else RCC->BDCR |= STM32_RTCSEL; +#endif /* RTC clock enabled.*/ RCC->BDCR |= RCC_BDCR_RTCEN; diff --git a/os/hal/ports/STM32/STM32F3xx/hal_lld.h b/os/hal/ports/STM32/STM32F3xx/hal_lld.h index a090087562..26473d6e11 100644 --- a/os/hal/ports/STM32/STM32F3xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F3xx/hal_lld.h @@ -387,6 +387,25 @@ #define STM32_LSE_ENABLED FALSE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief Main clock source selection. * @note If the selected clock source is not the PLL then the PLL is not diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld.c b/os/hal/ports/STM32/STM32F4xx/hal_lld.c index 63b30c24d2..5f746d19a0 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F4xx/hal_lld.c @@ -64,6 +64,7 @@ static void hal_lld_backup_domain_init(void) { } #if STM32_LSE_ENABLED + int fomeLseCounter = 0; #if defined(STM32_LSE_BYPASS) /* LSE Bypass.*/ RCC->BDCR |= RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; @@ -71,8 +72,10 @@ static void hal_lld_backup_domain_init(void) { /* No LSE Bypass.*/ RCC->BDCR |= RCC_BDCR_LSEON; #endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; #endif #if HAL_USE_RTC @@ -80,7 +83,11 @@ static void hal_lld_backup_domain_init(void) { initialization.*/ if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else RCC->BDCR |= STM32_RTCSEL; +#endif /* RTC clock enabled.*/ RCC->BDCR |= RCC_BDCR_RTCEN; diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld_type1.h b/os/hal/ports/STM32/STM32F4xx/hal_lld_type1.h index 615be83e01..7cce1d46f8 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_lld_type1.h +++ b/os/hal/ports/STM32/STM32F4xx/hal_lld_type1.h @@ -620,6 +620,25 @@ #define STM32_LSE_ENABLED FALSE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief USB/SDIO clock setting. */ diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld_type2.h b/os/hal/ports/STM32/STM32F4xx/hal_lld_type2.h index b90a427f5a..b481601914 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_lld_type2.h +++ b/os/hal/ports/STM32/STM32F4xx/hal_lld_type2.h @@ -402,6 +402,25 @@ #define STM32_LSE_ENABLED FALSE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief USB/SDIO clock setting. */ diff --git a/os/hal/ports/STM32/STM32F7xx/hal_lld.c b/os/hal/ports/STM32/STM32F7xx/hal_lld.c index 0e07bc9747..044fffb515 100644 --- a/os/hal/ports/STM32/STM32F7xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F7xx/hal_lld.c @@ -64,6 +64,7 @@ static void hal_lld_backup_domain_init(void) { } #if STM32_LSE_ENABLED + int fomeLseCounter = 0; #if defined(STM32_LSE_BYPASS) /* LSE Bypass.*/ RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; @@ -71,8 +72,10 @@ static void hal_lld_backup_domain_init(void) { /* No LSE Bypass.*/ RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; #endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; #endif #if HAL_USE_RTC @@ -80,7 +83,11 @@ static void hal_lld_backup_domain_init(void) { initialization.*/ if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else RCC->BDCR |= STM32_RTCSEL; +#endif /* RTC clock enabled.*/ RCC->BDCR |= RCC_BDCR_RTCEN; diff --git a/os/hal/ports/STM32/STM32F7xx/hal_lld.h b/os/hal/ports/STM32/STM32F7xx/hal_lld.h index c4a17c0526..24d96aae4c 100644 --- a/os/hal/ports/STM32/STM32F7xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F7xx/hal_lld.h @@ -541,6 +541,25 @@ #define STM32_LSE_ENABLED TRUE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief USB/SDIO clock setting. */ diff --git a/os/hal/ports/STM32/STM32H7xx/hal_lld.c b/os/hal/ports/STM32/STM32H7xx/hal_lld.c index 1ec2941639..0f2a88654d 100644 --- a/os/hal/ports/STM32/STM32H7xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32H7xx/hal_lld.c @@ -68,6 +68,7 @@ static inline void init_bkp_domain(void) { } #if STM32_LSE_ENABLED + int fomeLseCounter = 0; #if defined(STM32_LSE_BYPASS) /* LSE Bypass.*/ RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; @@ -75,8 +76,10 @@ static inline void init_bkp_domain(void) { /* No LSE Bypass.*/ RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; #endif - while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->BDCR & RCC_BDCR_LSERDY) == 0) + ; #endif #if HAL_USE_RTC @@ -84,7 +87,11 @@ static inline void init_bkp_domain(void) { initialization.*/ if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->BDCR |= (RCC->BDCR & RCC_BDCR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else RCC->BDCR |= STM32_RTCSEL; +#endif /* RTC clock enabled.*/ RCC->BDCR |= RCC_BDCR_RTCEN; diff --git a/os/hal/ports/STM32/STM32H7xx/hal_lld_type1.h b/os/hal/ports/STM32/STM32H7xx/hal_lld_type1.h index 0e929cc94c..88b59e84d0 100644 --- a/os/hal/ports/STM32/STM32H7xx/hal_lld_type1.h +++ b/os/hal/ports/STM32/STM32H7xx/hal_lld_type1.h @@ -662,6 +662,25 @@ #define STM32_LSE_ENABLED TRUE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief HSI divider. */ diff --git a/os/hal/ports/STM32/STM32H7xx/hal_lld_type2.h b/os/hal/ports/STM32/STM32H7xx/hal_lld_type2.h index 7102eea6bb..9d4d2631a9 100644 --- a/os/hal/ports/STM32/STM32H7xx/hal_lld_type2.h +++ b/os/hal/ports/STM32/STM32H7xx/hal_lld_type2.h @@ -624,6 +624,25 @@ #define STM32_LSE_ENABLED TRUE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief HSI divider. */ diff --git a/os/hal/ports/STM32/STM32H7xx/hal_lld_type3.h b/os/hal/ports/STM32/STM32H7xx/hal_lld_type3.h index b2e6e342bc..de5e58d85f 100644 --- a/os/hal/ports/STM32/STM32H7xx/hal_lld_type3.h +++ b/os/hal/ports/STM32/STM32H7xx/hal_lld_type3.h @@ -634,6 +634,25 @@ #define STM32_LSE_ENABLED TRUE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief HSI divider. */ diff --git a/os/hal/ports/STM32/STM32L0xx/hal_lld.c b/os/hal/ports/STM32/STM32L0xx/hal_lld.c index 0dd7d21f9e..94a3bf10d3 100644 --- a/os/hal/ports/STM32/STM32L0xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32L0xx/hal_lld.c @@ -63,9 +63,12 @@ static void hal_lld_backup_domain_init(void) { /* If enabled then the LSE is started.*/ #if STM32_LSE_ENABLED + int fomeLseCounter = 0; RCC->CSR |= RCC_CSR_LSEON; - while ((RCC->CSR & RCC_CSR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ + /* Waits until LSE is stable or times out. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->CSR & RCC_CSR_LSERDY) == 0) + ; #endif #if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK @@ -74,6 +77,11 @@ static void hal_lld_backup_domain_init(void) { if ((RCC->CSR & RCC_CSR_RTCEN) == 0) { /* Selects clock source.*/ RCC->CSR |= STM32_RTCSEL; +#if STM32_LSE_ENABLED + RCC->CSR |= (RCC->CSR & RCC_CSR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else + RCC->CSR |= STM32_RTCSEL; +#endif /* RTC clock enabled.*/ RCC->CSR |= RCC_CSR_RTCEN; diff --git a/os/hal/ports/STM32/STM32L0xx/hal_lld.h b/os/hal/ports/STM32/STM32L0xx/hal_lld.h index 12a192c6e2..dad91ea8cf 100644 --- a/os/hal/ports/STM32/STM32L0xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32L0xx/hal_lld.h @@ -370,6 +370,25 @@ #define STM32_LSE_ENABLED FALSE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief ADC clock setting. */ diff --git a/os/hal/ports/STM32/STM32L1xx/hal_lld.c b/os/hal/ports/STM32/STM32L1xx/hal_lld.c index 325a8f4da9..5cd284f7e7 100644 --- a/os/hal/ports/STM32/STM32L1xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32L1xx/hal_lld.c @@ -65,9 +65,12 @@ static void hal_lld_backup_domain_init(void) { /* If enabled then the LSE is started.*/ #if STM32_LSE_ENABLED + int fomeLseCounter = 0; + /* Waits until LSE is stable or times out. */ RCC->CSR |= RCC_CSR_LSEON; - while ((RCC->CSR & RCC_CSR_LSERDY) == 0) - ; /* Waits until LSE is stable. */ + while ((!FOME_STM32_LSE_WAIT_MAX || fomeLseCounter++ < FOME_STM32_LSE_WAIT_MAX) + && (RCC->CSR & RCC_CSR_LSERDY) == 0) + ; #endif #if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK @@ -75,7 +78,11 @@ static void hal_lld_backup_domain_init(void) { initialization.*/ if ((RCC->CSR & RCC_CSR_RTCEN) == 0) { /* Selects clock source.*/ +#if STM32_LSE_ENABLED + RCC->CSR |= (RCC->CSR & RCC_CSR_LSERDY) == 0 ? FOME_STM32_LSE_WAIT_MAX_RTCSEL : STM32_RTCSEL; +#else RCC->CSR |= STM32_RTCSEL; +#endif /* RTC clock enabled.*/ RCC->CSR |= RCC_CSR_RTCEN; diff --git a/os/hal/ports/STM32/STM32L1xx/hal_lld.h b/os/hal/ports/STM32/STM32L1xx/hal_lld.h index 9d6f566916..1757527d38 100644 --- a/os/hal/ports/STM32/STM32L1xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32L1xx/hal_lld.h @@ -266,6 +266,25 @@ #define STM32_LSE_ENABLED FALSE #endif +/** + * @brief Number of times to busy-loop waiting for LSE clock source. + * @note The default value of 0 disables this behavior. + * @note See also FOME_STM32_LSE_WAIT_MAX_RTCSEL. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX 0 +#endif + +/** + * @brief Fallback RTC clock source if stopped waiting for LSE clock source. + * @note If waiting for the LSE clock source times out due to + * FOME_STM32_LSE_WAIT_MAX, this allows the RTC clock source to + * fallback to another. + */ +#if !defined(FOME_STM32_LSE_WAIT_MAX_RTCSEL) || defined(__DOXYGEN__) +#define FOME_STM32_LSE_WAIT_MAX_RTCSEL STM32_RTCSEL_LSE +#endif + /** * @brief ADC clock setting. */