From 06e40c102d54add506b1966b87a4e96e6c3bd007 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 23 Sep 2021 13:40:45 +0000 Subject: [PATCH] Added fractional support to PLL, forced inline for all inline functions. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14821 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/RCCv2/stm32_csi.inc | 6 +- os/hal/ports/STM32/LLD/RCCv2/stm32_hse.inc | 6 +- os/hal/ports/STM32/LLD/RCCv2/stm32_hsi.inc | 6 +- os/hal/ports/STM32/LLD/RCCv2/stm32_lsi.inc | 2 +- os/hal/ports/STM32/LLD/RCCv2/stm32_pll3.inc | 100 +++++++++++++------- os/hal/ports/STM32/STM32MP1xx/hal_lld.h | 17 +++- 6 files changed, 91 insertions(+), 46 deletions(-) diff --git a/os/hal/ports/STM32/LLD/RCCv2/stm32_csi.inc b/os/hal/ports/STM32/LLD/RCCv2/stm32_csi.inc index 2f89d8719..aea1debab 100644 --- a/os/hal/ports/STM32/LLD/RCCv2/stm32_csi.inc +++ b/os/hal/ports/STM32/LLD/RCCv2/stm32_csi.inc @@ -57,7 +57,7 @@ /* Driver local functions. */ /*===========================================================================*/ -__STATIC_INLINE void csi_enable(void) { +__STATIC_FORCEINLINE void csi_enable(void) { RCC->OCENSETR = RCC_OCENSETR_CSION; while ((RCC->OCRDYR & RCC_OCRDYR_CSIRDY) == 0U) { @@ -65,12 +65,12 @@ __STATIC_INLINE void csi_enable(void) { } } -__STATIC_INLINE void csi_disable(void) { +__STATIC_FORCEINLINE void csi_disable(void) { RCC->OCENCLRR = RCC_OCENCLRR_CSION; } -__STATIC_INLINE void csi_init(void) { +__STATIC_FORCEINLINE void csi_init(void) { #if STM32_CSI_ENABLED /* HSI activation.*/ diff --git a/os/hal/ports/STM32/LLD/RCCv2/stm32_hse.inc b/os/hal/ports/STM32/LLD/RCCv2/stm32_hse.inc index 36d0a1708..d5901f3d0 100644 --- a/os/hal/ports/STM32/LLD/RCCv2/stm32_hse.inc +++ b/os/hal/ports/STM32/LLD/RCCv2/stm32_hse.inc @@ -89,7 +89,7 @@ /* Driver local functions. */ /*===========================================================================*/ -__STATIC_INLINE void hse_enable(void) { +__STATIC_FORCEINLINE void hse_enable(void) { #if 0 #if defined(STM32_HSE_BYPASS) @@ -118,12 +118,12 @@ __STATIC_INLINE void hse_enable(void) { } } -__STATIC_INLINE void hse_disable(void) { +__STATIC_FORCEINLINE void hse_disable(void) { RCC->OCENCLRR = RCC_OCENSETR_HSEON; } -__STATIC_INLINE void hse_init(void) { +__STATIC_FORCEINLINE void hse_init(void) { #if STM32_HSE_ENABLED hse_enable(); diff --git a/os/hal/ports/STM32/LLD/RCCv2/stm32_hsi.inc b/os/hal/ports/STM32/LLD/RCCv2/stm32_hsi.inc index 841675ca5..62d73e3ed 100644 --- a/os/hal/ports/STM32/LLD/RCCv2/stm32_hsi.inc +++ b/os/hal/ports/STM32/LLD/RCCv2/stm32_hsi.inc @@ -80,7 +80,7 @@ /* Driver local functions. */ /*===========================================================================*/ -__STATIC_INLINE void hsi_enable(void) { +__STATIC_FORCEINLINE void hsi_enable(void) { RCC->OCENSETR = RCC_OCENSETR_HSION; while ((RCC->OCRDYR & RCC_OCRDYR_HSIRDY) == 0U) { @@ -88,12 +88,12 @@ __STATIC_INLINE void hsi_enable(void) { } } -__STATIC_INLINE void hsi_disable(void) { +__STATIC_FORCEINLINE void hsi_disable(void) { RCC->OCENCLRR = RCC_OCENCLRR_HSION; } -__STATIC_INLINE void hsi_init(void) { +__STATIC_FORCEINLINE void hsi_init(void) { #if STM32_HSI_ENABLED /* HSI activation.*/ diff --git a/os/hal/ports/STM32/LLD/RCCv2/stm32_lsi.inc b/os/hal/ports/STM32/LLD/RCCv2/stm32_lsi.inc index f38a38b20..d441d6e4e 100644 --- a/os/hal/ports/STM32/LLD/RCCv2/stm32_lsi.inc +++ b/os/hal/ports/STM32/LLD/RCCv2/stm32_lsi.inc @@ -57,7 +57,7 @@ /* Driver local functions. */ /*===========================================================================*/ -__STATIC_INLINE void lsi_init(void) { +__STATIC_FORCEINLINE void lsi_init(void) { #if STM32_LSI_ENABLED /* LSI activation.*/ diff --git a/os/hal/ports/STM32/LLD/RCCv2/stm32_pll3.inc b/os/hal/ports/STM32/LLD/RCCv2/stm32_pll3.inc index 1cf7d1ae4..60f0ffe44 100644 --- a/os/hal/ports/STM32/LLD/RCCv2/stm32_pll3.inc +++ b/os/hal/ports/STM32/LLD/RCCv2/stm32_pll3.inc @@ -63,6 +63,10 @@ #error "STM32_PLL3DIVN_VALUE not defined in mcuconf.h" #endif +#if !defined(STM32_PLL3FRACV_VALUE) +#error "STM32_PLL3FRACV_VALUE not defined in mcuconf.h" +#endif + #if STM32_RCC_PLL3_HAS_P && !defined(STM32_PLL3DIVP_VALUE) #error "STM32_PLL3DIVP_VALUE not defined in mcuconf.h" #endif @@ -76,12 +80,16 @@ #endif /* Check on limits.*/ -#if !defined(STM32_PLL3INCLK_MAX) -#error "STM32_PLL3INCLK_MAX not defined in hal_lld.h" +#if !defined(STM32_PLL3REFCLK_MAX) +#error "STM32_PLL3REFCLK_MAX not defined in hal_lld.h" #endif -#if !defined(STM32_PLL3INCLK_MIN) -#error "STM32_PLL3INCLK_MIN not defined in hal_lld.h" +#if !defined(STM32_PLL3REFCLK_MIN) +#error "STM32_PLL3REFCLK_MIN not defined in hal_lld.h" +#endif + +#if !defined(STM32_PLL3REFCLK_SD_MIN) +#error "STM32_PLL3REFCLK_SD_MIN not defined in hal_lld.h" #endif #if !defined(STM32_PLL3VCOCLK_MAX) @@ -187,7 +195,7 @@ #if ((STM32_PLL3DIVM_VALUE >= STM32_PLL3DIVM_MIN) && \ (STM32_PLL3DIVM_VALUE <= STM32_PLL3DIVM_MAX)) || \ defined(__DOXYGEN__) -#define STM32_PLL3DIVM ((STM32_PLL3DIVM_VALUE - 1U) << RCC_PLLCFGR_PLL3DIVM_Pos) +#define STM32_PLL3DIVM ((STM32_PLL3DIVM_VALUE - 1U) << RCC_PLL3CFGR1_DIVM3_Pos) #else #error "invalid STM32_PLL3DIVM_VALUE value specified" @@ -196,11 +204,19 @@ /** * @brief Clock at the M divider input. */ -#define STM32_PLL3INCLK (STM32_PLL3MCLK / STM32_PLL3DIVM_VALUE) +#define STM32_PLL3REFCLK (STM32_PLL3MCLK / STM32_PLL3DIVM_VALUE) -#if (STM32_PLL3INCLK != 0) && \ - ((STM32_PLL3INCLK < STM32_PLL3INCLK_MIN) || (STM32_PLL3INCLK > STM32_PLL3INCLK_MAX)) -#error "STM32_PLL3INCLK outside acceptable range (STM32_PLL3INCLK_MIN...STM32_PLL3INCLK_MAX)" +#if (STM32_PLL3REFCLK != 0) && \ + ((STM32_PLL3REFCLK < STM32_PLL3REFCLK_MIN) || (STM32_PLL3REFCLK > STM32_PLL3REFCLK_MAX)) +#error "STM32_PLL3REFCLK outside acceptable range (STM32_PLL3REFCLK_MIN...STM32_PLL3REFCLK_MAX)" +#endif + + +#if (STM32_PLL3REFCLK < STM32_PLL3REFCLK_SD_MIN) || defined(__DOXYGEN___) +#define STM32_PLL3IFRGE 0U + +#else +#define STM32_PLL3IFRGE RCC_PLL3CFGR1_IFRGE_0 #endif /** @@ -209,16 +225,35 @@ #if ((STM32_PLL3DIVN_VALUE >= STM32_PLL3DIVN_MIN) && \ (STM32_PLL3DIVN_VALUE <= STM32_PLL3DIVN_MAX)) || \ defined(__DOXYGEN__) -#define STM32_PLL3DIVN ((STM32_PLL3DIVN_VALUE - 1U) << RCC_PLLCFGR_PLL3DIVN_Pos) +#define STM32_PLL3DIVN ((STM32_PLL3DIVN_VALUE - 1U) << RCC_PLL3CFGR1_DIVN_Pos) #else #error "invalid STM32_PLL3DIVN_VALUE value specified" #endif +/** + * @brief STM32_PLL3FRACV field. + */ +#if ((STM32_PLL3FRACV_VALUE >= 0) && \ + (STM32_PLL3FRACV_VALUE <= 8191)) || \ + defined(__DOXYGEN__) +#define STM32_PLL3FRACV (STM32_PLL3FRACV_VALUE << RCC_PLL3FRACR_FRACV_Pos) + +#else +#error "invalid STM32_PLL3DIVN_VALUE value specified" +#endif + +/* Assumes C99, intermediate results can be greater than 2^32.*/ +#if (0x80000000 << 1) == 0 +#error "preprocessor arithmetic issue, 64 bits capability required" +#endif + /** * @brief PLL VCO frequency. */ -#define STM32_PLL3VCOCLK (STM32_PLL3INCLK * STM32_PLL3DIVN_VALUE) +#define STM32_PLL3VCOCLK \ + (((STM32_PLL3REFCLK * 2) * \ + ((STM32_PLL3DIVN_VALUE * 8192) + STM32_PLL3FRACV_VALUE)) / 8192) /* * PLL VCO frequency range check. @@ -239,6 +274,7 @@ (STM32_PLL3DIVP_VALUE <= STM32_PLL3DIVP_MAX)) || \ defined(__DOXYGEN__) #define STM32_PLL3DIVP ((STM32_PLL3DIVP_VALUE - 1) << RCC_PLL3CFGR2_DIVP_Pos) + #else #error "invalid STM32_PLL3DIVP_VALUE value specified" #endif @@ -258,7 +294,7 @@ #endif #else /* !STM32_RCC_PLL_HAS_P */ -#define STM32_PLL3DIVP 0 +#define STM32_PLL3DIVP 0U #endif /* !STM32_RCC_PLL_HAS_P */ /*---------------------------------------------------------------------------*/ @@ -272,6 +308,7 @@ (STM32_PLL3DIVQ_VALUE <= STM32_PLL3DIVQ_MAX)) || \ defined(__DOXYGEN__) #define STM32_PLL3DIVQ ((STM32_PLL3DIVQ_VALUE - 1) << RCC_PLL3CFGR2_DIVQ_Pos) + #else #error "invalid STM32_PLL3DIVQ_VALUE value specified" #endif @@ -291,7 +328,7 @@ #endif #else /* !STM32_RCC_PLL_HAS_Q */ -#define STM32_PLL3DIVQ 0 +#define STM32_PLL3DIVQ 0U #endif /* !STM32_RCC_PLL_HAS_Q */ /*---------------------------------------------------------------------------*/ @@ -305,6 +342,7 @@ (STM32_PLL3DIVR_VALUE <= STM32_PLL3DIVR_MAX)) || \ defined(__DOXYGEN__) #define STM32_PLL3DIVR ((STM32_PLL3DIVR_VALUE - 1) << RCC_PLL3CFGR2_DIVR_Pos) + #else #error "invalid STM32_PLL3DIVR_VALUE value specified" #endif @@ -324,7 +362,7 @@ #endif #else /* !STM32_RCC_PLL_HAS_R */ -#define STM32_PLL3DIVR 0 +#define STM32_PLL3DIVR 0U #endif /* !STM32_RCC_PLL_HAS_R */ /*===========================================================================*/ @@ -339,49 +377,45 @@ /* Driver local functions. */ /*===========================================================================*/ -#if 0 -__STATIC_INLINE bool pll_not_locked(void) { +__STATIC_FORCEINLINE bool pll_not_locked(void) { - return (bool)((RCC->CR & RCC_CR_PLLRDY) == 0U); + return (bool)((RCC->PLL3CR & RCC_PLL3CR_PLL3RDY) == 0U); } -__STATIC_INLINE void pll_wait_lock(void) { +__STATIC_FORCEINLINE void pll_wait_lock(void) { while (pll_not_locked()) { /* Waiting for PLL lock.*/ } } -#endif #endif /* STM32_RCC_HAS_PLL */ -__STATIC_INLINE void pll_init(void) { +__STATIC_FORCEINLINE void pll_init(void) { #if STM32_RCC_HAS_PLL3 #if STM32_ACTIVATE_PLL3 - /* PLL activation.*/ -#if 0 - RCC->PLLCFGR = STM32_PLLPDIV | STM32_PLLR | - STM32_PLLREN | STM32_PLLQ | - STM32_PLLQEN | STM32_PLLP | - STM32_PLLPEN | STM32_PLLN | - STM32_PLLM | STM32_PLLSRC; - RCC->CR |= RCC_CR_PLLON; + /* PLL setup and activation.*/ + RCC->PLL3CFGR1 = STM32_PLL3IFRGE | STM32_PLL3DIVM | STM32_PLL3DIVN; + RCC->PLL3CFGR2 = STM32_PLL3DIVR | STM32_PLL3DIVQ | STM32_PLL3DIVP; + RCC->PLL3CR = RCC_PLL3CR_PLLON; + /* Waiting for lock.*/ pll_wait_lock(); -#endif + + /* Outputs enable after PLL lock.*/ + RCC->PLL3CR = RCC_PLL3CR_PLLON | + STM32_PLL3DIVREN | STM32_PLL3DIVQEN | STM32_PLL3DIVPEN; #endif #endif } -__STATIC_INLINE void pll_deinit(void) { +__STATIC_FORCEINLINE void pll_deinit(void) { #if STM32_RCC_HAS_PLL3 #if STM32_ACTIVATE_PLL3 /* PLL de-activation.*/ -#if 0 - RCC->PLLCFGR &= ~RCC_CR_PLLON; -#endif + RCC->PLL3CR &= ~RCC_PLL3CR_PLLON; #endif #endif } diff --git a/os/hal/ports/STM32/STM32MP1xx/hal_lld.h b/os/hal/ports/STM32/STM32MP1xx/hal_lld.h index 3a59bce91..9d524a998 100644 --- a/os/hal/ports/STM32/STM32MP1xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32MP1xx/hal_lld.h @@ -281,6 +281,17 @@ #define STM32_PLL3DIVN_VALUE 50 #endif +/** + * @brief PLL3 N multiplier fractional value. + * @note The allowed values are 0..8191. + * @note This initialization is performed only if TZEN=0 or MCKPROT=0 + * otherwise the setting must match the initialization performed + * on the Cortex-A side. + */ +#if !defined(STM32_PLL3FRACV_VALUE) || defined(__DOXYGEN__) +#define STM32_PLL3FRACV_VALUE 0 +#endif + /** * @brief PLL3 P divider value or zero if disabled. * @note The allowed values are 1..128. @@ -475,9 +486,9 @@ #define STM32_HSECLK_BYP_MAX 48000000 #define STM32_HSECLK_BYP_MIN 8000000 -#define STM32_PLL3INCLK_MAX 16000000 -#define STM32_PLL3INCLK_MIN 4000000 -#define STM32_PLL3INCLK_SD_MIN 8000000 +#define STM32_PLL3REFCLK_MAX 16000000 +#define STM32_PLL3REFCLK_MIN 4000000 +#define STM32_PLL3REFCLK_SD_MIN 8000000 #define STM32_PLL3VCOCLK_MAX 800000000 #define STM32_PLL3VCOCLK_MIN 400000000 #define STM32_PLL3PCLK_MAX 800000000