Dynamic support implemented for STM32L4+, improvements to STM32G4 HAL port.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14398 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-05-20 07:47:54 +00:00
parent 2cd2b4dfad
commit edecbf5144
10 changed files with 1192 additions and 444 deletions

View File

@ -61,13 +61,24 @@
/* Driver local functions. */ /* Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
__STATIC_INLINE void hsi48_enable(void) {
RCC->CRRCR |= RCC_CRRCR_HSI48ON;
while ((RCC->CRRCR & RCC_CRRCR_HSI48RDY) == 0U) {
/* Waiting for HSI48 activation.*/
}
}
__STATIC_INLINE void hsi48_disable(void) {
RCC->CRRCR &= ~RCC_CRRCR_HSI48ON;
}
__STATIC_INLINE void hsi48_init(void) { __STATIC_INLINE void hsi48_init(void) {
#if STM32_HSI48_ENABLED #if STM32_HSI48_ENABLED
/* HSI activation.*/ /* HSI activation.*/
RCC->CRRCR |= RCC_CRRCR_HSI48ON; hsi48_enable();
while ((RCC->CRRCR & RCC_CRRCR_HSI48RDY) == 0U) {
}
#endif #endif
} }

View File

@ -167,13 +167,18 @@
__STATIC_INLINE void msi_reset(void) { __STATIC_INLINE void msi_reset(void) {
/* Resetting to the MSI clock in case we come here after an initialization, /* Making sure MSI is active and ready.*/
because a debugger for example.*/ RCC->CR |= RCC_CR_MSION;
RCC->CR = RCC_CR_MSION;
while ((RCC->CR & RCC_CR_MSIRDY) == 0U) { while ((RCC->CR & RCC_CR_MSIRDY) == 0U) {
/* Wait until MSI is stable.*/ /* Wait until MSI is stable.*/
} }
/* Resetting MSI defaults.
Note from RM0432: MSIRANGE can be modified when MSI is OFF (MSION=0)
or when MSI is ready (MSIRDY=1). MSIRANGE must NOT be modified when
MSI is ON and NOT ready (MSION=1 and MSIRDY=0).*/
RCC->CR = (RCC->CR & ~RCC_CR_MSIRANGE_Msk) | RCC_CR_MSIRANGE_6;
/* Clocking from MSI, in case MSI was not the default source.*/ /* Clocking from MSI, in case MSI was not the default source.*/
RCC->CFGR = 0U; RCC->CFGR = 0U;
while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) { while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) {

View File

@ -319,9 +319,14 @@
/* Driver local functions. */ /* Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
__STATIC_INLINE bool pll_not_locked(void) {
return (bool)((RCC->CR & RCC_CR_PLLRDY) == 0U);
}
__STATIC_INLINE void pll_wait_lock(void) { __STATIC_INLINE void pll_wait_lock(void) {
while ((RCC->CR & RCC_CR_PLLRDY) == 0U) { while (pll_not_locked()) {
/* Waiting for PLL lock.*/ /* Waiting for PLL lock.*/
} }
} }

View File

