From 4e20785edc8203736bfee658b22b7ed8fe7f78d6 Mon Sep 17 00:00:00 2001 From: Rocco Marco Guglielmi Date: Tue, 31 May 2016 13:53:39 +0000 Subject: [PATCH] Improved PLLI2S extending support to STM32F446xx, STM32F469xx and STM32F479xx (Tested measuring PLLI2S as MCO2 with a scope). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9543 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/STM32F4xx/hal_lld.c | 3 +- os/hal/ports/STM32/STM32F4xx/hal_lld.h | 259 +++++++++++++++++++------ 2 files changed, 201 insertions(+), 61 deletions(-) diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld.c b/os/hal/ports/STM32/STM32F4xx/hal_lld.c index bbfbad2b4..aa38fb39e 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32F4xx/hal_lld.c @@ -227,7 +227,8 @@ void stm32_clock_init(void) { #if STM32_ACTIVATE_PLLI2S /* PLLI2S activation.*/ - RCC->PLLI2SCFGR = STM32_PLLI2SR | STM32_PLLI2SN; + RCC->PLLI2SCFGR = STM32_PLLI2SR | STM32_PLLI2SN | STM32_PLLI2SP | + STM32_PLLI2SQ | STM32_PLLI2SM; RCC->CR |= RCC_CR_PLLI2SON; /* Waiting for PLL lock.*/ diff --git a/os/hal/ports/STM32/STM32F4xx/hal_lld.h b/os/hal/ports/STM32/STM32F4xx/hal_lld.h index 337b8a052..b68968975 100644 --- a/os/hal/ports/STM32/STM32F4xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32F4xx/hal_lld.h @@ -129,8 +129,7 @@ */ #if defined(STM32F427xx) || defined(STM32F437xx) || \ defined(STM32F429xx) || defined(STM32F439xx) || \ - defined(STM32F446xx) || defined(STM32F469xx) || \ - defined(STM32F479xx) || defined(__DOXYGEN__) + defined(STM32F469xx) || defined(STM32F479xx) || defined(__DOXYGEN__) /** * @brief Absolute maximum system clock. */ @@ -204,7 +203,7 @@ /** * @brief Maximum APB1 clock frequency. */ -#define STM32_PCLK1_MAX (STM32_PLLOUT_MAX /4) +#define STM32_PCLK1_MAX (STM32_PLLOUT_MAX / 4) /** * @brief Maximum APB2 clock frequency. @@ -257,7 +256,7 @@ #define STM32_SPII2S_MAX 42000000 #endif -#if defined(STM32F410xx) +#if defined(STM32F410xx) || defined(__DOXYGEN__) #define STM32_SYSCLK_MAX 100000000 #define STM32_HSECLK_MAX 26000000 #define STM32_HSECLK_BYP_MAX 50000000 @@ -277,7 +276,7 @@ #define STM32_SPII2S_MAX 50000000 #endif -#if defined(STM32F411xx) +#if defined(STM32F411xx) || defined(__DOXYGEN__) #define STM32_SYSCLK_MAX 100000000 #define STM32_HSECLK_MAX 26000000 #define STM32_HSECLK_BYP_MAX 50000000 @@ -297,6 +296,26 @@ #define STM32_SPII2S_MAX 50000000 #endif +#if defined(STM32F446xx) || defined(__DOXYGEN__) +#define STM32_SYSCLK_MAX 180000000 +#define STM32_HSECLK_MAX 26000000 +#define STM32_HSECLK_BYP_MAX 50000000 +#define STM32_HSECLK_MIN 4000000 +#define STM32_HSECLK_BYP_MIN 1000000 +#define STM32_LSECLK_MAX 32768 +#define STM32_LSECLK_BYP_MAX 1000000 +#define STM32_LSECLK_MIN 32768 +#define STM32_PLLIN_MAX 2100000 +#define STM32_PLLIN_MIN 950000 +#define STM32_PLLVCO_MAX 432000000 +#define STM32_PLLVCO_MIN 100000000 +#define STM32_PLLOUT_MAX 180000000 +#define STM32_PLLOUT_MIN 12500000 +#define STM32_PCLK1_MAX (STM32_PLLOUT_MAX / 4) +#define STM32_PCLK2_MAX (STM32_PLLOUT_MAX / 2) +#define STM32_SPII2S_MAX 45000000 +#endif + #if defined(STM32F2XX) #define STM32_SYSCLK_MAX 120000000 #define STM32_HSECLK_MAX 26000000 @@ -431,6 +450,10 @@ #define STM32_PLLI2SM_MASK (31 << 0) /**< PLLI2SM mask. */ #define STM32_PLLI2SN_MASK (511 << 6) /**< PLLI2SN mask. */ #define STM32_PLLI2SP_MASK (3 << 16) /**< PLLI2SP mask. */ +#define STM32_PLLI2SP_DIV2 (0 << 16) /**< PLL clock divided by 2. */ +#define STM32_PLLI2SP_DIV4 (1 << 16) /**< PLL clock divided by 4. */ +#define STM32_PLLI2SP_DIV6 (2 << 16) /**< PLL clock divided by 6. */ +#define STM32_PLLI2SP_DIV8 (3 << 16) /**< PLL clock divided by 8. */ #define STM32_PLLI2SQ_MASK (15 << 24) /**< PLLI2SQ mask. */ #define STM32_PLLI2SR_MASK (7 << 28) /**< PLLI2SR mask. */ /** @} */ @@ -718,6 +741,104 @@ #endif #endif /* !defined(STM32F4XX) */ +/** + * @brief I2S clock source. + */ +#if !defined(STM32_I2SSRC) || defined(__DOXYGEN__) +#define STM32_I2SSRC STM32_I2SSRC_CKIN +#endif + +/** + * @brief PLLI2SN multiplier value. + * @note The allowed values are 192..432, except for + * STM32F446 where values are 50...432. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SN_VALUE 192 +#endif + +/** + * @brief PLLI2SM divider value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SM_VALUE 4 +#endif + +/** + * @brief PLLI2SR divider value. + * @note The allowed values are 2..7. + * @note The default value is calculated for a 96MHz I2S clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SR_VALUE 4 +#endif + +/** + * @brief PLLI2SP divider value. + * @note The allowed values are 2, 4, 6 and 8. + */ +#if !defined(STM32_PLLI2SP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SP_VALUE 4 +#endif + +/** + * @brief PLLI2SQ divider value. + * @note The allowed values are 2..15. + */ +#if !defined(STM32_PLLI2SQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLI2SQ_VALUE 4 +#endif + +/** + * @brief PLLSAIM value. + * @note The allowed values are 2..63. + * @note The default value is calculated for a 96MHz SAI clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSAIM_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIM_VALUE 4 +#endif + +/** + * @brief PLLSAIN value. + * @note The allowed values are 50..432. + * @note The default value is calculated for a 96MHz SAI clock + * output from an external 8MHz HSE clock. + */ +#if !defined(STM32_PLLSAIN_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIN_VALUE 192 +#endif + +/** + * @brief PLLSAIR value. + * @note The allowed values are 2..7. + */ +#if !defined(STM32_PLLSAIR_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIR_VALUE 4 +#endif + +/** + * @brief PLLSAIP divider value. + * @note The allowed values are 2, 4, 6 and 8. + */ +#if !defined(STM32_PLLSAIP_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIP_VALUE 4 +#endif + +/** + * @brief PLLSAIQ value. + * @note The allowed values are 2..15. + */ +#if !defined(STM32_PLLSAIQ_VALUE) || defined(__DOXYGEN__) +#define STM32_PLLSAIQ_VALUE 4 +#endif + /** * @brief AHB prescaler value. */ @@ -784,53 +905,6 @@ #if !defined(STM32_MCO2PRE) || defined(__DOXYGEN__) #define STM32_MCO2PRE STM32_MCO2PRE_DIV5 #endif - -/** - * @brief I2S clock source. - */ -#if !defined(STM32_I2SSRC) || defined(__DOXYGEN__) -#define STM32_I2SSRC STM32_I2SSRC_CKIN -#endif - -/** - * @brief PLLI2SN multiplier value. - * @note The allowed values are 192..432. - */ -#if !defined(STM32_PLLI2SN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SN_VALUE 192 -#endif - -/** - * @brief PLLI2SR multiplier value. - * @note The allowed values are 2..7. - */ -#if !defined(STM32_PLLI2SR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLI2SR_VALUE 5 -#endif - -/** - * @brief PLLSAIQ value. - * @note The allowed values are 2..15. - */ -#if !defined(STM32_PLLSAIQ_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIQ_VALUE 8 -#endif - -/** - * @brief PLLSAIQ value. - * @note The allowed values are 49..432. - */ -#if !defined(STM32_PLLSAIN_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIN_VALUE 120 -#endif - -/** - * @brief PLLSAIQ value. - * @note The allowed values are 2..7. - */ -#if !defined(STM32_PLLSAIR_VALUE) || defined(__DOXYGEN__) -#define STM32_PLLSAIR_VALUE 4 -#endif /** @} */ /*===========================================================================*/ @@ -1163,7 +1237,7 @@ #endif /** - * @brief PLLs input clock frequency. + * @brief PLL input clock frequency. */ #if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) #define STM32_PLLCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) @@ -1210,13 +1284,13 @@ * @brief STM32_PLLP field. */ #if (STM32_PLLP_VALUE == 2) || defined(__DOXYGEN__) -#define STM32_PLLP (0 << 16) +#define STM32_PLLP STM32_PLLP_DIV2 #elif STM32_PLLP_VALUE == 4 -#define STM32_PLLP (1 << 16) +#define STM32_PLLP STM32_PLLP_DIV4 #elif STM32_PLLP_VALUE == 6 -#define STM32_PLLP (2 << 16) +#define STM32_PLLP STM32_PLLP_DIV6 #elif STM32_PLLP_VALUE == 8 -#define STM32_PLLP (3 << 16) +#define STM32_PLLP STM32_PLLP_DIV8 #else #error "invalid STM32_PLLP_VALUE value specified" #endif @@ -1415,15 +1489,59 @@ #define STM32_ACTIVATE_PLLI2S FALSE #endif +/** + * @brief STM32_PLLI2SM field. + */ +#if ((STM32_PLLI2SM_VALUE >= 2) && (STM32_PLLI2SM_VALUE <= 63)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SM (STM32_PLLI2SM_VALUE << 0) +#else +#error "invalid STM32_PLLI2SM_VALUE value specified" +#endif + /** * @brief STM32_PLLI2SN field. */ +#if defined (STM32F446xx) || defined(__DOXYGEN__) +#if ((STM32_PLLI2SN_VALUE >= 50) && (STM32_PLLI2SN_VALUE <= 432)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SN (STM32_PLLI2SN_VALUE << 6) +#else +#error "invalid STM32_PLLI2SN_VALUE value specified" +#endif +#else /* !defined(STM32F446xx) */ #if ((STM32_PLLI2SN_VALUE >= 192) && (STM32_PLLI2SN_VALUE <= 432)) || \ defined(__DOXYGEN__) #define STM32_PLLI2SN (STM32_PLLI2SN_VALUE << 6) #else #error "invalid STM32_PLLI2SN_VALUE value specified" #endif +#endif /* defined(STM32F446xx) */ + +/** + * @brief STM32_PLLI2SP field. + */ +#if (STM32_PLLI2SP_VALUE == 2) || defined(__DOXYGEN__) +#define STM32_PLLI2SP STM32_PLLI2SP_DIV2 +#elif STM32_PLLI2SP_VALUE == 4 +#define STM32_PLLI2SP STM32_PLLI2SP_DIV4 +#elif STM32_PLLI2SP_VALUE == 6 +#define STM32_PLLI2SP STM32_PLLI2SP_DIV6 +#elif STM32_PLLI2SP_VALUE == 8 +#define STM32_PLLI2SP STM32_PLLI2SP_DIV8 +#else +#error "invalid STM32_PLLI2SP_VALUE value specified" +#endif + +/** + * @brief STM32_PLLI2SQ field. + */ +#if ((STM32_PLLI2SQ_VALUE >= 2) && (STM32_PLLI2SQ_VALUE <= 15)) || \ + defined(__DOXYGEN__) +#define STM32_PLLI2SQ (STM32_PLLI2SQ_VALUE << 24) +#else +#error "invalid STM32_PLLI2SQ_VALUE value specified" +#endif /** * @brief STM32_PLLI2SR field. @@ -1435,6 +1553,27 @@ #error "invalid STM32_PLLI2SR_VALUE value specified" #endif +/** + * @brief PLLI2S input clock frequency. + */ +#if defined(STM32F446xx) +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLI2SCLKIN (STM32_HSECLK / STM32_PLLI2SM_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLI2SCLKIN (STM32_HSICLK / STM32_PLLI2SM_VALUE) +#else +#error "invalid STM32_PLLSRC value specified" +#endif +#else /* !defined(STM32F446xx) */ +#if (STM32_PLLSRC == STM32_PLLSRC_HSE) || defined(__DOXYGEN__) +#define STM32_PLLI2SCLKIN (STM32_HSECLK / STM32_PLLM_VALUE) +#elif STM32_PLLSRC == STM32_PLLSRC_HSI +#define STM32_PLLI2SCLKIN (STM32_HSICLK / STM32_PLLM_VALUE) +#else +#error "invalid STM32_PLLSRC value specified" +#endif +#endif /* defined(STM32F446xx) */ + /** * @brief PLLSAI activation flag. */ @@ -1457,7 +1596,7 @@ defined(__DOXYGEN__) #define STM32_PLLSAIQ (STM32_PLLSAIQ_VALUE << 24) #else -#error "invalid STM32_PLLSAIR_VALUE value specified" +#error "invalid STM32_PLLSAIQ_VALUE value specified" #endif /** @@ -1471,9 +1610,9 @@ #endif /** - * @brief PLL VCO frequency. + * @brief PLLI2S VCO frequency. */ -#define STM32_PLLI2SVCO (STM32_PLLCLKIN * STM32_PLLI2SN_VALUE) +#define STM32_PLLI2SVCO (STM32_PLLI2SCLKIN * STM32_PLLI2SN_VALUE) /* * PLLI2S VCO frequency range check.