diff --git a/os/hal/ports/STM32/STM32L4xx/hal_lld.c b/os/hal/ports/STM32/STM32L4xx/hal_lld.c index 7ad91c7fe..d6d25199b 100644 --- a/os/hal/ports/STM32/STM32L4xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32L4xx/hal_lld.c @@ -48,7 +48,7 @@ uint32_t SystemCoreClock = STM32_HCLK; /** * @brief Initializes the backup domain. - * @note WARNING! Changing clock source impossible without resetting + * @note WARNING! Changing RTC clock source impossible without resetting * of the whole BKP domain. */ static void hal_lld_backup_domain_init(void) { @@ -59,7 +59,7 @@ static void hal_lld_backup_domain_init(void) { RCC->BDCR = RCC_BDCR_BDRST; RCC->BDCR = 0; } - + #if STM32_LSE_ENABLED /* LSE activation.*/ #if defined(STM32_LSE_BYPASS) @@ -218,12 +218,11 @@ void stm32_clock_init(void) { ; /* Wait until LSE is stable. */ #endif -#if STM32_MSIPLL_ENABLED - /* MSI PLL activation.*/ - RCC->CR |= RCC_CR_MSIPLLEN; -#endif + /* Flash setup for selected MSI speed setting.*/ + FLASH->ACR = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | + STM32_MSI_FLASHBITS; - /* Changing MSIRANGE value. Meanwhile range is set by MSISRANGE which is 4MHz.*/ + /* Changing MSIRANGE to configured value.*/ RCC->CR |= STM32_MSIRANGE; /* Switching from MSISRANGE to MSIRANGE.*/ @@ -231,7 +230,16 @@ void stm32_clock_init(void) { while ((RCC->CR & RCC_CR_MSIRDY) == 0) ; - /* Updating MSISRANGE value. MSISRANGE can be set only when MSIRGSEL is high. + /* MSI is configured SYSCLK source so wait for it to be stable as well.*/ + while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) + ; + +#if STM32_MSIPLL_ENABLED + /* MSI PLL (to LSE) activation */ + RCC->CR |= RCC_CR_MSIPLLEN; +#endif + + /* Updating MSISRANGE value. MSISRANGE can be set only when MSIRGSEL is high. This range is used exiting the Standby mode until MSIRGSEL is set.*/ RCC->CSR |= STM32_MSISRANGE; @@ -251,7 +259,7 @@ void stm32_clock_init(void) { /* Waiting for PLL lock.*/ while ((RCC->CR & RCC_CR_PLLRDY) == 0) ; -#endif /* STM32_OVERDRIVE_REQUIRED */ +#endif #if STM32_ACTIVATE_PLLSAI1 /* PLLSAI1 activation.*/ @@ -299,16 +307,22 @@ void stm32_clock_init(void) { RCC->CCIPR = ccipr; } - /* Flash setup.*/ - FLASH->ACR = FLASH_ACR_DCEN | FLASH_ACR_ICEN | FLASH_ACR_PRFTEN | - STM32_FLASHBITS; + /* Set flash WS's for SYSCLK source */ + if (STM32_FLASHBITS > STM32_MSI_FLASHBITS) + FLASH->ACR = STM32_FLASHBITS; - /* Switching to the configured clock source if it is different from MSI.*/ + /* Switching to the configured SYSCLK source if it is different from MSI.*/ #if (STM32_SW != STM32_SW_MSI) RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ + /* Wait until SYSCLK is stable.*/ while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) ; #endif + + /* Reduce the flash WS's for SYSCLK source if they are less than MSI WSs */ + if (STM32_FLASHBITS < STM32_MSI_FLASHBITS) + FLASH->ACR = STM32_FLASHBITS; + #endif /* STM32_NO_INIT */ /* SYSCFG clock enabled here because it is a multi-functional unit shared diff --git a/os/hal/ports/STM32/STM32L4xx/hal_lld.h b/os/hal/ports/STM32/STM32L4xx/hal_lld.h index 963a0703d..84d35aa0f 100644 --- a/os/hal/ports/STM32/STM32L4xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32L4xx/hal_lld.h @@ -34,8 +34,8 @@ * @{ */ -#ifndef _HAL_LLD_H_ -#define _HAL_LLD_H_ +#ifndef HAL_LLD_H +#define HAL_LLD_H #include "stm32_registry.h" @@ -1137,6 +1137,9 @@ #elif STM32_PLLSRC == STM32_PLLSRC_HSI16 #define STM32_PLLCLKIN (STM32_HSI16CLK / STM32_PLLM_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_NOCLOCK +#define STM32_PLLCLKIN 0 + #else #error "invalid STM32_PLLSRC value specified" #endif @@ -1144,7 +1147,8 @@ /* * PLLs input frequency range check. */ -#if (STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX) +#if (STM32_PLLCLKIN != 0) && \ + ((STM32_PLLCLKIN < STM32_PLLIN_MIN) || (STM32_PLLCLKIN > STM32_PLLIN_MAX)) #error "STM32_PLLCLKIN outside acceptable range (STM32_PLLIN_MIN...STM32_PLLIN_MAX)" #endif @@ -1157,6 +1161,11 @@ (STM32_SAI1SEL == STM32_SAI1SEL_PLL) || \ (STM32_SAI2SEL == STM32_SAI2SEL_PLL) || \ defined(__DOXYGEN__) + +#if STM32_PLLCLKIN == 0 +#error "PLL activation required but no PLL clock selected" +#endif + /** * @brief PLL activation flag. */ @@ -1265,7 +1274,8 @@ /* * PLL VCO frequency range check. */ -#if (STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX) +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLLVCO < STM32_PLLVCO_MIN) || (STM32_PLLVCO > STM32_PLLVCO_MAX)) #error "STM32_PLLVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" #endif @@ -1287,21 +1297,24 @@ /* * PLL-P output frequency range check. */ -#if (STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX) +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLL_P_CLKOUT > STM32_PLLP_MAX)) #error "STM32_PLL_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" #endif /* * PLL-Q output frequency range check. */ -#if (STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX) +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLL_Q_CLKOUT > STM32_PLLQ_MAX)) #error "STM32_PLL_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" #endif /* * PLL-R output frequency range check. */ -#if (STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX) +#if STM32_ACTIVATE_PLL && \ + ((STM32_PLL_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLL_R_CLKOUT > STM32_PLLR_MAX)) #error "STM32_PLL_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" #endif @@ -1439,6 +1452,11 @@ (STM32_CLK48SEL == STM32_CLK48SEL_PLLSAI1) || \ (STM32_ADCSEL == STM32_ADCSEL_PLLSAI1) || \ defined(__DOXYGEN__) + +#if STM32_PLLCLKIN == 0 +#error "PLLSAI1 activation required but no PLL clock selected" +#endif + /** * @brief PLLSAI1 activation flag. */ @@ -1543,11 +1561,11 @@ #define STM32_PLLSAI1VCO (STM32_PLLCLKIN * STM32_PLLSAI1N_VALUE) /* - * PLLSAI2 VCO frequency range check. + * PLLSAI1 VCO frequency range check. */ -#if (STM32_PLLSAI1VCO < STM32_PLLVCO_MIN) || \ - (STM32_PLLSAI1VCO > STM32_PLLVCO_MAX) -#error "STM32_PLLSAIVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI1VCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLSAI1VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" #endif /** @@ -1568,24 +1586,24 @@ /* * PLLSAI1-P output frequency range check. */ -#if (STM32_PLLSAI1_P_CLKOUT < STM32_PLLP_MIN) || \ - (STM32_PLLSAI1_P_CLKOUT > STM32_PLLP_MAX) +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI1_P_CLKOUT > STM32_PLLP_MAX)) #error "STM32_PLLSAI1_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" #endif /* * PLLSAI1-Q output frequency range check. */ -#if (STM32_PLLSAI1_Q_CLKOUT < STM32_PLLQ_MIN) || \ - (STM32_PLLSAI1_Q_CLKOUT > STM32_PLLQ_MAX) +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_Q_CLKOUT < STM32_PLLQ_MIN) || (STM32_PLLSAI1_Q_CLKOUT > STM32_PLLQ_MAX)) #error "STM32_PLLSAI1_Q_CLKOUT outside acceptable range (STM32_PLLQ_MIN...STM32_PLLQ_MAX)" #endif /* * PLLSAI1-R output frequency range check. */ -#if (STM32_PLLSAI1_R_CLKOUT < STM32_PLLR_MIN) || \ - (STM32_PLLSAI1_R_CLKOUT > STM32_PLLR_MAX) +#if STM32_ACTIVATE_PLLSAI1 && \ + ((STM32_PLLSAI1_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI1_R_CLKOUT > STM32_PLLR_MAX)) #error "STM32_PLLSAI1_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" #endif @@ -1596,6 +1614,11 @@ (STM32_SAI2SEL == STM32_SAI2SEL_PLLSAI2) || \ (STM32_ADCSEL == STM32_ADCSEL_PLLSAI2) || \ defined(__DOXYGEN__) + +#if STM32_PLLCLKIN == 0 +#error "PLLSAI2 activation required but no PLL clock selected" +#endif + /** * @brief PLLSAI2 activation flag. */ @@ -1674,9 +1697,9 @@ /* * PLLSAI2 VCO frequency range check. */ -#if (STM32_PLLSAI2VCO < STM32_PLLVCO_MIN) || \ - (STM32_PLLSAI2VCO > STM32_PLLVCO_MAX) -#error "STM32_PLLSAIVCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2VCO < STM32_PLLVCO_MIN) || (STM32_PLLSAI2VCO > STM32_PLLVCO_MAX)) +#error "STM32_PLLSAI2VCO outside acceptable range (STM32_PLLVCO_MIN...STM32_PLLVCO_MAX)" #endif /** @@ -1692,16 +1715,16 @@ /* * PLLSAI2-P output frequency range check. */ -#if (STM32_PLLSAI2_P_CLKOUT < STM32_PLLP_MIN) || \ - (STM32_PLLSAI2_P_CLKOUT > STM32_PLLP_MAX) +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2_P_CLKOUT < STM32_PLLP_MIN) || (STM32_PLLSAI2_P_CLKOUT > STM32_PLLP_MAX)) #error "STM32_PLLSAI2_P_CLKOUT outside acceptable range (STM32_PLLP_MIN...STM32_PLLP_MAX)" #endif /* * PLLSAI2-R output frequency range check. */ -#if (STM32_PLLSAI2_R_CLKOUT < STM32_PLLR_MIN) || \ - (STM32_PLLSAI2_R_CLKOUT > STM32_PLLR_MAX) +#if STM32_ACTIVATE_PLLSAI2 && \ + ((STM32_PLLSAI2_R_CLKOUT < STM32_PLLR_MIN) || (STM32_PLLSAI2_R_CLKOUT > STM32_PLLR_MAX)) #error "STM32_PLLSAI2_R_CLKOUT outside acceptable range (STM32_PLLR_MIN...STM32_PLLR_MAX)" #endif @@ -2030,6 +2053,26 @@ #define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS #endif +/** + * @brief Flash settings for MSI. + */ +#if (STM32_MSICLK <= STM32_0WS_THRESHOLD) || defined(__DOXYGEN__) +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_0WS + +#elif STM32_MSICLK <= STM32_1WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_1WS + +#elif STM32_MSICLK <= STM32_2WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_2WS + +#elif STM32_MSICLK <= STM32_3WS_THRESHOLD +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_3WS + +#else +#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_4WS +#endif + + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -2056,6 +2099,6 @@ extern "C" { } #endif -#endif /* _HAL_LLD_H_ */ +#endif /* HAL_LLD_H */ /** @} */ diff --git a/readme.txt b/readme.txt index eef00cc4e..90c109caa 100644 --- a/readme.txt +++ b/readme.txt @@ -73,6 +73,8 @@ ***************************************************************************** *** 16.1.6 *** +- HAL: Fixed potential wait states problem in STM32L4 initialization code + (bug #768). - HAL: Fixed SDIO driver not compiling on STM32F446 devices (bug #767). - HAL: Fixed error in STM32L4xx ST headers (bug #766). - HAL: Fixed wrong check in win32 simulator serial driver (bug #765).