Additional PWR support, fast switch support.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14423 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2021-05-23 11:47:18 +00:00
parent 296783fd57
commit 603dedb80f
7 changed files with 200 additions and 15 deletions

View File

@ -44,6 +44,16 @@
#define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED) #define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED)
#define STM32_PWR_CR3 (PWR_CR3_EIWUL) #define STM32_PWR_CR3 (PWR_CR3_EIWUL)
#define STM32_PWR_CR4 (0U) #define STM32_PWR_CR4 (0U)
#define STM32_PWR_PUCRA (0U)
#define STM32_PWR_PDCRA (0U)
#define STM32_PWR_PUCRB (0U)
#define STM32_PWR_PDCRB (0U)
#define STM32_PWR_PUCRC (0U)
#define STM32_PWR_PDCRC (0U)
#define STM32_PWR_PUCRD (0U)
#define STM32_PWR_PDCRD (0U)
#define STM32_PWR_PUCRF (0U)
#define STM32_PWR_PDCRF (0U)
#define STM32_HSIDIV_VALUE 1 #define STM32_HSIDIV_VALUE 1
#define STM32_HSI16_ENABLED TRUE #define STM32_HSI16_ENABLED TRUE
#define STM32_HSE_ENABLED FALSE #define STM32_HSE_ENABLED FALSE

View File

@ -44,6 +44,16 @@
#define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED) #define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED)
#define STM32_PWR_CR3 (PWR_CR3_EIWUL) #define STM32_PWR_CR3 (PWR_CR3_EIWUL)
#define STM32_PWR_CR4 (0U) #define STM32_PWR_CR4 (0U)
#define STM32_PWR_PUCRA (0U)
#define STM32_PWR_PDCRA (0U)
#define STM32_PWR_PUCRB (0U)
#define STM32_PWR_PDCRB (0U)
#define STM32_PWR_PUCRC (0U)
#define STM32_PWR_PDCRC (0U)
#define STM32_PWR_PUCRD (0U)
#define STM32_PWR_PDCRD (0U)
#define STM32_PWR_PUCRF (0U)
#define STM32_PWR_PDCRF (0U)
#define STM32_HSIDIV_VALUE 1 #define STM32_HSIDIV_VALUE 1
#define STM32_HSI16_ENABLED TRUE #define STM32_HSI16_ENABLED TRUE
#define STM32_HSE_ENABLED FALSE #define STM32_HSE_ENABLED FALSE

View File