@ -323,6 +323,18 @@
/* Driver local functions. */ /* Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
__STATIC_INLINE bool pllsai1_not_locked(void) {
return (bool)((RCC->CR & RCC_CR_PLLSAI1RDY) == 0U);
}
__STATIC_INLINE void pllsai1_wait_lock(void) {
while (pllsai1_not_locked()) {
/* Waiting for PLLSAI1 lock.*/
}
}
__STATIC_INLINE void pllsai1_init(void) { __STATIC_INLINE void pllsai1_init(void) {
#if STM32_ACTIVATE_PLLSAI1 #if STM32_ACTIVATE_PLLSAI1

View File

@ -323,6 +323,22 @@
/* Driver local functions. */ /* Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
__STATIC_INLINE bool pllsai2_not_locked(void) {
if ((RCC->CR & RCC_CR_PLLSAI2ON) == 0U) {
/* Disabled, no need to lock.*/
return false;
}
return (bool)((RCC->CR & RCC_CR_PLLSAI2RDY) == 0U);
}
__STATIC_INLINE void pllsai2_wait_lock(void) {
while (pllsai2_not_locked()) {
/* Waiting for PLLSAI2 lock.*/
}
}
__STATIC_INLINE void pllsai2_init(void) { __STATIC_INLINE void pllsai2_init(void) {
#if STM32_ACTIVATE_PLLSAI2 #if STM32_ACTIVATE_PLLSAI2
@ -335,8 +351,7 @@ __STATIC_INLINE void pllsai2_init(void) {
RCC->CR |= RCC_CR_PLLSAI2ON; RCC->CR |= RCC_CR_PLLSAI2ON;
/* Waiting for PLL lock.*/ /* Waiting for PLL lock.*/
while ((RCC->CR & RCC_CR_PLLSAI2RDY) == 0U) pllsai2_wait_lock();
;
#endif #endif
} }

View File

@ -139,42 +139,46 @@ typedef struct {
* @brief System limits for VOS RANGE1. * @brief System limits for VOS RANGE1.
*/ */
static const system_limits_t vos_range1 = { static const system_limits_t vos_range1 = {
.sysclk_max_boost = 170000000U, .sysclk_max_boost = STM32_VOS1_SYSCLK_MAX,
.sysclk_max_noboost = 150000000U, .sysclk_max_noboost = STM32_VOS1_SYSCLK_MAX_NOBOOST,
.pllin_max = 16000000U, .pllin_max = STM32_VOS1_PLLIN_MAX,
.pllin_min = 2660000U, .pllin_min = STM32_VOS1_PLLIN_MIN,
.pllvco_max = 344000000U, .pllvco_max = STM32_VOS1_PLLVCO_MAX,
.pllvco_min = 96000000U, .pllvco_min = STM32_VOS1_PLLVCO_MIN,
.pllp_max = 170000000U, .pllp_max = STM32_VOS1_PLLP_MAX,
.pllp_min = 2064500U, .pllp_min = STM32_VOS1_PLLP_MIN,
.pllq_max = 170000000U, .pllq_max = STM32_VOS1_PLLQ_MAX,
.pllq_min = 8000000U, .pllq_min = STM32_VOS1_PLLQ_MIN,
.pllr_max = 170000000U, .pllr_max = STM32_VOS1_PLLR_MAX,
.pllr_min = 8000000U, .pllr_min = STM32_VOS1_PLLR_MIN,
.flash_thresholds = { 20000000U, 40000000U, 60000000U, 80000000U, .flash_thresholds = {STM32_VOS1_0WS_THRESHOLD, STM32_VOS1_1WS_THRESHOLD,
100000000U, 120000000U, 140000000U, 160000000U, STM32_VOS1_2WS_THRESHOLD, STM32_VOS1_3WS_THRESHOLD,
170000000U} STM32_VOS1_4WS_THRESHOLD, STM32_VOS1_5WS_THRESHOLD,
STM32_VOS1_6WS_THRESHOLD, STM32_VOS1_7WS_THRESHOLD,
STM32_VOS1_8WS_THRESHOLD}
}; };
/** /**
* @brief System limits for VOS RANGE2. * @brief System limits for VOS RANGE2.
*/ */
static const system_limits_t vos_range2 = { static const system_limits_t vos_range2 = {
.sysclk_max_boost = 0U, .sysclk_max_boost = STM32_VOS2_SYSCLK_MAX,
.sysclk_max_noboost = 26000000U, .sysclk_max_noboost = STM32_VOS2_SYSCLK_MAX_NOBOOST,
.pllin_max = 16000000U, .pllin_max = STM32_VOS2_PLLIN_MAX,
.pllin_min = 2660000U, .pllin_min = STM32_VOS2_PLLIN_MIN,
.pllvco_max = 128000000U, .pllvco_max = STM32_VOS2_PLLVCO_MAX,
.pllvco_min = 96000000U, .pllvco_min = STM32_VOS2_PLLVCO_MIN,
.pllp_max = 26000000U, .pllp_max = STM32_VOS2_PLLP_MAX,
.pllp_min = 2064500U, .pllp_min = STM32_VOS2_PLLP_MIN,
.pllq_max = 26000000U, .pllq_max = STM32_VOS2_PLLQ_MAX,
.pllq_min = 8000000U, .pllq_min = STM32_VOS2_PLLQ_MIN,
.pllr_max = 26000000U, .pllr_max = STM32_VOS2_PLLR_MAX,
.pllr_min = 8000000U, .pllr_min = STM32_VOS2_PLLR_MIN,
.flash_thresholds = { 8000000U, 16000000U, 26000000U, 0U, .flash_thresholds = {STM32_VOS2_0WS_THRESHOLD, STM32_VOS2_1WS_THRESHOLD,
0U, 0U, 0U, 0U, STM32_VOS2_2WS_THRESHOLD, STM32_VOS2_3WS_THRESHOLD,
0U} STM32_VOS2_4WS_THRESHOLD, STM32_VOS2_5WS_THRESHOLD,
STM32_VOS2_6WS_THRESHOLD, STM32_VOS2_7WS_THRESHOLD,
STM32_VOS2_8WS_THRESHOLD}
}; };
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */ #endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
@ -387,7 +391,8 @@ static bool hal_lld_clock_check_tree(const halclkcfg_t *ccp) {
flashws = ((ccp->flash_acr & FLASH_ACR_LATENCY_Msk) >> FLASH_ACR_LATENCY_Pos); flashws = ((ccp->flash_acr & FLASH_ACR_LATENCY_Msk) >> FLASH_ACR_LATENCY_Pos);
if (flashws >= STM32_WS_THRESHOLDS) { if (flashws >= STM32_WS_THRESHOLDS) {
return true; return true;
} if (hclk > slp->flash_thresholds[flashws]) { }
if (hclk > slp->flash_thresholds[flashws]) {
return true; return true;
} }

View File

@ -652,177 +652,154 @@
#endif #endif
/**
* @name System Limits for VOS range 1
* @{
*/
#define STM32_VOS1_SYSCLK_MAX 170000000
#define STM32_VOS1_SYSCLK_MAX_NOBOOST 150000000
#define STM32_VOS1_HSECLK_MAX 48000000
#define STM32_VOS1_HSECLK_BYP_MAX 48000000
#define STM32_VOS1_HSECLK_MIN 8000000
#define STM32_VOS1_HSECLK_BYP_MIN 8000000
#define STM32_VOS1_LSECLK_MAX 32768
#define STM32_VOS1_LSECLK_BYP_MAX 1000000
#define STM32_VOS1_LSECLK_MIN 32768
#define STM32_VOS1_LSECLK_BYP_MIN 32768
#define STM32_VOS1_PLLIN_MAX 16000000
#define STM32_VOS1_PLLIN_MIN 2660000
#define STM32_VOS1_PLLVCO_MAX 344000000
#define STM32_VOS1_PLLVCO_MIN 96000000
#define STM32_VOS1_PLLP_MAX 170000000
#define STM32_VOS1_PLLP_MIN 2064500
#define STM32_VOS1_PLLQ_MAX 170000000
#define STM32_VOS1_PLLQ_MIN 8000000
#define STM32_VOS1_PLLR_MAX 170000000
#define STM32_VOS1_PLLR_MIN 8000000
#define STM32_VOS1_PCLK1_MAX 170000000
#define STM32_VOS1_PCLK2_MAX 170000000
#define STM32_VOS1_ADCCLK_MAX 60000000
#define STM32_VOS1_0WS_THRESHOLD 20000000
#define STM32_VOS1_1WS_THRESHOLD 40000000
#define STM32_VOS1_2WS_THRESHOLD 60000000
#define STM32_VOS1_3WS_THRESHOLD 80000000
#define STM32_VOS1_4WS_THRESHOLD 100000000
#define STM32_VOS1_5WS_THRESHOLD 120000000
#define STM32_VOS1_6WS_THRESHOLD 140000000
#define STM32_VOS1_7WS_THRESHOLD 160000000
#define STM32_VOS1_8WS_THRESHOLD 170000000
/** @} */
/**
* @name System Limits for VOS range 2
* @{
*/
#define STM32_VOS2_SYSCLK_MAX 26000000
#define STM32_VOS2_SYSCLK_MAX_NOBOOST 26000000
#define STM32_VOS2_HSECLK_MAX 26000000
#define STM32_VOS2_HSECLK_BYP_MAX 26000000
#define STM32_VOS2_HSECLK_MIN 8000000
#define STM32_VOS2_HSECLK_BYP_MIN 8000000
#define STM32_VOS2_LSECLK_MAX 32768
#define STM32_VOS2_LSECLK_BYP_MAX 1000000
#define STM32_VOS2_LSECLK_MIN 32768
#define STM32_VOS2_LSECLK_BYP_MIN 32768
#define STM32_VOS2_PLLIN_MAX 16000000
#define STM32_VOS2_PLLIN_MIN 2660000
#define STM32_VOS2_PLLVCO_MAX 128000000
#define STM32_VOS2_PLLVCO_MIN 96000000
#define STM32_VOS2_PLLP_MAX 26000000
#define STM32_VOS2_PLLP_MIN 2064500
#define STM32_VOS2_PLLQ_MAX 26000000
#define STM32_VOS2_PLLQ_MIN 8000000
#define STM32_VOS2_PLLR_MAX 26000000
#define STM32_VOS2_PLLR_MIN 8000000
#define STM32_VOS2_PCLK1_MAX 26000000
#define STM32_VOS2_PCLK2_MAX 26000000
#define STM32_VOS2_ADCCLK_MAX 26000000
#define STM32_VOS2_0WS_THRESHOLD 8000000
#define STM32_VOS2_1WS_THRESHOLD 16000000
#define STM32_VOS2_2WS_THRESHOLD 26000000
#define STM32_VOS2_3WS_THRESHOLD 0
#define STM32_VOS2_4WS_THRESHOLD 0
#define STM32_VOS2_5WS_THRESHOLD 0
#define STM32_VOS2_6WS_THRESHOLD 0
#define STM32_VOS2_7WS_THRESHOLD 0
#define STM32_VOS2_8WS_THRESHOLD 0
/** @} */
/* Voltage related limits.*/ /* Voltage related limits.*/
#if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__) #if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__)
/** #define STM32_SYSCLK_MAX STM32_VOS1_SYSCLK_MAX
* @name System Limits #define STM32_SYSCLK_MAX_NOBOOST STM32_VOS1_SYSCLK_MAX_NOBOOST
* @{ #define STM32_HSECLK_MAX STM32_VOS1_HSECLK_MAX
*/ #define STM32_HSECLK_BYP_MAX STM32_VOS1_HSECLK_BYP_MAX
/** #define STM32_HSECLK_MIN STM32_VOS1_HSECLK_MIN
* @brief Maximum SYSCLK clock frequency. #define STM32_HSECLK_BYP_MIN STM32_VOS1_HSECLK_BYP_MIN
*/ #define STM32_LSECLK_MAX STM32_VOS1_LSECLK_MAX
#define STM32_SYSCLK_MAX 170000000 #define STM32_LSECLK_BYP_MAX STM32_VOS1_LSECLK_BYP_MAX
#define STM32_LSECLK_MIN STM32_VOS1_LSECLK_MIN
#define STM32_LSECLK_BYP_MIN STM32_VOS1_LSECLK_BYP_MIN
#define STM32_PLLIN_MAX STM32_VOS1_PLLIN_MAX
#define STM32_PLLIN_MIN STM32_VOS1_PLLIN_MIN
#define STM32_PLLVCO_MAX STM32_VOS1_PLLVCO_MAX
#define STM32_PLLVCO_MIN STM32_VOS1_PLLVCO_MIN
#define STM32_PLLP_MAX STM32_VOS1_PLLP_MAX
#define STM32_PLLP_MIN STM32_VOS1_PLLP_MIN
#define STM32_PLLQ_MAX STM32_VOS1_PLLQ_MAX
#define STM32_PLLQ_MIN STM32_VOS1_PLLQ_MIN
#define STM32_PLLR_MAX STM32_VOS1_PLLR_MAX
#define STM32_PLLR_MIN STM32_VOS1_PLLR_MIN
#define STM32_PCLK1_MAX STM32_VOS1_PCLK1_MAX
#define STM32_PCLK2_MAX STM32_VOS1_PCLK2_MAX
#define STM32_ADCCLK_MAX STM32_VOS1_ADCCLK_MAX
/** #define STM32_0WS_THRESHOLD STM32_VOS1_0WS_THRESHOLD
* @brief Maximum SYSCLK clock frequency without voltage boost. #define STM32_1WS_THRESHOLD STM32_VOS1_1WS_THRESHOLD
*/ #define STM32_2WS_THRESHOLD STM32_VOS1_2WS_THRESHOLD
#define STM32_SYSCLK_MAX_NOBOOST 150000000 #define STM32_3WS_THRESHOLD STM32_VOS1_3WS_THRESHOLD
#define STM32_4WS_THRESHOLD STM32_VOS1_4WS_THRESHOLD
/** #define STM32_5WS_THRESHOLD STM32_VOS1_5WS_THRESHOLD
* @brief Maximum HSE clock frequency at current voltage setting. #define STM32_6WS_THRESHOLD STM32_VOS1_6WS_THRESHOLD
*/ #define STM32_7WS_THRESHOLD STM32_VOS1_7WS_THRESHOLD
#define STM32_HSECLK_MAX 48000000 #define STM32_8WS_THRESHOLD STM32_VOS1_8WS_THRESHOLD
/**
* @brief Maximum HSE clock frequency using an external source.
*/
#define STM32_HSECLK_BYP_MAX 48000000
/**
* @brief Minimum HSE clock frequency.
*/
#define STM32_HSECLK_MIN 8000000
/**
* @brief Minimum HSE clock frequency using an external source.
*/
#define STM32_HSECLK_BYP_MIN 8000000
/**
* @brief Maximum LSE clock frequency.
*/
#define STM32_LSECLK_MAX 32768
/**
* @brief Maximum LSE clock frequency.
*/
#define STM32_LSECLK_BYP_MAX 1000000
/**
* @brief Minimum LSE clock frequency.
*/
#define STM32_LSECLK_MIN 32768
/**
* @brief Minimum LSE clock frequency.
*/
#define STM32_LSECLK_BYP_MIN 32768
/**
* @brief Maximum PLLs input clock frequency.
*/
#define STM32_PLLIN_MAX 16000000
/**
* @brief Minimum PLLs input clock frequency.
*/
#define STM32_PLLIN_MIN 2660000
/**
* @brief Maximum VCO clock frequency at current voltage setting.
*/
#define STM32_PLLVCO_MAX 344000000
/**
* @brief Minimum VCO clock frequency at current voltage setting.
*/
#define STM32_PLLVCO_MIN 96000000
/**
* @brief Maximum PLL-P output clock frequency.
*/
#define STM32_PLLP_MAX 170000000
/**
* @brief Minimum PLL-P output clock frequency.
*/
#define STM32_PLLP_MIN 2064500
/**
* @brief Maximum PLL-Q output clock frequency.
*/
#define STM32_PLLQ_MAX 170000000
/**
* @brief Minimum PLL-Q output clock frequency.
*/
#define STM32_PLLQ_MIN 8000000
/**
* @brief Maximum PLL-R output clock frequency.
*/
#define STM32_PLLR_MAX 170000000
/**
* @brief Minimum PLL-R output clock frequency.
*/
#define STM32_PLLR_MIN 8000000
/**
* @brief Maximum APB clock frequency.
*/
#define STM32_PCLK1_MAX 170000000
/**
* @brief Maximum APB clock frequency.
*/
#define STM32_PCLK2_MAX 170000000
/**
* @brief Maximum ADC clock frequency.
*/
#define STM32_ADCCLK_MAX 60000000
/** @} */
/**
* @name Flash Wait states
* @{
*/
#define STM32_0WS_THRESHOLD 20000000
#define STM32_1WS_THRESHOLD 40000000
#define STM32_2WS_THRESHOLD 60000000
#define STM32_3WS_THRESHOLD 80000000
#define STM32_4WS_THRESHOLD 100000000
#define STM32_5WS_THRESHOLD 120000000
#define STM32_6WS_THRESHOLD 140000000
#define STM32_7WS_THRESHOLD 160000000
#define STM32_8WS_THRESHOLD 170000000
/** @} */
#elif STM32_VOS == STM32_VOS_RANGE2 #elif STM32_VOS == STM32_VOS_RANGE2
#define STM32_SYSCLK_MAX 26000000 #define STM32_SYSCLK_MAX STM32_VOS2_SYSCLK_MAX
#define STM32_SYSCLK_MAX_NOBOOST 26000000 #define STM32_SYSCLK_MAX_NOBOOST STM32_VOS2_SYSCLK_MAX_NOBOOST
#define STM32_HSECLK_MAX 26000000 #define STM32_HSECLK_MAX STM32_VOS2_HSECLK_MAX
#define STM32_HSECLK_BYP_MAX 26000000 #define STM32_HSECLK_BYP_MAX STM32_VOS2_HSECLK_BYP_MAX
#define STM32_HSECLK_MIN 8000000 #define STM32_HSECLK_MIN STM32_VOS2_HSECLK_MIN
#define STM32_HSECLK_BYP_MIN 8000000 #define STM32_HSECLK_BYP_MIN STM32_VOS2_HSECLK_BYP_MIN
#define STM32_LSECLK_MAX 32768 #define STM32_LSECLK_MAX STM32_VOS2_LSECLK_MAX
#define STM32_LSECLK_BYP_MAX 1000000 #define STM32_LSECLK_BYP_MAX STM32_VOS2_LSECLK_BYP_MAX
#define STM32_LSECLK_MIN 32768 #define STM32_LSECLK_MIN STM32_VOS2_LSECLK_MIN
#define STM32_LSECLK_BYP_MIN 32768 #define STM32_LSECLK_BYP_MIN STM32_VOS2_LSECLK_BYP_MIN
#define STM32_PLLIN_MAX 16000000 #define STM32_PLLIN_MAX STM32_VOS2_PLLIN_MAX
#define STM32_PLLIN_MIN 2660000 #define STM32_PLLIN_MIN STM32_VOS2_PLLIN_MIN
#define STM32_PLLVCO_MAX 128000000 #define STM32_PLLVCO_MAX STM32_VOS2_PLLVCO_MAX
#define STM32_PLLVCO_MIN 96000000 #define STM32_PLLVCO_MIN STM32_VOS2_PLLVCO_MIN
#define STM32_PLLP_MAX 26000000 #define STM32_PLLP_MAX STM32_VOS2_PLLP_MAX
#define STM32_PLLP_MIN 2064500 #define STM32_PLLP_MIN STM32_VOS2_PLLP_MIN
#define STM32_PLLQ_MAX 26000000 #define STM32_PLLQ_MAX STM32_VOS2_PLLQ_MAX
#define STM32_PLLQ_MIN 8000000 #define STM32_PLLQ_MIN STM32_VOS2_PLLQ_MIN
#define STM32_PLLR_MAX 26000000 #define STM32_PLLR_MAX STM32_VOS2_PLLR_MAX
#define STM32_PLLR_MIN 8000000 #define STM32_PLLR_MIN STM32_VOS2_PLLR_MIN
#define STM32_PCLK1_MAX 26000000 #define STM32_PCLK1_MAX STM32_VOS2_PCLK1_MAX
#define STM32_PCLK2_MAX 26000000 #define STM32_PCLK2_MAX STM32_VOS2_PCLK2_MAX
#define STM32_ADCCLK_MAX 26000000 #define STM32_ADCCLK_MAX STM32_VOS2_ADCCLK_MAX
#define STM32_0WS_THRESHOLD 8000000 #define STM32_0WS_THRESHOLD STM32_VOS2_0WS_THRESHOLD
#define STM32_1WS_THRESHOLD 16000000 #define STM32_1WS_THRESHOLD STM32_VOS2_1WS_THRESHOLD
#define STM32_2WS_THRESHOLD 26000000 #define STM32_2WS_THRESHOLD STM32_VOS2_2WS_THRESHOLD
#define STM32_3WS_THRESHOLD 0 #define STM32_3WS_THRESHOLD STM32_VOS2_3WS_THRESHOLD
#define STM32_4WS_THRESHOLD 0 #define STM32_4WS_THRESHOLD STM32_VOS2_4WS_THRESHOLD
#define STM32_5WS_THRESHOLD 0 #define STM32_5WS_THRESHOLD STM32_VOS2_5WS_THRESHOLD
#define STM32_6WS_THRESHOLD 0 #define STM32_6WS_THRESHOLD STM32_VOS2_6WS_THRESHOLD
#define STM32_7WS_THRESHOLD 0 #define STM32_7WS_THRESHOLD STM32_VOS2_7WS_THRESHOLD
#define STM32_8WS_THRESHOLD 0 #define STM32_8WS_THRESHOLD STM32_VOS2_8WS_THRESHOLD
#else #else
#error "invalid STM32_VOS value specified" #error "invalid STM32_VOS value specified"

View File

@ -28,6 +28,11 @@
/* Driver local definitions. */ /* Driver local definitions. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief Number of thresholds in the wait states array.
*/
#define STM32_WS_THRESHOLDS 6
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* Driver exported variables. */
/*===========================================================================*/ /*===========================================================================*/
@ -38,16 +43,569 @@
*/ */
uint32_t SystemCoreClock = STM32_HCLK; uint32_t SystemCoreClock = STM32_HCLK;
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
/**
* @brief Post-reset clock configuration.
*/
const halclkcfg_t hal_clkcfg_reset = {
.pwr_cr1 = PWR_CR1_VOS_0,
.pwr_cr2 = 0U,
.pwr_cr3 = PWR_CR3_EIWF,
.pwr_cr4 = 0U,
.pwr_cr5 = PWR_CR5_R1MODE,
.rcc_cr = RCC_CR_MSIRANGE_6 | RCC_CR_MSION,
.rcc_cfgr = RCC_CFGR_SW_MSI,
.rcc_pllcfgr = 0U,
.rcc_pllsai1cfgr = 0U,
.rcc_pllsai2cfgr = 0U,
.rcc_crrcr = 0U,
.flash_acr = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_LATENCY_0WS
};
/**
* @brief Default clock configuration.
*/
const halclkcfg_t hal_clkcfg_default = {
.pwr_cr1 = STM32_VOS_RANGE1 | PWR_CR1_DBP,
.pwr_cr2 = STM32_PWR_CR2,
.pwr_cr3 = STM32_PWR_CR3,
.pwr_cr4 = STM32_PWR_CR4,
.pwr_cr5 = STM32_CR5BITS,
.rcc_cr = 0U
#if STM32_MSIPLL_ENABLED
| STM32_MSIRANGE | RCC_CR_MSIPLLEN | RCC_CR_MSION
#else
| STM32_MSIRANGE | RCC_CR_MSION
#endif
#if STM32_HSI16_ENABLED
| RCC_CR_HSIKERON | RCC_CR_HSION
#endif
#if STM32_HSE_ENABLED
| RCC_CR_HSEON
#endif
#if STM32_ACTIVATE_PLL
| RCC_CR_PLLON
#endif
,
.rcc_cfgr = STM32_MCOPRE | STM32_MCOSEL |
STM32_PPRE2 | STM32_PPRE1 |
STM32_HPRE | STM32_SW,
.rcc_pllcfgr = STM32_PLLPDIV | STM32_PLLR |
STM32_PLLREN | STM32_PLLQ |
STM32_PLLQEN | STM32_PLLP |
STM32_PLLPEN | STM32_PLLN |
STM32_PLLM | STM32_PLLSRC,
.rcc_pllsai1cfgr = STM32_PLLSAI1PDIV | STM32_PLLSAI1R |
STM32_PLLSAI1REN | STM32_PLLSAI1Q |
STM32_PLLSAI1QEN | STM32_PLLSAI1P |
STM32_PLLSAI1PEN | STM32_PLLSAI1N |
STM32_PLLSAI1M,
.rcc_pllsai2cfgr = STM32_PLLSAI2PDIV | STM32_PLLSAI2R |
STM32_PLLSAI2REN | STM32_PLLSAI2Q |
STM32_PLLSAI2QEN | STM32_PLLSAI2P |
STM32_PLLSAI2PEN | STM32_PLLSAI2N |
STM32_PLLSAI2M,
#if STM32_HSI48_ENABLED
.rcc_crrcr = RCC_CRRCR_HSI48ON,
#else
.rcc_crrcr = 0U,
#endif
.flash_acr = FLASH_ACR_DCEN | FLASH_ACR_ICEN |
FLASH_ACR_PRFTEN | STM32_FLASHBITS
};
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/ /*===========================================================================*/
/* Driver local variables and types. */ /* Driver local variables and types. */
/*===========================================================================*/ /*===========================================================================*/
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
/**
* @brief Dynamic clock points for this device.
*/
static halfreq_t clock_points[CLK_ARRAY_SIZE] = {
[CLK_SYSCLK] = STM32_SYSCLK,
[CLK_PLLPCLK] = STM32_PLL_P_CLKOUT,
[CLK_PLLQCLK] = STM32_PLL_Q_CLKOUT,
[CLK_PLLRCLK] = STM32_PLL_R_CLKOUT,
[CLK_PLLSAI1PCLK] = STM32_PLLSAI1_P_CLKOUT,
[CLK_PLLSAI1QCLK] = STM32_PLLSAI1_Q_CLKOUT,
[CLK_PLLSAI1RCLK] = STM32_PLLSAI1_R_CLKOUT,
[CLK_PLLSAI2PCLK] = STM32_PLLSAI2_P_CLKOUT,
[CLK_PLLSAI2QCLK] = STM32_PLLSAI2_Q_CLKOUT,
[CLK_PLLSAI2RCLK] = STM32_PLLSAI2_R_CLKOUT,
[CLK_HCLK] = STM32_HCLK,
[CLK_PCLK1] = STM32_PCLK1,
[CLK_PCLK1TIM] = STM32_TIMP1CLK,
[CLK_PCLK2] = STM32_PCLK2,
[CLK_PCLK2TIM] = STM32_TIMP2CLK,
[CLK_MCO] = STM32_MCOCLK,
};
/**
* @brief Type of a structure representing system limits.
*/
typedef struct {
halfreq_t sysclk_max_boost;
halfreq_t sysclk_max_noboost;
halfreq_t pllin_max;
halfreq_t pllin_min;
halfreq_t pllvco_max;
halfreq_t pllvco_min;
halfreq_t pllp_max;
halfreq_t pllp_min;
halfreq_t pllq_max;
halfreq_t pllq_min;
halfreq_t pllr_max;
halfreq_t pllr_min;
halfreq_t flash_thresholds[STM32_WS_THRESHOLDS];
} system_limits_t;
/**
* @brief System limits for VOS RANGE1.
*/
static const system_limits_t vos_range1 = {
.sysclk_max_boost = STM32_VOS1_SYSCLK_MAX,
.sysclk_max_noboost = STM32_VOS1_SYSCLK_MAX_NOBOOST,
.pllin_max = STM32_VOS1_PLLIN_MAX,
.pllin_min = STM32_VOS1_PLLIN_MIN,
.pllvco_max = STM32_VOS1_PLLVCO_MAX,
.pllvco_min = STM32_VOS1_PLLVCO_MIN,
.pllp_max = STM32_VOS1_PLLP_MAX,
.pllp_min = STM32_VOS1_PLLP_MIN,
.pllq_max = STM32_VOS1_PLLQ_MAX,
.pllq_min = STM32_VOS1_PLLQ_MIN,
.pllr_max = STM32_VOS1_PLLR_MAX,
.pllr_min = STM32_VOS1_PLLR_MIN,
.flash_thresholds = {STM32_VOS1_0WS_THRESHOLD, STM32_VOS1_1WS_THRESHOLD,
STM32_VOS1_2WS_THRESHOLD, STM32_VOS1_3WS_THRESHOLD,
STM32_VOS1_4WS_THRESHOLD, STM32_VOS1_5WS_THRESHOLD}
};
/**
* @brief System limits for VOS RANGE2.
*/
static const system_limits_t vos_range2 = {
.sysclk_max_boost = STM32_VOS2_SYSCLK_MAX,
.sysclk_max_noboost = STM32_VOS2_SYSCLK_MAX_NOBOOST,
.pllin_max = STM32_VOS2_PLLIN_MAX,
.pllin_min = STM32_VOS2_PLLIN_MIN,
.pllvco_max = STM32_VOS2_PLLVCO_MAX,
.pllvco_min = STM32_VOS2_PLLVCO_MIN,
.pllp_max = STM32_VOS2_PLLP_MAX,
.pllp_min = STM32_VOS2_PLLP_MIN,
.pllq_max = STM32_VOS2_PLLQ_MAX,
.pllq_min = STM32_VOS2_PLLQ_MIN,
.pllr_max = STM32_VOS2_PLLR_MAX,
.pllr_min = STM32_VOS2_PLLR_MIN,
.flash_thresholds = {STM32_VOS2_0WS_THRESHOLD, STM32_VOS2_1WS_THRESHOLD,
STM32_VOS2_2WS_THRESHOLD, STM32_VOS2_3WS_THRESHOLD,
STM32_VOS2_4WS_THRESHOLD, STM32_VOS2_5WS_THRESHOLD}
};
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/ /*===========================================================================*/
/* Driver local functions. */ /* Driver local functions. */
/*===========================================================================*/ /*===========================================================================*/
#include "stm32_bd.inc" #include "stm32_bd.inc"
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
static bool hal_lld_check_pll(const system_limits_t *slp,
uint32_t cfgr,
halfreq_t selclk,
halfreq_t *pclkp,
halfreq_t *qclkp,
halfreq_t *rclkp) {
uint32_t mdiv, ndiv, pdiv, qdiv, rdiv;
halfreq_t vcoclk, pclk = 0U, qclk = 0U, rclk = 0U;
/* PLL M divider.*/
mdiv = ((cfgr & RCC_PLLCFGR_PLLM_Msk) >> RCC_PLLCFGR_PLLM_Pos) + 1U;
/* PLL N divider.*/
ndiv = (cfgr & RCC_PLLCFGR_PLLN_Msk) >> RCC_PLLCFGR_PLLN_Pos;
if (ndiv < 8) {
return true;
}
/* PLL VCO frequency.*/
vcoclk = (selclk / (halfreq_t)mdiv) * (halfreq_t)ndiv;
if((vcoclk < slp->pllvco_min) || (vcoclk > slp->pllvco_max)) {
return true;
}
/* PLL P output frequency.*/
pdiv = (cfgr & RCC_PLLCFGR_PLLPDIV_Msk) >> RCC_PLLCFGR_PLLPDIV_Pos;
if (pdiv == 1U) {
return true;
}
if (pdiv == 0U) {
if ((cfgr & RCC_PLLCFGR_PLLP) == 0U) {
pdiv = 7U;
}
else {
pdiv = 17U;
}
}
if ((cfgr & RCC_PLLCFGR_PLLPEN) != 0U) {
pclk = vcoclk / pdiv;
if((pclk < slp->pllp_min) || (pclk > slp->pllp_max)) {
return true;
}
}
/* PLL Q output frequency.*/
qdiv = 2U + (2U * (cfgr & RCC_PLLCFGR_PLLQ_Msk) >> RCC_PLLCFGR_PLLQ_Pos);
if ((cfgr & RCC_PLLCFGR_PLLQEN) != 0U) {
qclk = vcoclk / qdiv;
if((qclk < slp->pllq_min) || (qclk > slp->pllq_max)) {
return true;
}
}
/* PLL R output frequency.*/
rdiv = 2U + (2U * (cfgr & RCC_PLLCFGR_PLLR_Msk) >> RCC_PLLCFGR_PLLR_Pos);
if ((cfgr & RCC_PLLCFGR_PLLREN) != 0U) {
rclk = vcoclk / rdiv;
if((rclk < slp->pllr_min) || (rclk > slp->pllr_max)) {
return true;
}
}
*pclkp = pclk;
*qclkp = qclk;
*rclkp = rclk;
return false;
}
/**
* @brief Recalculates the clock tree frequencies.
*
* @param[in] ccp pointer to clock a @p halclkcfg_t structure
* @return The frequency calculation result.
* @retval false if the clock settings look valid
* @retval true if the clock settings look invalid
*
* @notapi
*/
static bool hal_lld_clock_check_tree(const halclkcfg_t *ccp) {
static const uint32_t hprediv[16] = {1U, 1U, 1U, 1U, 1U, 1U, 1U, 1U,
2U, 4U, 8U, 16U, 64U, 128U, 256U, 512U};
static const uint32_t pprediv[16] = {1U, 1U, 1U, 1U, 2U, 4U, 8U, 16U};
const system_limits_t *slp;
halfreq_t msiclk = 0U, hsi16clk = 0U, hseclk = 0U, pllselclk;
halfreq_t pllpclk = 0U, pllqclk = 0U, pllrclk = 0U;
halfreq_t pllsai1pclk = 0U, pllsai1qclk = 0U, pllsai1rclk = 0U;
halfreq_t pllsai2pclk = 0U, pllsai2qclk = 0U, pllsai2rclk = 0U;
halfreq_t sysclk, hclk, pclk1, pclk2, pclk1tim, pclk2tim, mcoclk;
uint32_t mcodiv, flashws;
/* System limits based on desired VOS settings.*/
if ((ccp->pwr_cr1 & PWR_CR1_VOS_Msk) == PWR_CR1_VOS_1) {
slp = &vos_range2;
}
else if ((ccp->pwr_cr1 & PWR_CR1_VOS_Msk) == PWR_CR1_VOS_0) {
slp = &vos_range1;
}
else {
return true;
}
/* MSI clock.*/
if ((ccp->rcc_cr & RCC_CR_MSION) != 0U) {
msiclk = STM32_MSICLK;
}
/* HSI16 clock.*/
if ((ccp->rcc_cr & RCC_CR_HSION) != 0U) {
hsi16clk = STM32_HSI16CLK;
}
/* HSE clock.*/
if ((ccp->rcc_cr & RCC_CR_HSEON) != 0U) {
hseclk = STM32_HSECLK;
}
/* PLL MUX clock.*/
switch (ccp->rcc_pllcfgr & RCC_PLLCFGR_PLLSRC_Msk) {
case RCC_PLLCFGR_PLLSRC_MSI:
pllselclk = msiclk;
break;
case RCC_PLLCFGR_PLLSRC_HSI:
pllselclk = hsi16clk;
break;
case RCC_PLLCFGR_PLLSRC_HSE:
pllselclk = hseclk;
break;
default:
pllselclk = 0U;
}
/* PLL outputs.*/
if ((ccp->rcc_cr & RCC_CR_PLLON) != 0U) {
if (hal_lld_check_pll(slp, ccp->rcc_pllcfgr, pllselclk,
&pllpclk, &pllqclk, &pllrclk)) {
return true;
}
}
/* PLLSAI1 outputs.*/
if ((ccp->rcc_cr & RCC_CR_PLLSAI1ON) != 0U) {
if (hal_lld_check_pll(slp, ccp->rcc_pllsai1cfgr, pllselclk,
&pllsai1pclk, &pllsai1qclk, &pllsai1rclk)) {
return true;
}
}
/* PLLSAI2 outputs.*/
if ((ccp->rcc_cr & RCC_CR_PLLSAI2ON) != 0U) {
if (hal_lld_check_pll(slp, ccp->rcc_pllsai2cfgr, pllselclk,
&pllsai2pclk, &pllsai2qclk, &pllsai2rclk)) {
return true;
}
}
/* SYSCLK frequency.*/
switch(ccp->rcc_cfgr & RCC_CFGR_SW_Msk) {
case RCC_CFGR_SW_MSI:
sysclk = msiclk;
break;
case RCC_CFGR_SW_HSI:
sysclk = hsi16clk;
break;
case RCC_CFGR_SW_HSE:
sysclk = hseclk;
break;
case RCC_CFGR_SW_PLL:
sysclk = pllrclk;
break;
default:
sysclk = 0U;
}
if ((ccp->pwr_cr5 & PWR_CR5_R1MODE) == 0U) {
if (sysclk > slp->sysclk_max_boost) {
return true;
}
}
else {
if (sysclk > slp->sysclk_max_noboost) {
return true;
}
}
/* HCLK frequency.*/
hclk = sysclk / hprediv[(ccp->rcc_cfgr & RCC_CFGR_HPRE_Msk) >> RCC_CFGR_HPRE_Pos];
/* PPRE1 frequency.*/
pclk1 = hclk / pprediv[(ccp->rcc_cfgr & RCC_CFGR_PPRE1_Msk) >> RCC_CFGR_PPRE1_Pos];
if ((ccp->rcc_cfgr & RCC_CFGR_PPRE1_Msk) < RCC_CFGR_PPRE1_DIV2) {
pclk1tim = pclk1;
}
else {
pclk1tim = pclk1 * 2U;
}
/* PPRE2 frequency.*/
pclk2 = hclk / pprediv[(ccp->rcc_cfgr & RCC_CFGR_PPRE2_Msk) >> RCC_CFGR_PPRE2_Pos];
if ((ccp->rcc_cfgr & RCC_CFGR_PPRE1_Msk) < RCC_CFGR_PPRE2_DIV2) {
pclk2tim = pclk2;
}
else {
pclk2tim = pclk2 * 2U;
}
/* MCO clock.*/
switch(ccp->rcc_cfgr & RCC_CFGR_MCOSEL_Msk) {
case STM32_MCOSEL_NOCLOCK:
mcoclk = 0U;
break;
case STM32_MCOSEL_SYSCLK:
mcoclk = sysclk;
break;
case STM32_MCOSEL_MSI:
mcoclk = hsi16clk;
break;
case STM32_MCOSEL_HSI16:
mcoclk = hsi16clk;
break;
case STM32_MCOSEL_HSE:
mcoclk = hseclk;
break;
case STM32_MCOSEL_PLLRCLK:
mcoclk = pllrclk;
break;
case STM32_MCOSEL_LSI:
mcoclk = STM32_LSICLK;
break;
case STM32_MCOSEL_LSE:
mcoclk = STM32_LSECLK;
break;
case STM32_MCOSEL_HSI48:
mcoclk = STM32_HSI48CLK;
break;
default:
mcoclk = 0U;
}
mcodiv = 1U << ((ccp->rcc_cfgr & RCC_CFGR_MCOPRE_Msk) >> RCC_CFGR_MCOPRE_Pos);
if (mcodiv > 16U) {
return true;
}
mcoclk /= mcodiv;
/* Flash settings.*/
flashws = ((ccp->flash_acr & FLASH_ACR_LATENCY_Msk) >> FLASH_ACR_LATENCY_Pos);
if (flashws >= STM32_WS_THRESHOLDS) {
return true;
}
if (hclk > slp->flash_thresholds[flashws]) {
return true;
}
/* Writing out results.*/
clock_points[CLK_SYSCLK] = sysclk;
clock_points[CLK_PLLPCLK] = pllpclk;
clock_points[CLK_PLLQCLK] = pllqclk;
clock_points[CLK_PLLRCLK] = pllrclk;
clock_points[CLK_PLLSAI1PCLK] = pllsai1pclk;
clock_points[CLK_PLLSAI1QCLK] = pllsai1qclk;
clock_points[CLK_PLLSAI1RCLK] = pllsai1rclk;
clock_points[CLK_PLLSAI2PCLK] = pllsai2pclk;
clock_points[CLK_PLLSAI2QCLK] = pllsai2qclk;
clock_points[CLK_PLLSAI2RCLK] = pllsai2rclk;
clock_points[CLK_HCLK] = hclk;
clock_points[CLK_PCLK1] = pclk1;
clock_points[CLK_PCLK1TIM] = pclk1tim;
clock_points[CLK_PCLK2] = pclk2;
clock_points[CLK_PCLK2TIM] = pclk2tim;
clock_points[CLK_MCO] = mcoclk;
return false;
}
/**
* @brief Switches to a different clock configuration.
*
* @param[in] ccp pointer to clock a @p halclkcfg_t structure
* @return The clock switch result.
* @retval false if the clock switch succeeded
* @retval true if the clock switch failed
*
* @notapi
*/
bool hal_lld_clock_raw_switch(const halclkcfg_t *ccp) {
/* Restoring default PWR settings related clocks and sleep modes.*/
PWR->CR1 = PWR_CR1_VOS_0;
/* Waiting for all regulator status bits to be cleared, this means that
power levels are stable.*/
while ((PWR->SR2 & (PWR_SR2_VOSF | PWR_SR2_REGLPF)) != 0U) {
/* Waiting for the regulator to be ready.*/
}
/* If the clock source is not MSI then we switch to MSI and reset some
other relevant registers to their default value.*/
if ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_MSI) {
/* Making sure MSI is activated and in use.*/
msi_reset();
/* Resetting flash ACR settings to the default value.*/
FLASH->ACR = 0x00000600U;
/* Resetting all other clock sources and PLLs.*/
RCC->CRRCR = 0U;
RCC->CR = 0x00000063U;
while ((RCC->CR & (RCC_CR_HSIRDY | RCC_CR_HSERDY)) != 0U) {
/* Waiting for oscillators to shut down.*/
}
/* Disabling boost mode.*/
PWR->CR5 = PWR_CR5_R1MODE;
}
/* HSI16 setup, if required, before starting the PLL.*/
if ((ccp->rcc_cr & RCC_CR_HSION) != 0U) {
hsi16_enable();
}
/* HSE setup, if required, before starting the PLL.*/
if ((ccp->rcc_cr & RCC_CR_HSEON) != 0U) {
hse_enable();
}
/* HSI48 setup, if required, before starting the PLL.*/
if ((ccp->rcc_crrcr & RCC_CRRCR_HSI48ON) != 0U) {
hsi48_enable();
}
/* PLLs setup.*/
RCC->PLLCFGR = ccp->rcc_pllcfgr;
RCC->PLLSAI1CFGR = ccp->rcc_pllsai1cfgr;
RCC->PLLSAI2CFGR = ccp->rcc_pllsai2cfgr;
/* PLLs enabled if specified.*/
RCC->CR = ccp->rcc_cr;
/* PLLs activation polling if required.*/
while (true) {
if (((ccp->rcc_cr & RCC_CR_PLLON) != 0U) && pll_not_locked()) {
continue;
}
if (((ccp->rcc_cr & RCC_CR_PLLSAI1ON) != 0U) && pllsai1_not_locked()) {
continue;
}
if (((ccp->rcc_cr & RCC_CR_PLLSAI2ON) != 0U) && pllsai2_not_locked()) {
continue;
}
break;
}
/* MCO and bus dividers first.*/
RCC->CFGR = (RCC->CFGR & RCC_CFGR_SW_Msk) | (ccp->rcc_cfgr & ~RCC_CFGR_SW_Msk);
/* Final flash ACR settings.*/
FLASH->ACR = ccp->flash_acr;
/* Final PWR modes.*/
PWR->CR1 = ccp->pwr_cr1;
PWR->CR2 = ccp->pwr_cr2;
PWR->CR3 = ccp->pwr_cr3;
PWR->CR4 = ccp->pwr_cr4;
PWR->CR5 = ccp->pwr_cr5;
/* Waiting for the correct regulator state.*/
if ((ccp->pwr_cr1 & PWR_CR1_LPR) == 0U) {
/* Main mode selected.*/
while ((PWR->SR2 & PWR_SR2_REGLPF) != 0U) {
/* Waiting for the regulator to be in main mode.*/
}
}
else {
/* Low power mode selected.*/
while ((PWR->SR2 & PWR_SR2_REGLPF) == 0U) {
/* Waiting for the regulator to be in low power mode.*/
}
}
/* Switching to the final clock source.*/
RCC->CFGR = (RCC->CFGR & ~RCC_CFGR_SW_Msk) | (ccp->rcc_cfgr & RCC_CFGR_SW_Msk);
while ((RCC->CFGR & RCC_CFGR_SWS) != ((ccp->rcc_cfgr & RCC_CFGR_SW_Msk) << RCC_CFGR_SWS_Pos)) {
/* Waiting for clock switch.*/
}
return false;
}
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/ /*===========================================================================*/
/* Driver interrupt handlers. */ /* Driver interrupt handlers. */
/*===========================================================================*/ /*===========================================================================*/
@ -75,6 +633,48 @@ void hal_lld_init(void) {
irqInit(); irqInit();
} }
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
void stm32_clock_init(void) {
#if !STM32_NO_INIT
/* Reset of all peripherals.
Note, GPIOs are not reset because initialized before this point in
board files.*/
rccResetAHB1(~0);
rccResetAHB2(~STM32_GPIO_EN_MASK);
rccResetAHB3(~0);
rccResetAPB1R1(~0);
rccResetAPB1R2(~0);
rccResetAPB2(~0);
/* SYSCFG clock enabled here because it is a multi-functional unit shared
among multiple drivers.*/
rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, false);
/* PWR clock enabled.*/
rccEnablePWRInterface(false);
/* Backup domain made accessible.*/
PWR->CR1 |= PWR_CR1_DBP;
/* Backup domain reset.*/
bd_reset();
/* Static clocks setup.*/
lse_init();
lsi_init();
/* Selecting the default clock/power/flash configuration.*/
if (hal_lld_clock_raw_switch(&hal_clkcfg_default)) {
osalSysHalt("clkswc");
}
/* Backup domain initializations.*/
bd_init();
#endif /* STM32_NO_INIT */
}
#else /* !defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/** /**
* @brief STM32L4xx clocks and PLL initialization. * @brief STM32L4xx clocks and PLL initialization.
* @note All the involved constants come from the file @p board.h. * @note All the involved constants come from the file @p board.h.
@ -111,22 +711,11 @@ void stm32_clock_init(void) {
while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */ while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */
; /* stable. */ ; /* stable. */
/* Programmable voltage detector enable.*/ /* Additional PWR configurations.*/
#if STM32_PVD_ENABLE PWR->CR2 = STM32_PWR_CR2;
PWR->CR2 = PWR_CR2_PVDE | (STM32_PLS & STM32_PLS_MASK); PWR->CR3 = STM32_PWR_CR3;
#else PWR->CR4 = STM32_PWR_CR4;
PWR->CR2 = 0; PWR->CR5 = STM32_CR5BITS;
#endif /* STM32_PVD_ENABLE */
/* Enabling independent VDDUSB.*/
#if HAL_USE_USB
PWR->CR2 |= PWR_CR2_USV;
#endif /* HAL_USE_USB */
/* Enabling independent VDDIO2 required by GPIOG.*/
#if STM32_HAS_GPIOG
PWR->CR2 |= PWR_CR2_IOSV;
#endif /* STM32_HAS_GPIOG */
/* MSI clock reset.*/ /* MSI clock reset.*/
msi_reset(); msi_reset();
@ -205,5 +794,50 @@ void stm32_clock_init(void) {
} }
#endif /* STM32_NO_INIT */ #endif /* STM32_NO_INIT */
} }
#endif /* !defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
/**
* @brief Switches to a different clock configuration
*
* @param[in] ccp pointer to clock a @p halclkcfg_t structure
* @return The clock switch result.
* @retval false if the clock switch succeeded
* @retval true if the clock switch failed
*
* @notapi
*/
bool hal_lld_clock_switch_mode(const halclkcfg_t *ccp) {
if (hal_lld_clock_check_tree(ccp)) {
return true;
}
if (hal_lld_clock_raw_switch(ccp)) {
return true;
}
/* Updating the CMSIS variable.*/
SystemCoreClock = hal_lld_get_clock_point(CLK_HCLK);
return false;
}
/**
* @brief Returns the frequency of a clock point in Hz.
*
* @param[in] clkpt clock point to be returned
* @return The clock point frequency in Hz or zero if the
* frequency is unknown.
*
* @notapi
*/
halfreq_t hal_lld_get_clock_point(halclkpt_t clkpt) {
osalDbgAssert(clkpt < CLK_ARRAY_SIZE, "invalid clock point");
return clock_points[clkpt];
}
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/** @} */ /** @} */

