git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13472 27425a3e-05d8-49a3-a47f-9c15f0e5edd8

This commit is contained in:
Giovanni Di Sirio 2020-03-24 14:10:13 +00:00
parent 0cfd870354
commit b8fdc98a3c
8 changed files with 229 additions and 181 deletions

View File

@ -0,0 +1,174 @@
/*
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/**
* @file RCCv1/stm32_msi.inc
* @brief Shared MSI clock handler.
*
* @addtogroup STM32_MSI_HANDLER
* @{
*/
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/**
* @name RCC_CR register bits definitions
* @{
*/
#define STM32_MSIRANGE_MASK (15 << 4) /**< MSIRANGE field mask. */
#define STM32_MSIRANGE_100K (0 << 4) /**< 100kHz nominal. */
#define STM32_MSIRANGE_200K (1 << 4) /**< 200kHz nominal. */
#define STM32_MSIRANGE_400K (2 << 4) /**< 400kHz nominal. */
#define STM32_MSIRANGE_800K (3 << 4) /**< 800kHz nominal. */
#define STM32_MSIRANGE_1M (4 << 4) /**< 1MHz nominal. */
#define STM32_MSIRANGE_2M (5 << 4) /**< 2MHz nominal. */
#define STM32_MSIRANGE_4M (6 << 4) /**< 4MHz nominal. */
#define STM32_MSIRANGE_8M (7 << 4) /**< 8MHz nominal. */
#define STM32_MSIRANGE_16M (8 << 4) /**< 16MHz nominal. */
#define STM32_MSIRANGE_24M (9 << 4) /**< 24MHz nominal. */
#define STM32_MSIRANGE_32M (10 << 4) /**< 32MHz nominal. */
#define STM32_MSIRANGE_48M (11 << 4) /**< 48MHz nominal. */
/** @} */
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/* Registry checks for robustness.*/
#if !defined(STM32_HAS_MSI)
#error "STM32_PLLSRC not defined in stm32_registry.h"
#endif
/* Checks on configurations.*/
#if !defined(STM32_MSIPLL_ENABLED)
#error "STM32_MSIPLL_ENABLED not defined in mcuconf.h"
#endif
#if !defined(STM32_MSIRANGE)
#error "STM32_MSIRANGE not defined in mcuconf.h"
#endif
#if !defined(STM32_MSISRANGE)
#error "STM32_MSISRANGE not defined in mcuconf.h"
#endif
#if !defined(STM32_LSE_ENABLED)
#error "STM32_LSE_ENABLED not defined in mcuconf.h"
#endif
#if STM32_MSIPLL_ENABLED && !STM32_LSE_ENABLED
#error "STM32_MSIPLL_ENABLED requires LSE"
#endif
/**
* @brief MSI frequency.
*/
#if STM32_MSIRANGE == STM32_MSIRANGE_100K
#define STM32_MSICLK 100000
#elif STM32_MSIRANGE == STM32_MSIRANGE_200K
#define STM32_MSICLK 200000
#elif STM32_MSIRANGE == STM32_MSIRANGE_400K
#define STM32_MSICLK 400000
#elif STM32_MSIRANGE == STM32_MSIRANGE_800K
#define STM32_MSICLK 800000
#elif STM32_MSIRANGE == STM32_MSIRANGE_1M
#define STM32_MSICLK 1000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_2M
#define STM32_MSICLK 2000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_4M
#define STM32_MSICLK 4000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_8M
#define STM32_MSICLK 8000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_16M
#define STM32_MSICLK 16000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_24M
#define STM32_MSICLK 24000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_32M
#define STM32_MSICLK 32000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_48M
#define STM32_MSICLK 48000000
#else
#error "invalid STM32_MSIRANGE value specified"
#endif
/**
* @brief MSIS frequency.
*/
#if STM32_MSISRANGE == STM32_MSISRANGE_1M
#define STM32_MSISCLK 1000000
#elif STM32_MSISRANGE == STM32_MSISRANGE_2M
#define STM32_MSISCLK 2000000
#elif STM32_MSISRANGE == STM32_MSISRANGE_4M
#define STM32_MSISCLK 4000000
#elif STM32_MSISRANGE == STM32_MSISRANGE_8M
#define STM32_MSISCLK 8000000
#else
#error "invalid STM32_MSISRANGE value specified"
#endif
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static inline void msi_init(void) {
uint32_t cr;
/* Initial clocks setup and wait for MSI stabilization, the MSI clock is
always enabled because it is the fall back clock when PLL the fails.
Trim fields are not altered from reset values.*/
/* MSIRANGE can be set only when MSI is OFF or READY, it is ready after
reset.*/
#if STM32_MSIPLL_ENABLED
cr = STM32_MSIRANGE | RCC_CR_MSIPLLEN | RCC_CR_MSION;
#else
cr = STM32_MSIRANGE | RCC_CR_MSION;
#endif
RCC->CR = cr;
while ((RCC->CR & RCC_CR_MSIRDY) == 0)
; /* Wait until MSI is stable. */
/* Clocking from MSI, in case MSI was not the default source.*/
RCC->CFGR = 0;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI)
; /* Wait until MSI is selected. */
/* Updating MSISRANGE value. MSISRANGE can be set only when MSIRGSEL is high.
This range is used exiting the Standby mode until MSIRGSEL is set.*/
cr |= RCC_CR_MSIRGSEL;
RCC->CR = cr;
RCC->CSR |= STM32_MSISRANGE;
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
/** @} */

