From 57dc4418deee2b123301d36eec3a020acee3814b Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Mon, 18 Jul 2016 13:17:17 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9712 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/STM32L4xx/hal_lld.c | 36 +++++++---- os/hal/ports/STM32/STM32L4xx/hal_lld.h | 87 +++++++++++++++++++------- 2 files changed, 90 insertions(+), 33 deletions(-) diff --git a/os/hal/ports/STM32/STM32L4xx/hal_lld.c b/os/hal/ports/STM32/STM32L4xx/hal_lld.c index c4916b8af..73d229c78 100644 --- a/os/hal/ports/STM32/STM32L4xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32L4xx/hal_lld.c @@ -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 e20c9fdfa..c7fbdeee0 100644 --- a/os/hal/ports/STM32/STM32L4xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32L4xx/hal_lld.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. */ /*===========================================================================*/