@ -45,6 +45,14 @@
*/ */
#define STM32_RCC_CR_RESET (RCC_CR_HSION) #define STM32_RCC_CR_RESET (RCC_CR_HSION)
/**
* @brief PWR CR bits safe for fast switch.
*/
#define STM32_PWR_CR1_SAFE_ONLY_MASK (PWR_CR1_FPD_LPSLP | \
PWR_CR1_FPD_LPRUN | \
PWR_CR1_FPD_STOP | \
PWR_CR1_LPMS_Msk)
/*===========================================================================*/ /*===========================================================================*/
/* Driver exported variables. */ /* Driver exported variables. */
/*===========================================================================*/ /*===========================================================================*/
@ -62,8 +70,6 @@ uint32_t SystemCoreClock = STM32_HCLK;
const halclkcfg_t hal_clkcfg_reset = { const halclkcfg_t hal_clkcfg_reset = {
.pwr_cr1 = PWR_CR1_VOS_0 | PWR_CR1_FPD_STOP, .pwr_cr1 = PWR_CR1_VOS_0 | PWR_CR1_FPD_STOP,
.pwr_cr2 = 0U, .pwr_cr2 = 0U,
.pwr_cr3 = PWR_CR3_EIWUL,
.pwr_cr4 = 0U,
.rcc_cr = RCC_CR_HSION, .rcc_cr = RCC_CR_HSION,
.rcc_cfgr = RCC_CFGR_SW_HSI, .rcc_cfgr = RCC_CFGR_SW_HSI,
.rcc_pllcfgr = 0U, .rcc_pllcfgr = 0U,
@ -76,8 +82,6 @@ const halclkcfg_t hal_clkcfg_reset = {
const halclkcfg_t hal_clkcfg_default = { const halclkcfg_t hal_clkcfg_default = {
.pwr_cr1 = STM32_VOS_RANGE1 | PWR_CR1_DBP, .pwr_cr1 = STM32_VOS_RANGE1 | PWR_CR1_DBP,
.pwr_cr2 = STM32_PWR_CR2, .pwr_cr2 = STM32_PWR_CR2,
.pwr_cr3 = STM32_PWR_CR3,
.pwr_cr4 = STM32_PWR_CR4,
.rcc_cr = 0U .rcc_cr = 0U
#if STM32_HSI16_ENABLED #if STM32_HSI16_ENABLED
| RCC_CR_HSIKERON | RCC_CR_HSION | RCC_CR_HSIKERON | RCC_CR_HSION
@ -402,16 +406,16 @@ static bool hal_lld_clock_check_tree(const halclkcfg_t *ccp) {
} }
/** /**
* @brief Switches to a different clock configuration. * @brief Configures full clock settings.
* *
* @param[in] ccp pointer to clock a @p halclkcfg_t structure * @param[in] ccp pointer to clock a @p halclkcfg_t structure
* @return The clock switch result. * @return The clock configuration result.
* @retval false if the clock switch succeeded * @retval false if the clock switch succeeded
* @retval true if the clock switch failed * @retval true if the clock switch failed
* *
* @notapi * @notapi
*/ */
bool hal_lld_clock_raw_switch(const halclkcfg_t *ccp) { bool hal_lld_clock_raw_config(const halclkcfg_t *ccp) {
/* Restoring default PWR settings related clocks and sleep modes.*/ /* Restoring default PWR settings related clocks and sleep modes.*/
PWR->CR1 = PWR_CR1_VOS_0; PWR->CR1 = PWR_CR1_VOS_0;
@ -467,8 +471,6 @@ bool hal_lld_clock_raw_switch(const halclkcfg_t *ccp) {
/* Final PWR modes.*/ /* Final PWR modes.*/
PWR->CR1 = ccp->pwr_cr1; PWR->CR1 = ccp->pwr_cr1;
PWR->CR2 = ccp->pwr_cr2; PWR->CR2 = ccp->pwr_cr2;
PWR->CR3 = ccp->pwr_cr3;
PWR->CR4 = ccp->pwr_cr4;
/* Waiting for the correct regulator state.*/ /* Waiting for the correct regulator state.*/
if ((ccp->pwr_cr1 & PWR_CR1_LPR) == 0U) { if ((ccp->pwr_cr1 & PWR_CR1_LPR) == 0U) {
@ -499,6 +501,36 @@ bool hal_lld_clock_raw_switch(const halclkcfg_t *ccp) {
return false; return false;
} }
/**
* @brief Configures clock switch-only settings.
* @note This is a fast reconfiguration, clock sources settings are not
* touched, only switches and dividers are reprogrammed.
*
* @param[in] cwp pointer to clock a @p halclkswc_t structure
* @return The clock configuration result.
* @retval false if the clock switch succeeded
* @retval true if the clock switch failed
*
* @notapi
*/
bool hal_lld_clock_raw_switch(const halclkswc_t *cwp) {
/* PWR modes.*/
PWR->CR1 = (PWR->CR1 & ~STM32_PWR_CR1_SAFE_ONLY_MASK) |
(cwp->pwr_cr1 & STM32_PWR_CR1_SAFE_ONLY_MASK);
/* Flash ACR settings.*/
flash_set_acr(cwp->flash_acr);
/* Switching to the final clock source.*/
RCC->CFGR = cwp->rcc_cfgr;
while ((RCC->CFGR & RCC_CFGR_SWS) != ((cwp->rcc_cfgr & RCC_CFGR_SW_Msk) << RCC_CFGR_SWS_Pos)) {
/* Waiting for clock switch.*/
}
return false;
}
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */ #endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/ /*===========================================================================*/
@ -554,6 +586,20 @@ void stm32_clock_init(void) {
/* Backup domain made accessible.*/ /* Backup domain made accessible.*/
PWR->CR1 |= PWR_CR1_DBP; PWR->CR1 |= PWR_CR1_DBP;
/* Static PWR initializations.*/
PWR->CR3 = STM32_PWR_CR3;
PWR->CR4 = STM32_PWR_CR4;
PWR->PUCRA = STM32_PWR_PUCRA;
PWR->PDCRA = STM32_PWR_PDCRA;
PWR->PUCRB = STM32_PWR_PUCRB;
PWR->PDCRB = STM32_PWR_PDCRB;
PWR->PUCRC = STM32_PWR_PUCRC;
PWR->PDCRC = STM32_PWR_PDCRC;
PWR->PUCRD = STM32_PWR_PUCRD;
PWR->PDCRD = STM32_PWR_PDCRD;
PWR->PUCRF = STM32_PWR_PUCRF;
PWR->PDCRF = STM32_PWR_PDCRF;
/* Backup domain reset.*/ /* Backup domain reset.*/
bd_reset(); bd_reset();
@ -562,7 +608,7 @@ void stm32_clock_init(void) {
lsi_init(); lsi_init();
/* Selecting the default clock/power/flash configuration.*/ /* Selecting the default clock/power/flash configuration.*/
if (hal_lld_clock_raw_switch(&hal_clkcfg_default)) { if (hal_lld_clock_raw_config(&hal_clkcfg_default)) {
osalSysHalt("clkswc"); osalSysHalt("clkswc");
} }
@ -593,7 +639,19 @@ void stm32_clock_init(void) {
; /* stable. */ ; /* stable. */
/* Additional PWR configurations.*/ /* Additional PWR configurations.*/
PWR->CR2 = STM32_PWR_CR2; PWR->CR2 = STM32_PWR_CR2;
PWR->CR3 = STM32_PWR_CR3;
PWR->CR4 = STM32_PWR_CR4;
PWR->PUCRA = STM32_PWR_PUCRA;
PWR->PDCRA = STM32_PWR_PDCRA;
PWR->PUCRB = STM32_PWR_PUCRB;
PWR->PDCRB = STM32_PWR_PDCRB;
PWR->PUCRC = STM32_PWR_PUCRC;
PWR->PDCRC = STM32_PWR_PDCRC;
PWR->PUCRD = STM32_PWR_PUCRD;
PWR->PDCRD = STM32_PWR_PDCRD;
PWR->PUCRF = STM32_PWR_PUCRF;
PWR->PDCRF = STM32_PWR_PDCRF;
/* Backup domain reset.*/ /* Backup domain reset.*/
bd_reset(); bd_reset();
@ -654,7 +712,7 @@ bool hal_lld_clock_switch_mode(const halclkcfg_t *ccp) {
return true; return true;
} }
if (hal_lld_clock_raw_switch(ccp)) { if (hal_lld_clock_raw_config(ccp)) {
return true; return true;
} }

View File

@ -384,6 +384,76 @@
#define STM32_PWR_CR4 (0U) #define STM32_PWR_CR4 (0U)
#endif #endif
/**
* @brief PWR PUCRA register initialization value.
*/
#if !defined(STM32_PWR_PUCRA) || defined(__DOXYGEN__)
#define STM32_PWR_PUCRA (0U)
#endif
/**
* @brief PWR PDCRA register initialization value.
*/
#if !defined(STM32_PWR_PDCRA) || defined(__DOXYGEN__)
#define STM32_PWR_PDCRA (0U)
#endif
/**
* @brief PWR PUCRB register initialization value.
*/
#if !defined(STM32_PWR_PUCRB) || defined(__DOXYGEN__)
#define STM32_PWR_PUCRB (0U)
#endif
/**
* @brief PWR PDCRB register initialization value.
*/
#if !defined(STM32_PWR_PDCRB) || defined(__DOXYGEN__)
#define STM32_PWR_PDCRB (0U)
#endif
/**
* @brief PWR PUCRC register initialization value.
*/
#if !defined(STM32_PWR_PUCRC) || defined(__DOXYGEN__)
#define STM32_PWR_PUCRC (0U)
#endif
/**
* @brief PWR PDCRC register initialization value.
*/
#if !defined(STM32_PWR_PDCRC) || defined(__DOXYGEN__)
#define STM32_PWR_PDCRC (0U)
#endif
/**
* @brief PWR PUCRD register initialization value.
*/
#if !defined(STM32_PWR_PUCRD) || defined(__DOXYGEN__)
#define STM32_PWR_PUCRD (0U)
#endif
/**
* @brief PWR PDCRD register initialization value.
*/
#if !defined(STM32_PWR_PDCRD) || defined(__DOXYGEN__)
#define STM32_PWR_PDCRD (0U)
#endif
/**
* @brief PWR PUCRF register initialization value.
*/
#if !defined(STM32_PWR_PUCRF) || defined(__DOXYGEN__)
#define STM32_PWR_PUCRF (0U)
#endif
/**
* @brief PWR PDCRF register initialization value.
*/
#if !defined(STM32_PWR_PDCRF) || defined(__DOXYGEN__)
#define STM32_PWR_PDCRF (0U)
#endif
/** /**
* @brief HSI16 divider value. * @brief HSI16 divider value.
* @note The allowed values are 1, 2, 4, 8, 16, 32, 64, 128. * @note The allowed values are 1, 2, 4, 8, 16, 32, 64, 128.
@ -1461,18 +1531,25 @@ typedef unsigned halclkpt_t;
typedef uint32_t halfreq_t; typedef uint32_t halfreq_t;
/** /**
* @brief Type of a clock configuration structure. * @brief Type of a clock configuration and switch structure.
*/ */
typedef struct { typedef struct {
uint32_t pwr_cr1; uint32_t pwr_cr1;
uint32_t pwr_cr2; uint32_t pwr_cr2;
uint32_t pwr_cr3;
uint32_t pwr_cr4;
uint32_t rcc_cr; uint32_t rcc_cr;
uint32_t rcc_cfgr; uint32_t rcc_cfgr;
uint32_t rcc_pllcfgr; uint32_t rcc_pllcfgr;
uint32_t flash_acr; uint32_t flash_acr;
} halclkcfg_t; } halclkcfg_t;
/**
* @brief Type of a clock switch-only structure.
*/
typedef struct {
uint32_t pwr_cr1;
uint32_t rcc_cfgr;
uint32_t flash_acr;
} halclkswc_t;
#endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */ #endif /* defined(HAL_LLD_USE_CLOCK_MANAGEMENT) */
/*===========================================================================*/ /*===========================================================================*/

View File

@ -44,6 +44,16 @@
#define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED) #define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED)
#define STM32_PWR_CR3 (PWR_CR3_EIWUL) #define STM32_PWR_CR3 (PWR_CR3_EIWUL)
#define STM32_PWR_CR4 (0U) #define STM32_PWR_CR4 (0U)
#define STM32_PWR_PUCRA (0U)
#define STM32_PWR_PDCRA (0U)
#define STM32_PWR_PUCRB (0U)
#define STM32_PWR_PDCRB (0U)
#define STM32_PWR_PUCRC (0U)
#define STM32_PWR_PDCRC (0U)
#define STM32_PWR_PUCRD (0U)
#define STM32_PWR_PDCRD (0U)
#define STM32_PWR_PUCRF (0U)
#define STM32_PWR_PDCRF (0U)
#define STM32_HSIDIV_VALUE 1 #define STM32_HSIDIV_VALUE 1
#define STM32_HSI16_ENABLED TRUE #define STM32_HSI16_ENABLED TRUE
#define STM32_HSE_ENABLED FALSE #define STM32_HSE_ENABLED FALSE

View File

@ -44,6 +44,16 @@
#define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED) #define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED)
#define STM32_PWR_CR3 (PWR_CR3_EIWUL) #define STM32_PWR_CR3 (PWR_CR3_EIWUL)
#define STM32_PWR_CR4 (0U) #define STM32_PWR_CR4 (0U)
#define STM32_PWR_PUCRA (0U)
#define STM32_PWR_PDCRA (0U)
#define STM32_PWR_PUCRB (0U)
#define STM32_PWR_PDCRB (0U)
#define STM32_PWR_PUCRC (0U)
#define STM32_PWR_PDCRC (0U)
#define STM32_PWR_PUCRD (0U)
#define STM32_PWR_PDCRD (0U)
#define STM32_PWR_PUCRF (0U)
#define STM32_PWR_PDCRF (0U)
#define STM32_HSIDIV_VALUE 1 #define STM32_HSIDIV_VALUE 1
#define STM32_HSI16_ENABLED TRUE #define STM32_HSI16_ENABLED TRUE
#define STM32_HSE_ENABLED FALSE #define STM32_HSE_ENABLED FALSE

View File

@ -55,6 +55,16 @@
#define STM32_PWR_CR2 ${doc.STM32_PWR_CR2!"(STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED)"} #define STM32_PWR_CR2 ${doc.STM32_PWR_CR2!"(STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED)"}
#define STM32_PWR_CR3 ${doc.STM32_PWR_CR3!"(PWR_CR3_EIWUL)"} #define STM32_PWR_CR3 ${doc.STM32_PWR_CR3!"(PWR_CR3_EIWUL)"}
#define STM32_PWR_CR4 ${doc.STM32_PWR_CR4!"(0U)"} #define STM32_PWR_CR4 ${doc.STM32_PWR_CR4!"(0U)"}
#define STM32_PWR_PUCRA ${doc.STM32_PWR_PUCRA!"(0U)"}
#define STM32_PWR_PDCRA ${doc.STM32_PWR_PDCRA!"(0U)"}
#define STM32_PWR_PUCRB ${doc.STM32_PWR_PUCRB!"(0U)"}
#define STM32_PWR_PDCRB ${doc.STM32_PWR_PDCRB!"(0U)"}
#define STM32_PWR_PUCRC ${doc.STM32_PWR_PUCRC!"(0U)"}
#define STM32_PWR_PDCRC ${doc.STM32_PWR_PDCRC!"(0U)"}
#define STM32_PWR_PUCRD ${doc.STM32_PWR_PUCRD!"(0U)"}
#define STM32_PWR_PDCRD ${doc.STM32_PWR_PDCRD!"(0U)"}
#define STM32_PWR_PUCRF ${doc.STM32_PWR_PUCRF!"(0U)"}
#define STM32_PWR_PDCRF ${doc.STM32_PWR_PDCRF!"(0U)"}
#define STM32_HSIDIV_VALUE ${doc.STM32_HSIDIV_VALUE!"1"} #define STM32_HSIDIV_VALUE ${doc.STM32_HSIDIV_VALUE!"1"}
#define STM32_HSI16_ENABLED ${doc.STM32_HSI16_ENABLED!"TRUE"} #define STM32_HSI16_ENABLED ${doc.STM32_HSI16_ENABLED!"TRUE"}
#define STM32_HSE_ENABLED ${doc.STM32_HSE_ENABLED!"FALSE"} #define STM32_HSE_ENABLED ${doc.STM32_HSE_ENABLED!"FALSE"}