From 8fd1b6863d7331e6e72cd88d67fb8c9bc6faf41a Mon Sep 17 00:00:00 2001 From: Markus Fuchs Date: Thu, 16 Jun 2022 13:55:43 +0200 Subject: [PATCH] drivers: counter: stm32: Add support for HSE as RTC clock source Add Kconfig options COUNTER_RTC_STM32_CLOCK_HSE and COUNTER_RTC_STM32_HSE_DIV to allow configuring HSE as the RTC clock source. Signed-off-by: Markus Fuchs --- drivers/counter/Kconfig.stm32_rtc | 15 +++++++++++++++ drivers/counter/counter_ll_stm32_rtc.c | 19 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/drivers/counter/Kconfig.stm32_rtc b/drivers/counter/Kconfig.stm32_rtc index eeda1a6ea706d..e9db2311d46fc 100644 --- a/drivers/counter/Kconfig.stm32_rtc +++ b/drivers/counter/Kconfig.stm32_rtc @@ -30,6 +30,14 @@ config COUNTER_RTC_STM32_CLOCK_LSE help Use LSE as RTC clock +config COUNTER_RTC_STM32_CLOCK_HSE + bool "HSE" + depends on SOC_SERIES_STM32F2X || SOC_SERIES_STM32F4X || \ + SOC_SERIES_STM32F7X || SOC_SERIES_STM32H7X || \ + SOC_SERIES_STM32L0X || SOC_SERIES_STM32L1X + help + Use HSE as RTC clock. An appropriate prescaler must be set. + endchoice #COUNTER_RTC_STM32_CLOCK_SRC if !SOC_SERIES_STM32F4X @@ -75,6 +83,13 @@ config COUNTER_RTC_STM32_LSE_BYPASS help Enable LSE bypass +config COUNTER_RTC_STM32_HSE_DIV + int "HSE prescaler" + depends on COUNTER_RTC_STM32_CLOCK_HSE + default 0 + help + HSE division factor for obtaining a 1 MHz RTC clock + config COUNTER_RTC_STM32_BACKUP_DOMAIN_RESET bool "Do backup domain reset" default y diff --git a/drivers/counter/counter_ll_stm32_rtc.c b/drivers/counter/counter_ll_stm32_rtc.c index dc1c2bb7087b6..3c457d0e12793 100644 --- a/drivers/counter/counter_ll_stm32_rtc.c +++ b/drivers/counter/counter_ll_stm32_rtc.c @@ -52,6 +52,11 @@ LOG_MODULE_REGISTER(counter_rtc_stm32, CONFIG_COUNTER_LOG_LEVEL); #define RTC_EXTI_LINE LL_EXTI_LINE_17 #endif +/* Macro to fill up HSE prescaler values */ +#define fn_hse_prescaler(v) LL_RCC_RTC_HSE_DIV_ ## v +#define hse_prescaler(v) fn_hse_prescaler(v) +#define LL_RCC_RTC_HSE_DIV_0 LL_RCC_RTC_NOCLOCK + struct rtc_stm32_config { struct counter_config_info counter_info; struct stm32_pclken pclken; @@ -310,6 +315,16 @@ static int rtc_stm32_init(const struct device *dev) LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSI); +#elif defined(CONFIG_COUNTER_RTC_STM32_CLOCK_HSE) + + LL_RCC_SetRTC_HSEPrescaler(hse_prescaler(CONFIG_COUNTER_RTC_STM32_HSE_DIV)); + + /* Wait until HSE is ready */ + while (LL_RCC_HSE_IsReady() != 1) { + } + + LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_HSE); + #else /* CONFIG_COUNTER_RTC_STM32_CLOCK_LSE */ #if !defined(CONFIG_SOC_SERIES_STM32F4X) && \ @@ -396,6 +411,10 @@ static const struct rtc_stm32_config rtc_config = { /* prescaler values for LSI @ 32 KHz */ .AsynchPrescaler = 0x7F, .SynchPrescaler = 0x00F9, +#elif defined(CONFIG_COUNTER_RTC_STM32_CLOCK_HSE) + /* prescaler values for divided HSE @ 1 MHz */ + .AsynchPrescaler = 0x7C, + .SynchPrescaler = 0x1F3F, #else /* CONFIG_COUNTER_RTC_STM32_CLOCK_LSE */ /* prescaler values for LSE @ 32768 Hz */ .AsynchPrescaler = 0x7F,