View File

@ -318,7 +318,7 @@ static inline void pll_init(void) {
STM32_PLLREN | STM32_PLLQ |
STM32_PLLQEN | STM32_PLLP |
STM32_PLLPEN | STM32_PLLN |
STM32_PLLM;
STM32_PLLM | STM32_PLLSRC;
RCC->CR |= RCC_CR_PLLON;
/* Waiting for PLL lock.*/

View File

@ -306,7 +306,7 @@ static inline void pllsai1_init(void) {
STM32_PLLSAI1REN | STM32_PLLSAI1Q |
STM32_PLLSAI1QEN | STM32_PLLSAI1P |
STM32_PLLSAI1PEN | STM32_PLLSAI1N |
STM32_PLLSAI1M;
STM32_PLLSAI1M | STM32_PLLSAI1SRC;
RCC->CR |= RCC_CR_PLLSAI1ON;
/* Waiting for PLL lock.*/

View File

@ -306,7 +306,7 @@ static inline void pllsai2_init(void) {
STM32_PLLSAI2REN | STM32_PLLSAI2Q |
STM32_PLLSAI2QEN | STM32_PLLSAI2P |
STM32_PLLSAI2PEN | STM32_PLLSAI2N |
STM32_PLLSAI2M;
STM32_PLLSAI2M | STM32_PLLSAI2SRC;
RCC->CR |= RCC_CR_PLLSAI2ON;
/* Waiting for PLL lock.*/

View File

@ -267,7 +267,7 @@ void stm32_clock_init(void) {
RCC->CSR |= STM32_MSISRANGE;
#if STM32_ACTIVATE_PLL || STM32_ACTIVATE_PLLSAI1 || STM32_ACTIVATE_PLLSAI2
/* PLLM and PLLSRC are common to all PLLs.*/
/* PLLSRC is common to all PLLs.*/
RCC->PLLCFGR = STM32_PLLPDIV | STM32_PLLR |
STM32_PLLREN | STM32_PLLQ |
STM32_PLLQEN | STM32_PLLP |

View File

@ -60,27 +60,6 @@ static void hal_lld_backup_domain_init(void) {
RCC->BDCR = 0;
}
#if STM32_LSE_ENABLED
/* LSE activation.*/
#if defined(STM32_LSE_BYPASS)
/* LSE Bypass.*/
RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP;
#else
/* No LSE Bypass.*/
RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON;
#endif
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
; /* Wait until LSE is stable. */
#endif
#if STM32_MSIPLL_ENABLED
/* MSI PLL activation depends on LSE. Reactivating and checking for
MSI stability.*/
RCC->CR |= RCC_CR_MSIPLLEN;
while ((RCC->CR & RCC_CR_MSIRDY) == 0)
; /* Wait until MSI is stable. */
#endif
#if HAL_USE_RTC
/* If the backup domain hasn't been initialized yet then proceed with
initialization.*/
@ -97,6 +76,13 @@ static void hal_lld_backup_domain_init(void) {
RCC->BDCR |= STM32_LSCOSEL;
}
static void flash_ws_init(uint32_t bits) {
FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | bits;
while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) {
}
}
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
@ -164,8 +150,8 @@ void stm32_clock_init(void) {
RCC->APB1ENR1 = RCC_APB1ENR1_PWREN;
#endif
/* Core voltage setup.*/
PWR->CR1 = STM32_VOS;
/* Core voltage setup, backup domain made accessible.*/
PWR->CR1 = STM32_VOS | PWR_CR1_DBP;
while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */
; /* stable. */
@ -174,19 +160,25 @@ void stm32_clock_init(void) {
PWR->CR3 = STM32_PWR_CR3;
PWR->CR4 = STM32_PWR_CR4;
/* Initial clocks setup and wait for MSI stabilization, the MSI clock is
always enabled because it is the fall back clock when PLL the fails.
Trim fields are not altered from reset values.*/
/* Setting the wait states required by MSI clock.*/
flash_ws_init(STM32_MSI_FLASHBITS);
/* MSIRANGE can be set only when MSI is OFF or READY.*/
RCC->CR = RCC_CR_MSION;
while ((RCC->CR & RCC_CR_MSIRDY) == 0)
; /* Wait until MSI is stable. */
/* LSE must be initialized before MSI because MSIPLL uses LSE.*/
#if STM32_LSE_ENABLED
/* LSE activation.*/
#if defined(STM32_LSE_BYPASS)
/* LSE Bypass.*/
RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP;
#else
/* No LSE Bypass.*/
RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON;
#endif
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
; /* Wait until LSE is stable. */
#endif
/* Clocking from MSI, in case MSI was not the default source.*/
RCC->CFGR = 0;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI)
; /* Wait until MSI is selected. */
/* Clocks setup.*/
msi_init();
#if STM32_HSI16_ENABLED
/* HSI activation.*/
@ -220,84 +212,10 @@ void stm32_clock_init(void) {
; /* Wait until LSI is stable. */
#endif
/* Backup domain access enabled and left open.*/
PWR->CR1 |= PWR_CR1_DBP;
#if STM32_LSE_ENABLED
/* LSE activation.*/
#if defined(STM32_LSE_BYPASS)
/* LSE Bypass.*/
RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP;
#else
/* No LSE Bypass.*/
RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON;
#endif
while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0)
; /* Wait until LSE is stable. */
#endif
/* Flash setup for selected MSI speed setting.*/
FLASH->ACR = STM32_MSI_FLASHBITS;
/* Changing MSIRANGE to configured value.*/
RCC->CR |= STM32_MSIRANGE;
/* Switching from MSISRANGE to MSIRANGE.*/
RCC->CR |= RCC_CR_MSIRGSEL;
while ((RCC->CR & RCC_CR_MSIRDY) == 0)
;
/* 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;
#if STM32_ACTIVATE_PLL || STM32_ACTIVATE_PLLSAI1 || STM32_ACTIVATE_PLLSAI2
/* PLLM and PLLSRC are common to all PLLs.*/
RCC->PLLCFGR = STM32_PLLPDIV | STM32_PLLR |
STM32_PLLREN | STM32_PLLQ |
STM32_PLLQEN | STM32_PLLP |
STM32_PLLPEN | STM32_PLLN |
STM32_PLLM | STM32_PLLSRC;
#endif
/* PLL activation.*/
/* PLLs activation.*/
pll_init();
#if STM32_ACTIVATE_PLLSAI1
/* PLLSAI1 activation.*/
RCC->PLLSAI1CFGR = STM32_PLLSAI1PDIV | STM32_PLLSAI1R |
STM32_PLLSAI1REN | STM32_PLLSAI1Q |
STM32_PLLSAI1QEN | STM32_PLLSAI1P |
STM32_PLLSAI1PEN | STM32_PLLSAI1N |
STM32_PLLSAI1M;
RCC->CR |= RCC_CR_PLLSAI1ON;
/* Waiting for PLL lock.*/
while ((RCC->CR & RCC_CR_PLLSAI1RDY) == 0)
;
#endif
#if STM32_ACTIVATE_PLLSAI2
/* PLLSAI2 activation.*/
RCC->PLLSAI2CFGR = STM32_PLLSAI2PDIV | STM32_PLLSAI2R |
STM32_PLLSAI2REN | STM32_PLLSAI2P |
STM32_PLLSAI2PEN | STM32_PLLSAI2N |
STM32_PLLSAI2M;
RCC->CR |= RCC_CR_PLLSAI2ON;
/* Waiting for PLL lock.*/
while ((RCC->CR & RCC_CR_PLLSAI2RDY) == 0)
;
#endif
pllsai1_init();
pllsai2_init();
/* Other clock-related settings (dividers, MCO etc).*/
RCC->CFGR = STM32_MCOPRE | STM32_MCOSEL | STM32_STOPWUCK |
@ -329,10 +247,7 @@ void stm32_clock_init(void) {
/* Set flash WS's for SYSCLK source */
if (STM32_FLASHBITS > STM32_MSI_FLASHBITS) {
FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS;
while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) !=
(STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) {
}
flash_ws_init(STM32_FLASHBITS);
}
/* Switching to the configured SYSCLK source if it is different from MSI.*/
@ -344,11 +259,8 @@ void stm32_clock_init(void) {
#endif
/* Reduce the flash WS's for SYSCLK source if they are less than MSI WSs */
if (STM32_FLASHBITS < STM32_MSI_FLASHBITS) {
FLASH->ACR = (FLASH->ACR & ~FLASH_ACR_LATENCY_Msk) | STM32_FLASHBITS;
while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) !=
(STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) {
}
if (STM32_FLASHBITS <= STM32_MSI_FLASHBITS) {
flash_ws_init(STM32_FLASHBITS);
}
#endif /* STM32_NO_INIT */

View File

@ -938,51 +938,8 @@
#error "invalid STM32_VOS value specified"
#endif
/**
* @brief MSI frequency.
*/
#if STM32_MSIRANGE == STM32_MSIRANGE_100K
#define STM32_MSICLK 100000
#elif STM32_MSIRANGE == STM32_MSIRANGE_200K
#define STM32_MSICLK 200000
#elif STM32_MSIRANGE == STM32_MSIRANGE_400K
#define STM32_MSICLK 400000
#elif STM32_MSIRANGE == STM32_MSIRANGE_800K
#define STM32_MSICLK 800000
#elif STM32_MSIRANGE == STM32_MSIRANGE_1M
#define STM32_MSICLK 1000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_2M
#define STM32_MSICLK 2000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_4M
#define STM32_MSICLK 4000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_8M
#define STM32_MSICLK 8000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_16M
#define STM32_MSICLK 16000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_24M
#define STM32_MSICLK 24000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_32M
#define STM32_MSICLK 32000000
#elif STM32_MSIRANGE == STM32_MSIRANGE_48M
#define STM32_MSICLK 48000000
#else
#error "invalid STM32_MSIRANGE value specified"
#endif
/**
* @brief MSIS frequency.
*/
#if STM32_MSISRANGE == STM32_MSISRANGE_1M
#define STM32_MSISCLK 1000000
#elif STM32_MSISRANGE == STM32_MSISRANGE_2M
#define STM32_MSISCLK 2000000
#elif STM32_MSISRANGE == STM32_MSISRANGE_4M
#define STM32_MSISCLK 4000000
#elif STM32_MSISRANGE == STM32_MSISRANGE_8M
#define STM32_MSISCLK 8000000
#else
#error "invalid STM32_MSISRANGE value specified"
#endif
/* MSI handling.*/
#include "stm32_msi.inc"
/*
* HSI16 related checks.

View File

@ -78,6 +78,11 @@
#if defined(STM32L552xx) || defined(__DOXYGEN__)
/* RCC attributes.*/
#define STM32_HAS_HSI16 TRUE
#define STM32_HAS_HSI48 TRUE
#define STM32_HAS_MSI TRUE
#define STM32_HAS_LSI TRUE
#define STM32_HAS_PLL TRUE
#define STM32_PLL_HAS_P TRUE
#define STM32_PLL_HAS_Q TRUE