This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 2dbfa541508f590e3a3018dcf1a281acdb82873d Author: Michael Jung <[email protected]> AuthorDate: Wed Mar 17 20:05:07 2021 +0100 stm32l5: Optional LSE xtal drive strength ramp-up Ported from stm32f7/h7: If configured this way, ramp-up the LSE crystal oscillator driving strength until the LSE starts up. Signed-off-by: Michael Jung <[email protected]> --- arch/arm/src/stm32l5/Kconfig | 19 +++++ arch/arm/src/stm32l5/stm32l5_lse.c | 87 ++++++++++++++++------ .../stm32l5/nucleo-l552ze/configs/nsh/defconfig | 2 + 3 files changed, 86 insertions(+), 22 deletions(-) diff --git a/arch/arm/src/stm32l5/Kconfig b/arch/arm/src/stm32l5/Kconfig index 280f53d..741eb97 100644 --- a/arch/arm/src/stm32l5/Kconfig +++ b/arch/arm/src/stm32l5/Kconfig @@ -248,6 +248,10 @@ config STM32L5_PWR bool "PWR" default n +config STM32L5_RTC + bool "RTC" + default n + config STM32L5_LPUART1 bool "LPUART1" default n @@ -389,10 +393,24 @@ endchoice if STM32L5_RTC_LSECLOCK +config STM32L5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY + bool "Automaticaly boost the LSE oscillator drive capability level until it starts-up" + default n + ---help--- + This will cycle through the values from low to high. To avoid + damaging the the crystal. We want to use the lowest setting that gets + the OSC running. See app note AN2867 + + 0 = Low drive capability (default) + 1 = Medium low drive capability + 2 = Medium high drive capability + 3 = High drive capability + config STM32L5_RTC_LSECLOCK_START_DRV_CAPABILITY int "LSE oscillator drive capability level at LSE start-up" default 0 range 0 3 + depends on !STM32L5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY ---help--- 0 = Low drive capability (default) 1 = Medium low drive capability @@ -403,6 +421,7 @@ config STM32L5_RTC_LSECLOCK_RUN_DRV_CAPABILITY int "LSE oscillator drive capability level after LSE start-up" default 0 range 0 3 + depends on !STM32L5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY ---help--- 0 = Low drive capability (default) 1 = Medium low drive capability diff --git a/arch/arm/src/stm32l5/stm32l5_lse.c b/arch/arm/src/stm32l5/stm32l5_lse.c index b8f96dc..35ad78e 100644 --- a/arch/arm/src/stm32l5/stm32l5_lse.c +++ b/arch/arm/src/stm32l5/stm32l5_lse.c @@ -71,6 +71,20 @@ #endif /**************************************************************************** + * Private Data + ****************************************************************************/ + +#ifdef CONFIG_STM32L5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY +static const uint32_t drives[4] = +{ + RCC_BDCR_LSEDRV_LOW, + RCC_BDCR_LSEDRV_MEDLO, + RCC_BDCR_LSEDRV_MEDHI, + RCC_BDCR_LSEDRV_HIGH +}; +#endif + +/**************************************************************************** * Public Functions ****************************************************************************/ @@ -87,6 +101,9 @@ void stm32l5_rcc_enablelse(void) bool writable; uint32_t regval; volatile int32_t timeout; +#ifdef CONFIG_STM32L5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY + volatile int32_t drive = 0; +#endif /* Check if both the External Low-Speed (LSE) oscillator and the LSE system * clock are already running. @@ -113,46 +130,72 @@ void stm32l5_rcc_enablelse(void) regval |= RCC_BDCR_LSEON; #ifdef CONFIG_STM32L5_RTC_LSECLOCK_START_DRV_CAPABILITY - /* Set start-up drive capability for LSE oscillator. */ + /* Set start-up drive capability for LSE oscillator. LSE must be OFF + * to change drive strength. + */ - regval &= ~RCC_BDCR_LSEDRV_MASK; + regval &= ~(RCC_BDCR_LSEDRV_MASK | RCC_BDCR_LSEON); regval |= CONFIG_STM32L5_RTC_LSECLOCK_START_DRV_CAPABILITY << RCC_BDCR_LSEDRV_SHIFT; -#endif - putreg32(regval, STM32L5_RCC_BDCR); + regval |= RCC_BDCR_LSEON; +#endif - /* Wait for the LSE clock to be ready (or until a timeout elapsed) - */ - - for (timeout = LSERDY_TIMEOUT; timeout > 0; timeout--) +#ifdef CONFIG_STM32L5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY + do { - /* Check if the LSERDY flag is the set in the BDCR */ + regval &= ~(RCC_BDCR_LSEDRV_MASK | RCC_BDCR_LSEON); + regval |= drives[drive++]; + putreg32(regval, STM32L5_RCC_BDCR); + regval |= RCC_BDCR_LSEON; +#endif + + putreg32(regval, STM32L5_RCC_BDCR); - regval = getreg32(STM32L5_RCC_BDCR); + /* Wait for the LSE clock to be ready (or until a timeout elapsed) + */ - if (regval & RCC_BDCR_LSERDY) + for (timeout = LSERDY_TIMEOUT; timeout > 0; timeout--) { - /* If so, then break-out with timeout > 0 */ + /* Check if the LSERDY flag is the set in the BDCR */ + + regval = getreg32(STM32L5_RCC_BDCR); + + if (regval & RCC_BDCR_LSERDY) + { + /* If so, then break-out with timeout > 0 */ + break; + } + } + +#ifdef CONFIG_STM32L5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY + if (timeout != 0) + { break; } } + while (drive < sizeof(drives) / sizeof(drives[0])); +#endif - /* Enable LSE system clock. The LSE system clock seems to provide a - * means to gate the LSE clock distribution to peripherals. It must be - * enabled for MSI PLL mode (syncing the MSI to the LSE). - */ + if (timeout != 0) + { + /* Enable LSE system clock. The LSE system clock seems to provide + * a means to gate the LSE clock distribution to peripherals. It + * must be enabled for MSI PLL mode (syncing the MSI to the LSE). + */ - regval |= RCC_BDCR_LSESYSEN; + regval |= RCC_BDCR_LSESYSEN; - putreg32(regval, STM32L5_RCC_BDCR); + putreg32(regval, STM32L5_RCC_BDCR); - /* Wait for the LSE system clock to be ready */ + /* Wait for the LSE system clock to be ready */ - while (!((regval = getreg32(STM32L5_RCC_BDCR)) & RCC_BDCR_LSESYSRDY)) - { - up_waste(); + while (!((regval = getreg32(STM32L5_RCC_BDCR)) & + RCC_BDCR_LSESYSRDY)) + { + up_waste(); + } } #if defined(CONFIG_STM32L5_RTC_LSECLOCK_RUN_DRV_CAPABILITY) && \ diff --git a/boards/arm/stm32l5/nucleo-l552ze/configs/nsh/defconfig b/boards/arm/stm32l5/nucleo-l552ze/configs/nsh/defconfig index 6cbb531..db231f0 100644 --- a/boards/arm/stm32l5/nucleo-l552ze/configs/nsh/defconfig +++ b/boards/arm/stm32l5/nucleo-l552ze/configs/nsh/defconfig @@ -54,6 +54,8 @@ CONFIG_RR_INTERVAL=200 CONFIG_SCHED_WAITPID=y CONFIG_SDCLONE_DISABLE=y CONFIG_STACK_COLORATION=y +CONFIG_STM32L5_RTC=y +CONFIG_STM32L5_RTC_AUTO_LSECLOCK_START_DRV_CAPABILITY=y CONFIG_STM32L5_USART3=y CONFIG_SYSTEM_NSH=y CONFIG_SYSTEM_STACKMONITOR=y
