Skip to content

Commit 8bf4e52

Browse files
drivers: counter: stm32: config rtc prescaler from DT
Handle RTC prescaler options inside RTC counter driver Signed-off-by: Jake Greaves <jake.greaves@analog.com>
1 parent d09764a commit 8bf4e52

File tree

2 files changed

+60
-12
lines changed

2 files changed

+60
-12
lines changed

drivers/counter/counter_ll_stm32_rtc.c

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,9 @@ struct rtc_stm32_config {
9494
struct counter_config_info counter_info;
9595
LL_RTC_InitTypeDef ll_rtc_config;
9696
const struct stm32_pclken *pclken;
97+
#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
98+
uint32_t hse_prescaler;
99+
#endif
97100
};
98101

99102
struct rtc_stm32_data {
@@ -593,6 +596,11 @@ static int rtc_stm32_init(const struct device *dev)
593596
}
594597
#endif
595598

599+
#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
600+
/* Must be configured before selecting the RTC clock source */
601+
LL_RCC_SetRTC_HSEPrescaler(cfg->hse_prescaler);
602+
#endif
603+
596604
if (LL_RTC_Init(RTC, ((LL_RTC_InitTypeDef *)
597605
&cfg->ll_rtc_config)) != SUCCESS) {
598606
return -EIO;
@@ -623,28 +631,65 @@ static struct rtc_stm32_data rtc_data;
623631

624632
static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0);
625633

634+
#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
635+
#if STM32_HSE_FREQ % MHZ(1) != 0
636+
#error RTC clock source HSE frequency should be whole MHz
637+
#elif STM32_HSE_FREQ < MHZ(16) && defined(LL_RCC_RTC_HSE_DIV_16)
638+
#define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_16
639+
#define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 16)
640+
#elif STM32_HSE_FREQ < MHZ(32) && defined(LL_RCC_RTC_HSE_DIV_32)
641+
#define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_32
642+
#define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 32)
643+
#elif STM32_HSE_FREQ < MHZ(64) && defined(LL_RCC_RTC_HSE_DIV_64)
644+
#define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_64
645+
#define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 64)
646+
#else
647+
#error RTC does not support HSE frequency
648+
#endif
649+
#define RTC_HSE_ASYNC_PRESCALER 125
650+
#define RTC_HSE_SYNC_PRESCALER (RTC_HSE_FREQUENCY / RTC_HSE_ASYNC_PRESCALER)
651+
#endif /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE */
652+
626653
static const struct rtc_stm32_config rtc_config = {
627654
.counter_info = {
628655
.max_top_value = UINT32_MAX,
629656
#ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
630657
/* freq = 1Hz for not subsec based driver */
631658
.freq = RTCCLK_FREQ / ((RTC_ASYNCPRE + 1) * (RTC_SYNCPRE + 1)),
632-
#else /* !CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
659+
#else /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
633660
.freq = RTCCLK_FREQ / (RTC_ASYNCPRE + 1),
634-
#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
661+
#endif
635662
.flags = COUNTER_CONFIG_INFO_COUNT_UP,
636663
.channels = 1,
637664
},
638665
.ll_rtc_config = {
639-
.AsynchPrescaler = RTC_ASYNCPRE,
666+
#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI || \
667+
DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE
668+
.AsynchPrescaler = DT_INST_PROP_OR(0, async_prescaler, RTC_ASYNCPRE),
640669
#if !defined(CONFIG_SOC_SERIES_STM32F1X)
641670
.HourFormat = LL_RTC_HOURFORMAT_24HOUR,
642-
.SynchPrescaler = RTC_SYNCPRE,
643-
#else /* CONFIG_SOC_SERIES_STM32F1X */
671+
.SynchPrescaler = DT_INST_PROP_OR(0, sync_prescaler, RTC_SYNCPRE),
672+
#else /* CONFIG_SOC_SERIES_STM32F1X */
644673
.OutPutSource = LL_RTC_CALIB_OUTPUT_NONE,
645-
#endif /* CONFIG_SOC_SERIES_STM32F1X */
674+
#endif /* !CONFIG_SOC_SERIES_STM32F1X */
675+
#elif DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
676+
.AsynchPrescaler =
677+
DT_INST_PROP_OR(0, async_prescaler, _HSE_ASYNC_PRESCALER - 1),
678+
#if !defined(CONFIG_SOC_SERIES_STM32F1X)
679+
.HourFormat = LL_RTC_HOURFORMAT_24HOUR,
680+
.SynchPrescaler =
681+
DT_INST_PROP_OR(0, hse_prescaler, RTC_HSE_SYNC_PRESCALER - 1),
682+
#else /* CONFIG_SOC_SERIES_STM32F1X */
683+
.OutPutSource = LL_RTC_CALIB_OUTPUT_NONE,
684+
#endif /* !CONFIG_SOC_SERIES_STM32F1X */
685+
#else
686+
#error Invalid RTC SRC
687+
#endif
646688
},
647689
.pclken = rtc_clk,
690+
#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
691+
.hse_prescaler = DT_INST_PROP_OR(0, hse_prescaler, RTC_HSE_PRESCALER),
692+
#endif
648693
};
649694

650695
#ifdef CONFIG_PM_DEVICE

dts/bindings/rtc/st,stm32-rtc.yaml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,23 @@ properties:
1717
sync-prescaler:
1818
type: int
1919
description: |
20-
RTC synchronous prescaler value. Optional, defaulting to set values
21-
depending on source clock.
20+
RTC synchronous prescaler value. Optional, if not set defaulted in code to:
21+
- Selected to give 1 Hz tick rate, bsed on source clock frequency and asynchronous
22+
prescaler value
2223
2324
async-prescaler:
2425
type: int
2526
description: |
26-
RTC asynchronous prescaler value. Optional, defaulting to set values
27-
depending on source clock.
27+
RTC asynchronous prescaler value. Optional, if not set defaulted in code to:
28+
- 0x7F if RTC source clock is LSE/LSI
29+
- 1 if using counter with CONFIG_COUNTER_RTC_STM32_SUBSECONDS option
30+
- 0x7C if RTC source clock is HSE
2831
2932
hse-prescaler:
3033
type: int
3134
description: |
32-
RTC HSE prescaler value. Optional, defaulting to set values
33-
when HSE is selected as the source clock.
35+
RTC HSE prescaler value. Applies only when RTC source clock is HSE.
36+
Optional, defaulting to the value calculated based on HSE clock frequency.
3437
3538
calib-out-freq:
3639
type: int

0 commit comments

Comments
 (0)