View File

@ -66,6 +66,29 @@
#endif #endif
/** @} */ /** @} */
/**
* @name Clock points names
* @{
*/
#define CLK_SYSCLK 0U
#define CLK_PLLPCLK 1U
#define CLK_PLLQCLK 2U
#define CLK_PLLRCLK 3U
#define CLK_PLLSAI1PCLK 4U
#define CLK_PLLSAI1QCLK 5U
#define CLK_PLLSAI1RCLK 6U
#define CLK_PLLSAI2PCLK 7U
#define CLK_PLLSAI2QCLK 8U
#define CLK_PLLSAI2RCLK 9U
#define CLK_HCLK 10U
#define CLK_PCLK1 11U
#define CLK_PCLK1TIM 12U
#define CLK_PCLK2 13U
#define CLK_PCLK2TIM 14U
#define CLK_MCO 15U
#define CLK_ARRAY_SIZE 16U
/** @} */
/** /**
* @name PWR_CR1 register bits definitions * @name PWR_CR1 register bits definitions
* @{ * @{
@ -75,21 +98,6 @@
#define STM32_VOS_RANGE2 (2 << 9) /**< Core voltage 1.0 Volts. */ #define STM32_VOS_RANGE2 (2 << 9) /**< Core voltage 1.0 Volts. */
/** @} */ /** @} */
/**
* @name PWR_CR2 register bits definitions
* @{
*/
#define STM32_PLS_MASK (7 << 1) /**< PLS bits mask. */
#define STM32_PLS_LEV0 (0 << 1) /**< PVD level 0. */
#define STM32_PLS_LEV1 (1 << 1) /**< PVD level 1. */
#define STM32_PLS_LEV2 (2 << 1) /**< PVD level 2. */
#define STM32_PLS_LEV3 (3 << 1) /**< PVD level 3. */
#define STM32_PLS_LEV4 (4 << 1) /**< PVD level 4. */
#define STM32_PLS_LEV5 (5 << 1) /**< PVD level 5. */
#define STM32_PLS_LEV6 (6 << 1) /**< PVD level 6. */
#define STM32_PLS_EXT (7 << 1) /**< PVD level 7. */
/** @} */
/** /**
* @name RCC_CFGR register bits definitions * @name RCC_CFGR register bits definitions
* @{ * @{
@ -110,7 +118,7 @@
#define STM32_MCOSEL_MSI (2 << 24) /**< MSI clock on MCO pin. */ #define STM32_MCOSEL_MSI (2 << 24) /**< MSI clock on MCO pin. */
#define STM32_MCOSEL_HSI16 (3 << 24) /**< HSI16 clock on MCO pin. */ #define STM32_MCOSEL_HSI16 (3 << 24) /**< HSI16 clock on MCO pin. */
#define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */ #define STM32_MCOSEL_HSE (4 << 24) /**< HSE clock on MCO pin. */
#define STM32_MCOSEL_PLL (5 << 24) /**< PLL clock on MCO pin. */ #define STM32_MCOSEL_PLLRCLK (5 << 24) /**< PLLR clock on MCO pin. */
#define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */ #define STM32_MCOSEL_LSI (6 << 24) /**< LSI clock on MCO pin. */
#define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */ #define STM32_MCOSEL_LSE (7 << 24) /**< LSE clock on MCO pin. */
#define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */ #define STM32_MCOSEL_HSI48 (8 << 24) /**< HSI48 clock on MCO pin. */
@ -300,6 +308,13 @@
#define STM32_NO_INIT FALSE #define STM32_NO_INIT FALSE
#endif #endif
/**
* @brief Enables the dynamic clock handling.
*/
#if !defined(STM32_CLOCK_DYNAMIC) || defined(__DOXYGEN__)
#define STM32_CLOCK_DYNAMIC FALSE
#endif
/** /**
* @brief Core voltage selection. * @brief Core voltage selection.
* @note This setting affects all the performance and clock related * @note This setting affects all the performance and clock related
@ -311,17 +326,24 @@
#endif #endif
/** /**
* @brief Enables or disables the programmable voltage detector. * @brief PWR CR2 register initialization value.
*/ */
#if !defined(STM32_PVD_ENABLE) || defined(__DOXYGEN__) #if !defined(STM32_PWR_CR2) || defined(__DOXYGEN__)
#define STM32_PVD_ENABLE FALSE #define STM32_PWR_CR2 (PWR_CR2_PLS_LEV0 | PWR_CR2_IOSV)
#endif #endif
/** /**
* @brief Sets voltage level for programmable voltage detector. * @brief PWR CR3 register initialization value.
*/ */
#if !defined(STM32_PLS) || defined(__DOXYGEN__) #if !defined(STM32_PWR_CR3) || defined(__DOXYGEN__)
#define STM32_PLS STM32_PLS_LEV0 #define STM32_PWR_CR3 (PWR_CR3_EIWF)
#endif
/**
* @brief PWR CR4 register initialization value.
*/
#if !defined(STM32_PWR_CR4) || defined(__DOXYGEN__)
#define STM32_PWR_CR4 (0U)
#endif #endif
/** /**
@ -773,6 +795,11 @@
/* Derived constants and error checks. */ /* Derived constants and error checks. */
/*===========================================================================*/ /*===========================================================================*/
/* Clock handling mode selection.*/
#if STM32_CLOCK_DYNAMIC == TRUE
#define HAL_LLD_USE_CLOCK_MANAGEMENT
#endif
/* /*
* Configuration-related checks. * Configuration-related checks.
*/ */
@ -800,171 +827,142 @@
#endif #endif
/**
* @name System Limits for VOS range 1
* @{
*/
#define STM32_VOS1_SYSCLK_MAX 120000000
#define STM32_VOS1_SYSCLK_MAX_NOBOOST 80000000
#define STM32_VOS1_HSECLK_MAX 48000000
#define STM32_VOS1_HSECLK_BYP_MAX 48000000
#define STM32_VOS1_HSECLK_MIN 8000000
#define STM32_VOS1_HSECLK_BYP_MIN 8000000
#define STM32_VOS1_LSECLK_MAX 32768
#define STM32_VOS1_LSECLK_BYP_MAX 1000000
#define STM32_VOS1_LSECLK_MIN 32768
#define STM32_VOS1_LSECLK_BYP_MIN 32768
#define STM32_VOS1_PLLIN_MAX 16000000
#define STM32_VOS1_PLLIN_MIN 2660000
#define STM32_VOS1_PLLVCO_MAX 344000000
#define STM32_VOS1_PLLVCO_MIN 64000000
#define STM32_VOS1_PLLP_MAX 120000000
#define STM32_VOS1_PLLP_MIN 2064500
#define STM32_VOS1_PLLQ_MAX 120000000
#define STM32_VOS1_PLLQ_MIN 8000000
#define STM32_VOS1_PLLR_MAX 120000000
#define STM32_VOS1_PLLR_MIN 8000000
#define STM32_VOS1_PCLK1_MAX 120000000
#define STM32_VOS1_PCLK2_MAX 120000000
#define STM32_VOS1_ADCCLK_MAX 80000000
#define STM32_VOS1_0WS_THRESHOLD 20000000
#define STM32_VOS1_1WS_THRESHOLD 40000000
#define STM32_VOS1_2WS_THRESHOLD 60000000
#define STM32_VOS1_3WS_THRESHOLD 80000000
#define STM32_VOS1_4WS_THRESHOLD 100000000
#define STM32_VOS1_5WS_THRESHOLD 120000000
/** @} */
/**
* @name System Limits for VOS range 2
* @{
*/
#define STM32_VOS2_SYSCLK_MAX 0
#define STM32_VOS2_SYSCLK_MAX_NOBOOST 26000000
#define STM32_VOS2_HSECLK_MAX 26000000
#define STM32_VOS2_HSECLK_BYP_MAX 26000000
#define STM32_VOS2_HSECLK_MIN 8000000
#define STM32_VOS2_HSECLK_BYP_MIN 8000000
#define STM32_VOS2_LSECLK_MAX 32768
#define STM32_VOS2_LSECLK_BYP_MAX 1000000
#define STM32_VOS2_LSECLK_MIN 32768
#define STM32_VOS2_LSECLK_BYP_MIN 32768
#define STM32_VOS2_PLLIN_MAX 16000000
#define STM32_VOS2_PLLIN_MIN 2660000
#define STM32_VOS2_PLLVCO_MAX 128000000
#define STM32_VOS2_PLLVCO_MIN 64000000
#define STM32_VOS2_PLLP_MAX 26000000
#define STM32_VOS2_PLLP_MIN 2064500
#define STM32_VOS2_PLLQ_MAX 26000000
#define STM32_VOS2_PLLQ_MIN 8000000
#define STM32_VOS2_PLLR_MAX 26000000
#define STM32_VOS2_PLLR_MIN 8000000
#define STM32_VOS2_PCLK1_MAX 26000000
#define STM32_VOS2_PCLK2_MAX 26000000
#define STM32_VOS2_ADCCLK_MAX 26000000
#define STM32_VOS2_0WS_THRESHOLD 8000000
#define STM32_VOS2_1WS_THRESHOLD 16000000
#define STM32_VOS2_2WS_THRESHOLD 26000000
#define STM32_VOS2_3WS_THRESHOLD 0
#define STM32_VOS2_4WS_THRESHOLD 0
#define STM32_VOS2_5WS_THRESHOLD 0
/** @} */
/* Voltage related limits.*/ /* Voltage related limits.*/
#if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__) #if (STM32_VOS == STM32_VOS_RANGE1) || defined(__DOXYGEN__)
/** #define STM32_SYSCLK_MAX STM32_VOS1_SYSCLK_MAX
* @name System Limits #define STM32_SYSCLK_MAX_NOBOOST STM32_VOS1_SYSCLK_MAX_NOBOOST
* @{ #define STM32_HSECLK_MAX STM32_VOS1_HSECLK_MAX
*/ #define STM32_HSECLK_BYP_MAX STM32_VOS1_HSECLK_BYP_MAX
/** #define STM32_HSECLK_MIN STM32_VOS1_HSECLK_MIN
* @brief Maximum SYSCLK clock frequency in boost mode. #define STM32_HSECLK_BYP_MIN STM32_VOS1_HSECLK_BYP_MIN
*/ #define STM32_LSECLK_MAX STM32_VOS1_LSECLK_MAX
#define STM32_SYSCLK_MAX 120000000 #define STM32_LSECLK_BYP_MAX STM32_VOS1_LSECLK_BYP_MAX
#define STM32_LSECLK_MIN STM32_VOS1_LSECLK_MIN
#define STM32_LSECLK_BYP_MIN STM32_VOS1_LSECLK_BYP_MIN
#define STM32_PLLIN_MAX STM32_VOS1_PLLIN_MAX
#define STM32_PLLIN_MIN STM32_VOS1_PLLIN_MIN
#define STM32_PLLVCO_MAX STM32_VOS1_PLLVCO_MAX
#define STM32_PLLVCO_MIN STM32_VOS1_PLLVCO_MIN
#define STM32_PLLP_MAX STM32_VOS1_PLLP_MAX
#define STM32_PLLP_MIN STM32_VOS1_PLLP_MIN
#define STM32_PLLQ_MAX STM32_VOS1_PLLQ_MAX
#define STM32_PLLQ_MIN STM32_VOS1_PLLQ_MIN
#define STM32_PLLR_MAX STM32_VOS1_PLLR_MAX
#define STM32_PLLR_MIN STM32_VOS1_PLLR_MIN
#define STM32_PCLK1_MAX STM32_VOS1_PCLK1_MAX
#define STM32_PCLK2_MAX STM32_VOS1_PCLK2_MAX
#define STM32_ADCCLK_MAX STM32_VOS1_ADCCLK_MAX
/** #define STM32_0WS_THRESHOLD STM32_VOS1_0WS_THRESHOLD
* @brief Maximum SYSCLK clock frequency in normal mode. #define STM32_1WS_THRESHOLD STM32_VOS1_1WS_THRESHOLD
*/ #define STM32_2WS_THRESHOLD STM32_VOS1_2WS_THRESHOLD
#define STM32_SYSCLK_NOBOOST_MAX 80000000 #define STM32_3WS_THRESHOLD STM32_VOS1_3WS_THRESHOLD
#define STM32_4WS_THRESHOLD STM32_VOS1_4WS_THRESHOLD
/** #define STM32_5WS_THRESHOLD STM32_VOS1_5WS_THRESHOLD
* @brief Maximum HSE clock frequency at current voltage setting.
*/
#define STM32_HSECLK_MAX 48000000
/**
* @brief Maximum HSE clock frequency using an external source.
*/
#define STM32_HSECLK_BYP_MAX 48000000
/**
* @brief Minimum HSE clock frequency.
*/
#define STM32_HSECLK_MIN 8000000
/**
* @brief Minimum HSE clock frequency using an external source.
*/
#define STM32_HSECLK_BYP_MIN 8000000
/**
* @brief Maximum LSE clock frequency.
*/
#define STM32_LSECLK_MAX 32768
/**
* @brief Maximum LSE clock frequency.
*/
#define STM32_LSECLK_BYP_MAX 1000000
/**
* @brief Minimum LSE clock frequency.
*/
#define STM32_LSECLK_MIN 32768
/**
* @brief Minimum LSE clock frequency.
*/
#define STM32_LSECLK_BYP_MIN 32768
/**
* @brief Maximum PLLs input clock frequency.
*/
#define STM32_PLLIN_MAX 16000000
/**
* @brief Minimum PLLs input clock frequency.
*/
#define STM32_PLLIN_MIN 2660000
/**
* @brief Maximum VCO clock frequency at current voltage setting.
*/
#define STM32_PLLVCO_MAX 344000000
/**
* @brief Minimum VCO clock frequency at current voltage setting.
*/
#define STM32_PLLVCO_MIN 64000000
/**
* @brief Maximum PLL-P output clock frequency.
*/
#define STM32_PLLP_MAX 120000000
/**
* @brief Minimum PLL-P output clock frequency.
*/
#define STM32_PLLP_MIN 2064500
/**
* @brief Maximum PLL-Q output clock frequency.
*/
#define STM32_PLLQ_MAX 120000000
/**
* @brief Minimum PLL-Q output clock frequency.
*/
#define STM32_PLLQ_MIN 8000000
/**
* @brief Maximum PLL-R output clock frequency.
*/
#define STM32_PLLR_MAX 120000000
/**
* @brief Minimum PLL-R output clock frequency.
*/
#define STM32_PLLR_MIN 8000000
/**
* @brief Maximum APB1 clock frequency.
*/
#define STM32_PCLK1_MAX 120000000
/**
* @brief Maximum APB2 clock frequency.
*/
#define STM32_PCLK2_MAX 120000000
/**
* @brief Maximum ADC clock frequency.
*/
#define STM32_ADCCLK_MAX 80000000
/** @} */
/**
* @name Flash Wait states
* @{
*/
#define STM32_0WS_THRESHOLD 20000000
#define STM32_1WS_THRESHOLD 40000000
#define STM32_2WS_THRESHOLD 60000000
#define STM32_3WS_THRESHOLD 80000000
#define STM32_4WS_THRESHOLD 100000000
#define STM32_5WS_THRESHOLD 120000000
/** @} */
#elif STM32_VOS == STM32_VOS_RANGE2 #elif STM32_VOS == STM32_VOS_RANGE2
#define STM32_SYSCLK_MAX 26000000 #define STM32_SYSCLK_MAX STM32_VOS2_SYSCLK_MAX
#define STM32_SYSCLK_NOBOOST_MAX 26000000 #define STM32_SYSCLK_MAX_NOBOOST STM32_VOS2_SYSCLK_MAX_NOBOOST
#define STM32_HSECLK_MAX 26000000 #define STM32_HSECLK_MAX STM32_VOS2_HSECLK_MAX
#define STM32_HSECLK_BYP_MAX 26000000 #define STM32_HSECLK_BYP_MAX STM32_VOS2_HSECLK_BYP_MAX
#define STM32_HSECLK_MIN 8000000 #define STM32_HSECLK_MIN STM32_VOS2_HSECLK_MIN
#define STM32_HSECLK_BYP_MIN 8000000 #define STM32_HSECLK_BYP_MIN STM32_VOS2_HSECLK_BYP_MIN
#define STM32_LSECLK_MAX 32768 #define STM32_LSECLK_MAX STM32_VOS2_LSECLK_MAX
#define STM32_LSECLK_BYP_MAX 1000000 #define STM32_LSECLK_BYP_MAX STM32_VOS2_LSECLK_BYP_MAX
#define STM32_LSECLK_MIN 32768 #define STM32_LSECLK_MIN STM32_VOS2_LSECLK_MIN
#define STM32_LSECLK_BYP_MIN 32768 #define STM32_LSECLK_BYP_MIN STM32_VOS2_LSECLK_BYP_MIN
#define STM32_PLLIN_MAX 16000000 #define STM32_PLLIN_MAX STM32_VOS2_PLLIN_MAX
#define STM32_PLLIN_MIN 2660000 #define STM32_PLLIN_MIN STM32_VOS2_PLLIN_MIN
#define STM32_PLLVCO_MAX 128000000 #define STM32_PLLVCO_MAX STM32_VOS2_PLLVCO_MAX
#define STM32_PLLVCO_MIN 64000000 #define STM32_PLLVCO_MIN STM32_VOS2_PLLVCO_MIN
#define STM32_PLLP_MAX 26000000 #define STM32_PLLP_MAX STM32_VOS2_PLLP_MAX
#define STM32_PLLP_MIN 2064500 #define STM32_PLLP_MIN STM32_VOS2_PLLP_MIN
#define STM32_PLLQ_MAX 26000000 #define STM32_PLLQ_MAX STM32_VOS2_PLLQ_MAX
#define STM32_PLLQ_MIN 8000000 #define STM32_PLLQ_MIN STM32_VOS2_PLLQ_MIN
#define STM32_PLLR_MAX 26000000 #define STM32_PLLR_MAX STM32_VOS2_PLLR_MAX
#define STM32_PLLR_MIN 8000000 #define STM32_PLLR_MIN STM32_VOS2_PLLR_MIN
#define STM32_PCLK1_MAX 26000000 #define STM32_PCLK1_MAX STM32_VOS2_PCLK1_MAX
#define STM32_PCLK2_MAX 26000000 #define STM32_PCLK2_MAX STM32_VOS2_PCLK2_MAX
#define STM32_ADCCLK_MAX 26000000 #define STM32_ADCCLK_MAX STM32_VOS2_ADCCLK_MAX
#define STM32_0WS_THRESHOLD 8000000 #define STM32_0WS_THRESHOLD STM32_VOS2_0WS_THRESHOLD
#define STM32_1WS_THRESHOLD 16000000 #define STM32_1WS_THRESHOLD STM32_VOS2_1WS_THRESHOLD
#define STM32_2WS_THRESHOLD 26000000 #define STM32_2WS_THRESHOLD STM32_VOS2_2WS_THRESHOLD
#define STM32_3WS_THRESHOLD 0 #define STM32_3WS_THRESHOLD STM32_VOS2_3WS_THRESHOLD
#define STM32_4WS_THRESHOLD 0 #define STM32_4WS_THRESHOLD STM32_VOS2_4WS_THRESHOLD
#define STM32_5WS_THRESHOLD 0 #define STM32_5WS_THRESHOLD STM32_VOS2_5WS_THRESHOLD
#else #else
#error "invalid STM32_VOS value specified" #error "invalid STM32_VOS value specified"
@ -996,7 +994,7 @@
L4 devices.*/ L4 devices.*/
#if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \ #if (STM32_MCOSEL == STM32_MCOSEL_HSI16) || \
((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ ((STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) && \
(STM32_PLLSRC == STM32_PLLSRC_HSI16)) (STM32_PLLSRC == STM32_PLLSRC_HSI16))
#error "HSI16 not enabled, required by STM32_MCOSEL" #error "HSI16 not enabled, required by STM32_MCOSEL"
#endif #endif
@ -1085,7 +1083,7 @@
#endif #endif
#if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \ #if (STM32_MCOSEL == STM32_MCOSEL_HSE) || \
((STM32_MCOSEL == STM32_MCOSEL_PLL) && \ ((STM32_MCOSEL == STM32_MCOSEL_PLLRCLK) && \
(STM32_PLLSRC == STM32_PLLSRC_HSE)) (STM32_PLLSRC == STM32_PLLSRC_HSE))
#error "HSE not enabled, required by STM32_MCOSEL" #error "HSE not enabled, required by STM32_MCOSEL"
#endif #endif
@ -1436,10 +1434,10 @@
* @brief USART1 clock frequency. * @brief USART1 clock frequency.
*/ */
#if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__) #if (STM32_USART1SEL == STM32_USART1SEL_PCLK2) || defined(__DOXYGEN__)
#define STM32_USART1CLK STM32_PCLK2 #define STM32_USART1CLK hal_lld_get_clock_point(CLK_PCLK2)
#elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK #elif STM32_USART1SEL == STM32_USART1SEL_SYSCLK
#define STM32_USART1CLK STM32_SYSCLK #define STM32_USART1CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_USART1SEL == STM32_USART1SEL_HSI16 #elif STM32_USART1SEL == STM32_USART1SEL_HSI16
#define STM32_USART1CLK STM32_HSI16CLK #define STM32_USART1CLK STM32_HSI16CLK
@ -1455,10 +1453,10 @@
* @brief USART2 clock frequency. * @brief USART2 clock frequency.
*/ */
#if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_USART2SEL == STM32_USART2SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_USART2CLK STM32_PCLK1 #define STM32_USART2CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK #elif STM32_USART2SEL == STM32_USART2SEL_SYSCLK
#define STM32_USART2CLK STM32_SYSCLK #define STM32_USART2CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_USART2SEL == STM32_USART2SEL_HSI16 #elif STM32_USART2SEL == STM32_USART2SEL_HSI16
#define STM32_USART2CLK STM32_HSI16CLK #define STM32_USART2CLK STM32_HSI16CLK
@ -1474,10 +1472,10 @@
* @brief USART3 clock frequency. * @brief USART3 clock frequency.
*/ */
#if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_USART3SEL == STM32_USART3SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_USART3CLK STM32_PCLK1 #define STM32_USART3CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK #elif STM32_USART3SEL == STM32_USART3SEL_SYSCLK
#define STM32_USART3CLK STM32_SYSCLK #define STM32_USART3CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_USART3SEL == STM32_USART3SEL_HSI16 #elif STM32_USART3SEL == STM32_USART3SEL_HSI16
#define STM32_USART3CLK STM32_HSI16CLK #define STM32_USART3CLK STM32_HSI16CLK
@ -1493,10 +1491,10 @@
* @brief UART4 clock frequency. * @brief UART4 clock frequency.
*/ */
#if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_UART4SEL == STM32_UART4SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_UART4CLK STM32_PCLK1 #define STM32_UART4CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK #elif STM32_UART4SEL == STM32_UART4SEL_SYSCLK
#define STM32_UART4CLK STM32_SYSCLK #define STM32_UART4CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_UART4SEL == STM32_UART4SEL_HSI16 #elif STM32_UART4SEL == STM32_UART4SEL_HSI16
#define STM32_UART4CLK STM32_HSI16CLK #define STM32_UART4CLK STM32_HSI16CLK
@ -1512,10 +1510,10 @@
* @brief UART5 clock frequency. * @brief UART5 clock frequency.
*/ */
#if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_UART5SEL == STM32_UART5SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_UART5CLK STM32_PCLK1 #define STM32_UART5CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK #elif STM32_UART5SEL == STM32_UART5SEL_SYSCLK
#define STM32_UART5CLK STM32_SYSCLK #define STM32_UART5CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_UART5SEL == STM32_UART5SEL_HSI16 #elif STM32_UART5SEL == STM32_UART5SEL_HSI16
#define STM32_UART5CLK STM32_HSI16CLK #define STM32_UART5CLK STM32_HSI16CLK
@ -1531,10 +1529,10 @@
* @brief LPUART1 clock frequency. * @brief LPUART1 clock frequency.
*/ */
#if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_LPUART1SEL == STM32_LPUART1SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_LPUART1CLK STM32_PCLK1 #define STM32_LPUART1CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK #elif STM32_LPUART1SEL == STM32_LPUART1SEL_SYSCLK
#define STM32_LPUART1CLK STM32_SYSCLK #define STM32_LPUART1CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16 #elif STM32_LPUART1SEL == STM32_LPUART1SEL_HSI16
#define STM32_LPUART1CLK STM32_HSI16CLK #define STM32_LPUART1CLK STM32_HSI16CLK
@ -1550,10 +1548,10 @@
* @brief I2C1 clock frequency. * @brief I2C1 clock frequency.
*/ */
#if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_I2C1SEL == STM32_I2C1SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_I2C1CLK STM32_PCLK1 #define STM32_I2C1CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK #elif STM32_I2C1SEL == STM32_I2C1SEL_SYSCLK
#define STM32_I2C1CLK STM32_SYSCLK #define STM32_I2C1CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16 #elif STM32_I2C1SEL == STM32_I2C1SEL_HSI16
#define STM32_I2C1CLK STM32_HSI16CLK #define STM32_I2C1CLK STM32_HSI16CLK
@ -1566,10 +1564,10 @@
* @brief I2C2 clock frequency. * @brief I2C2 clock frequency.
*/ */
#if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_I2C2SEL == STM32_I2C2SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_I2C2CLK STM32_PCLK1 #define STM32_I2C2CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK #elif STM32_I2C2SEL == STM32_I2C2SEL_SYSCLK
#define STM32_I2C2CLK STM32_SYSCLK #define STM32_I2C2CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16 #elif STM32_I2C2SEL == STM32_I2C2SEL_HSI16
#define STM32_I2C2CLK STM32_HSI16CLK #define STM32_I2C2CLK STM32_HSI16CLK
@ -1582,10 +1580,10 @@
* @brief I2C3 clock frequency. * @brief I2C3 clock frequency.
*/ */
#if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_I2C3SEL == STM32_I2C3SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_I2C3CLK STM32_PCLK1 #define STM32_I2C3CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK #elif STM32_I2C3SEL == STM32_I2C3SEL_SYSCLK
#define STM32_I2C3CLK STM32_SYSCLK #define STM32_I2C3CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16 #elif STM32_I2C3SEL == STM32_I2C3SEL_HSI16
#define STM32_I2C3CLK STM32_HSI16CLK #define STM32_I2C3CLK STM32_HSI16CLK
@ -1598,10 +1596,10 @@
* @brief I2C4 clock frequency. * @brief I2C4 clock frequency.
*/ */
#if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_I2C4SEL == STM32_I2C4SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_I2C4CLK STM32_PCLK1 #define STM32_I2C4CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK #elif STM32_I2C4SEL == STM32_I2C4SEL_SYSCLK
#define STM32_I2C4CLK STM32_SYSCLK #define STM32_I2C4CLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16 #elif STM32_I2C4SEL == STM32_I2C4SEL_HSI16
#define STM32_I2C4CLK STM32_HSI16CLK #define STM32_I2C4CLK STM32_HSI16CLK
@ -1614,7 +1612,7 @@
* @brief LPTIM1 clock frequency. * @brief LPTIM1 clock frequency.
*/ */
#if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_LPTIM1SEL == STM32_LPTIM1SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_LPTIM1CLK STM32_PCLK1 #define STM32_LPTIM1CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI #elif STM32_LPTIM1SEL == STM32_LPTIM1SEL_LSI
#define STM32_LPTIM1CLK STM32_LSICLK #define STM32_LPTIM1CLK STM32_LSICLK
@ -1633,7 +1631,7 @@
* @brief LPTIM2 clock frequency. * @brief LPTIM2 clock frequency.
*/ */
#if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK1) || defined(__DOXYGEN__) #if (STM32_LPTIM2SEL == STM32_LPTIM2SEL_PCLK1) || defined(__DOXYGEN__)
#define STM32_LPTIM2CLK STM32_PCLK1 #define STM32_LPTIM2CLK hal_lld_get_clock_point(CLK_PCLK1)
#elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI #elif STM32_LPTIM2SEL == STM32_LPTIM2SEL_LSI
#define STM32_LPTIM2CLK STM32_LSICLK #define STM32_LPTIM2CLK STM32_LSICLK
@ -1763,7 +1761,7 @@
#define STM32_ADCCLK STM32_PLLSAI1_R_CLKOUT #define STM32_ADCCLK STM32_PLLSAI1_R_CLKOUT
#elif STM32_ADCSEL == STM32_ADCSEL_SYSCLK #elif STM32_ADCSEL == STM32_ADCSEL_SYSCLK
#define STM32_ADCCLK STM32_SYSCLK #define STM32_ADCCLK hal_lld_get_clock_point(CLK_SYSCLK)
#else #else
#error "invalid source selected for ADC clock" #error "invalid source selected for ADC clock"
@ -1773,10 +1771,10 @@
* @brief DFSDM clock frequency. * @brief DFSDM clock frequency.
*/ */
#if (STM32_DFSDMSEL == STM32_DFSDMSEL_PCLK2) || defined(__DOXYGEN__) #if (STM32_DFSDMSEL == STM32_DFSDMSEL_PCLK2) || defined(__DOXYGEN__)
#define STM32_DFSDMCLK STM32_PCLK2 #define STM32_DFSDMCLK hal_lld_get_clock_point(CLK_PCLK2)
#elif STM32_DFSDMSEL == STM32_DFSDMSEL_SYSCLK #elif STM32_DFSDMSEL == STM32_DFSDMSEL_SYSCLK
#define STM32_DFSDMCLK STM32_SYSCLK #define STM32_DFSDMCLK hal_lld_get_clock_point(CLK_SYSCLK)
#else #else
#error "invalid source selected for DFSDM clock" #error "invalid source selected for DFSDM clock"
@ -1810,7 +1808,7 @@
* @brief OSPI clock frequency. * @brief OSPI clock frequency.
*/ */
#if (STM32_OSPISEL == STM32_OSPISEL_SYSCLK) || defined(__DOXYGEN__) #if (STM32_OSPISEL == STM32_OSPISEL_SYSCLK) || defined(__DOXYGEN__)
#define STM32_OSPICLK STM32_SYSCLK #define STM32_OSPICLK hal_lld_get_clock_point(CLK_SYSCLK)
#elif STM32_OSPISEL == STM32_OSPISEL_MSI #elif STM32_OSPISEL == STM32_OSPISEL_MSI
#define STM32_OSPICLK STM32_MSICLK #define STM32_OSPICLK STM32_MSICLK
@ -1823,30 +1821,40 @@
#endif #endif
/** /**
* @brief Clock of timers connected to APB1 * @brief TIMP1CLK clock frequency.
*/ */
#if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__) #if (STM32_PPRE1 == STM32_PPRE1_DIV1) || defined(__DOXYGEN__)
#define STM32_TIMCLK1 (STM32_PCLK1 * 1) #define STM32_TIMP1CLK (STM32_PCLK1 * 1)
#else #else
#define STM32_TIMCLK1 (STM32_PCLK1 * 2) #define STM32_TIMP1CLK (STM32_PCLK1 * 2)
#endif #endif
/**
* @brief TIMP2CLK clock frequency.
*/
#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__)
#define STM32_TIMP2CLK (STM32_PCLK2 * 1)
#else
#define STM32_TIMP2CLK (STM32_PCLK2 * 2)
#endif
/**
* @brief Clock of timers connected to APB1.
*/
#define STM32_TIMCLK1 hal_lld_get_clock_point(CLK_PCLK1TIM)
/** /**
* @brief Clock of timers connected to APB2. * @brief Clock of timers connected to APB2.
*/ */
#if (STM32_PPRE2 == STM32_PPRE2_DIV1) || defined(__DOXYGEN__) #define STM32_TIMCLK2 hal_lld_get_clock_point(CLK_PCLK2TIM)
#define STM32_TIMCLK2 (STM32_PCLK2 * 1)
#else
#define STM32_TIMCLK2 (STM32_PCLK2 * 2)
#endif
/** /**
* @brief Voltage boost settings. * @brief Voltage boost settings.
*/ */
#if (STM32_SYSCLK <= STM32_SYSCLK_NOBOOST_MAX) || defined(__DOXYGEN__) #if (STM32_SYSCLK > STM32_SYSCLK_MAX_NOBOOST) || defined(__DOXYGEN__)
#define STM32_R1MODE PWR_CR5_R1MODE #define STM32_CR5BITS 0
#else #else
#define STM32_R1MODE 0 #define STM32_CR5BITS PWR_CR5_R1MODE
#endif #endif
/** /**
@ -1864,8 +1872,11 @@
#elif STM32_HCLK <= STM32_3WS_THRESHOLD #elif STM32_HCLK <= STM32_3WS_THRESHOLD
#define STM32_FLASHBITS FLASH_ACR_LATENCY_3WS #define STM32_FLASHBITS FLASH_ACR_LATENCY_3WS
#else #elif STM32_HCLK <= STM32_4WS_THRESHOLD
#define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS #define STM32_FLASHBITS FLASH_ACR_LATENCY_4WS
#else
#define STM32_FLASHBITS FLASH_ACR_LATENCY_5WS
#endif #endif
/** /**
@ -1883,18 +1894,82 @@
#elif STM32_MSICLK <= STM32_3WS_THRESHOLD #elif STM32_MSICLK <= STM32_3WS_THRESHOLD
#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_3WS #define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_3WS
#else #elif STM32_MSICLK <= STM32_4WS_THRESHOLD
#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_4WS #define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_4WS
#else
#define STM32_MSI_FLASHBITS FLASH_ACR_LATENCY_5WS
#endif #endif
/*===========================================================================*/ /*===========================================================================*/
/* Driver data structures and types. */ /* Driver data structures and types. */
/*===========================================================================*/ /*===========================================================================*/
/**
* @brief Type of a clock point identifier.
*/
typedef unsigned halclkpt_t;
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
/**
* @brief Type of a clock point frequency in Hz.
*/
typedef uint32_t halfreq_t;
/**
* @brief Type of a clock configuration structure.
*/
typedef struct {
uint32_t pwr_cr1;
uint32_t pwr_cr2;
uint32_t pwr_cr3;
uint32_t pwr_cr4;
uint32_t pwr_cr5;
uint32_t rcc_cr;
uint32_t rcc_cfgr;
uint32_t rcc_pllcfgr;
uint32_t rcc_pllsai1cfgr;
uint32_t rcc_pllsai2cfgr;
uint32_t rcc_crrcr;
uint32_t flash_acr;
} halclkcfg_t;
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/ /*===========================================================================*/
/* Driver macros. */ /* Driver macros. */
/*===========================================================================*/ /*===========================================================================*/
#if !defined(HAL_LLD_USE_CLOCK_MANAGEMENT)
/**
* @brief Returns the frequency of a clock point in Hz.
* @note Static implementation.
*
* @param[in] clkpt clock point to be returned
* @return The clock point frequency in Hz or zero if the
* frequency is unknown.
*
* @notapi
*/
#define hal_lld_get_clock_point(clkpt) \
((clkpt) == CLK_SYSCLK ? STM32_SYSCLK : \
(clkpt) == CLK_HCLK ? STM32_HCLK : \
(clkpt) == CLK_PCLK1 ? STM32_PCLK1 : \
(clkpt) == CLK_PLLPCLK ? STM32_PLL_P_CLKOUT : \
(clkpt) == CLK_PLLQCLK ? STM32_PLL_Q_CLKOUT : \
(clkpt) == CLK_PLLRCLK ? STM32_PLL_R_CLKOUT : \
(clkpt) == CLK_PLLSAI1PCLK ? STM32_PLLSAI1_P_CLKOUT : \
(clkpt) == CLK_PLLSAI1QCLK ? STM32_PLLSAI1_Q_CLKOUT : \
(clkpt) == CLK_PLLSAI1RCLK ? STM32_PLLSAI1_R_CLKOUT : \
(clkpt) == CLK_PLLSAI2PCLK ? STM32_PLLSAI2_P_CLKOUT : \
(clkpt) == CLK_PLLSAI2QCLK ? STM32_PLLSAI2_Q_CLKOUT : \
(clkpt) == CLK_PLLSAI2RCLK ? STM32_PLLSAI2_R_CLKOUT : \
(clkpt) == CLK_PCLK1TIM ? STM32_TIMP1CLK : \
(clkpt) == CLK_PCLK2 ? STM32_PCLK2 : \
(clkpt) == CLK_PCLK2TIM ? STM32_TIMP2CLK : \
(clkpt) == CLK_MCO ? STM32_MCOCLK : \
0U)
#endif /* !defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/ /*===========================================================================*/
/* External declarations. */ /* External declarations. */
/*===========================================================================*/ /*===========================================================================*/
@ -1909,11 +1984,20 @@
#include "stm32_rcc.h" #include "stm32_rcc.h"
#include "stm32_tim.h" #include "stm32_tim.h"
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) && !defined(__DOXYGEN__)
extern const halclkcfg_t hal_clkcfg_reset;
extern const halclkcfg_t hal_clkcfg_default;
#endif
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
void hal_lld_init(void); void hal_lld_init(void);
void stm32_clock_init(void); void stm32_clock_init(void);
#if defined(HAL_LLD_USE_CLOCK_MANAGEMENT) || defined(__DOXYGEN__)
bool hal_lld_clock_switch_mode(const halclkcfg_t *ccp);
halfreq_t hal_lld_get_clock_point(halclkpt_t clkpt);
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -75,7 +75,7 @@
*** Next *** *** Next ***
- NEW: STM32 ADCv3, USARTv2, USARTv3, USBv1 updated for dynamic clocking. - NEW: STM32 ADCv3, USARTv2, USARTv3, USBv1 updated for dynamic clocking.
- NEW: Dynamic support implemented for STM32G4xx. - NEW: Dynamic support implemented for STM32G4, STM32L4+.
- NEW: Dynamic clocks support in HAL. - NEW: Dynamic clocks support in HAL.
- NEW: Reload feature added to RT virtual timers. - NEW: Reload feature added to RT virtual timers.
- NEW: Upgraded the clock initialization for STM32G0, STM32L4 and STM32L4++ - NEW: Upgraded the clock initialization for STM32G0, STM32L4 and STM32L4++