From 603dedb80f1c3ede7467dacf3e6d646c3a2a3c47 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 23 May 2021 11:47:18 +0000 Subject: [PATCH] Additional PWR support, fast switch support. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14423 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- .../NIL-STM32G071RB-NUCLEO64/cfg/mcuconf.h | 10 +++ .../RT-STM32G071RB-NUCLEO64/cfg/mcuconf.h | 10 +++ os/hal/ports/STM32/STM32G0xx/hal_lld.c | 82 +++++++++++++++--- os/hal/ports/STM32/STM32G0xx/hal_lld.h | 83 ++++++++++++++++++- .../ADC/cfg/stm32g071rb_nucleo64/mcuconf.h | 10 +++ .../RTC/cfg/stm32g071_nucleo64/mcuconf.h | 10 +++ .../conf/mcuconf_stm32g071xx/mcuconf.h.ftl | 10 +++ 7 files changed, 200 insertions(+), 15 deletions(-) diff --git a/demos/STM32/NIL-STM32G071RB-NUCLEO64/cfg/mcuconf.h b/demos/STM32/NIL-STM32G071RB-NUCLEO64/cfg/mcuconf.h index d5fdb880c..5ce188251 100644 --- a/demos/STM32/NIL-STM32G071RB-NUCLEO64/cfg/mcuconf.h +++ b/demos/STM32/NIL-STM32G071RB-NUCLEO64/cfg/mcuconf.h @@ -44,6 +44,16 @@ #define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED) #define STM32_PWR_CR3 (PWR_CR3_EIWUL) #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_HSI16_ENABLED TRUE #define STM32_HSE_ENABLED FALSE diff --git a/demos/STM32/RT-STM32G071RB-NUCLEO64/cfg/mcuconf.h b/demos/STM32/RT-STM32G071RB-NUCLEO64/cfg/mcuconf.h index d5c1b125c..60e609576 100644 --- a/demos/STM32/RT-STM32G071RB-NUCLEO64/cfg/mcuconf.h +++ b/demos/STM32/RT-STM32G071RB-NUCLEO64/cfg/mcuconf.h @@ -44,6 +44,16 @@ #define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED) #define STM32_PWR_CR3 (PWR_CR3_EIWUL) #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_HSI16_ENABLED TRUE #define STM32_HSE_ENABLED FALSE diff --git a/os/hal/ports/STM32/STM32G0xx/hal_lld.c b/os/hal/ports/STM32/STM32G0xx/hal_lld.c index a7e3bdd7a..bc1e8f515 100644 --- a/os/hal/ports/STM32/STM32G0xx/hal_lld.c +++ b/os/hal/ports/STM32/STM32G0xx/hal_lld.c @@ -45,6 +45,14 @@ */ #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. */ /*===========================================================================*/ @@ -62,8 +70,6 @@ uint32_t SystemCoreClock = STM32_HCLK; const halclkcfg_t hal_clkcfg_reset = { .pwr_cr1 = PWR_CR1_VOS_0 | PWR_CR1_FPD_STOP, .pwr_cr2 = 0U, - .pwr_cr3 = PWR_CR3_EIWUL, - .pwr_cr4 = 0U, .rcc_cr = RCC_CR_HSION, .rcc_cfgr = RCC_CFGR_SW_HSI, .rcc_pllcfgr = 0U, @@ -76,8 +82,6 @@ const halclkcfg_t hal_clkcfg_reset = { 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, .rcc_cr = 0U #if STM32_HSI16_ENABLED | 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 - * @return The clock switch result. + * @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 halclkcfg_t *ccp) { +bool hal_lld_clock_raw_config(const halclkcfg_t *ccp) { /* Restoring default PWR settings related clocks and sleep modes.*/ PWR->CR1 = PWR_CR1_VOS_0; @@ -467,8 +471,6 @@ bool hal_lld_clock_raw_switch(const halclkcfg_t *ccp) { /* Final PWR modes.*/ PWR->CR1 = ccp->pwr_cr1; PWR->CR2 = ccp->pwr_cr2; - PWR->CR3 = ccp->pwr_cr3; - PWR->CR4 = ccp->pwr_cr4; /* Waiting for the correct regulator state.*/ if ((ccp->pwr_cr1 & PWR_CR1_LPR) == 0U) { @@ -499,6 +501,36 @@ bool hal_lld_clock_raw_switch(const halclkcfg_t *ccp) { 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) */ /*===========================================================================*/ @@ -554,6 +586,20 @@ void stm32_clock_init(void) { /* Backup domain made accessible.*/ 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.*/ bd_reset(); @@ -562,7 +608,7 @@ void stm32_clock_init(void) { lsi_init(); /* 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"); } @@ -593,7 +639,19 @@ void stm32_clock_init(void) { ; /* stable. */ /* 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.*/ bd_reset(); @@ -654,7 +712,7 @@ bool hal_lld_clock_switch_mode(const halclkcfg_t *ccp) { return true; } - if (hal_lld_clock_raw_switch(ccp)) { + if (hal_lld_clock_raw_config(ccp)) { return true; } diff --git a/os/hal/ports/STM32/STM32G0xx/hal_lld.h b/os/hal/ports/STM32/STM32G0xx/hal_lld.h index f295a0efa..4cda763e8 100644 --- a/os/hal/ports/STM32/STM32G0xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32G0xx/hal_lld.h @@ -384,6 +384,76 @@ #define STM32_PWR_CR4 (0U) #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. * @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; /** - * @brief Type of a clock configuration structure. + * @brief Type of a clock configuration and switch structure. */ typedef struct { uint32_t pwr_cr1; uint32_t pwr_cr2; - uint32_t pwr_cr3; - uint32_t pwr_cr4; uint32_t rcc_cr; uint32_t rcc_cfgr; uint32_t rcc_pllcfgr; uint32_t flash_acr; } 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) */ /*===========================================================================*/ diff --git a/testhal/STM32/multi/ADC/cfg/stm32g071rb_nucleo64/mcuconf.h b/testhal/STM32/multi/ADC/cfg/stm32g071rb_nucleo64/mcuconf.h index d10c89448..f6e48d7ca 100644 --- a/testhal/STM32/multi/ADC/cfg/stm32g071rb_nucleo64/mcuconf.h +++ b/testhal/STM32/multi/ADC/cfg/stm32g071rb_nucleo64/mcuconf.h @@ -44,6 +44,16 @@ #define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED) #define STM32_PWR_CR3 (PWR_CR3_EIWUL) #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_HSI16_ENABLED TRUE #define STM32_HSE_ENABLED FALSE diff --git a/testhal/STM32/multi/RTC/cfg/stm32g071_nucleo64/mcuconf.h b/testhal/STM32/multi/RTC/cfg/stm32g071_nucleo64/mcuconf.h index f7b14b2ed..fe27e627c 100644 --- a/testhal/STM32/multi/RTC/cfg/stm32g071_nucleo64/mcuconf.h +++ b/testhal/STM32/multi/RTC/cfg/stm32g071_nucleo64/mcuconf.h @@ -44,6 +44,16 @@ #define STM32_PWR_CR2 (STM32_PVDRT_LEV0 | STM32_PVDFT_LEV0 | STM32_PVDE_DISABLED) #define STM32_PWR_CR3 (PWR_CR3_EIWUL) #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_HSI16_ENABLED TRUE #define STM32_HSE_ENABLED FALSE diff --git a/tools/ftl/processors/conf/mcuconf_stm32g071xx/mcuconf.h.ftl b/tools/ftl/processors/conf/mcuconf_stm32g071xx/mcuconf.h.ftl index a65b17de1..79b18cdcc 100644 --- a/tools/ftl/processors/conf/mcuconf_stm32g071xx/mcuconf.h.ftl +++ b/tools/ftl/processors/conf/mcuconf_stm32g071xx/mcuconf.h.ftl @@ -55,6 +55,16 @@ #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_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_HSI16_ENABLED ${doc.STM32_HSI16_ENABLED!"TRUE"} #define STM32_HSE_ENABLED ${doc.STM32_HSE_ENABLED!"FALSE"}