Skip to content

Commit e247cc3

Browse files
greavesinator85kartben
authored andcommitted
drivers: counter: stm32: config rtc prescaler from DT
Handle RTC prescaler options inside RTC counter driver Signed-off-by: Jake Greaves <[email protected]>
1 parent 20d9780 commit e247cc3

File tree

1 file changed

+50
-5
lines changed

1 file changed

+50
-5
lines changed

drivers/counter/counter_ll_stm32_rtc.c

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

100103
struct rtc_stm32_data {
@@ -592,6 +595,11 @@ static int rtc_stm32_init(const struct device *dev)
592595
}
593596
#endif
594597

598+
#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
599+
/* Must be configured before selecting the RTC clock source */
600+
LL_RCC_SetRTC_HSEPrescaler(cfg->hse_prescaler);
601+
#endif
602+
595603
if (LL_RTC_Init(RTC, ((LL_RTC_InitTypeDef *)
596604
&cfg->ll_rtc_config)) != SUCCESS) {
597605
goto out_disable_bkup_access;
@@ -629,28 +637,65 @@ static struct rtc_stm32_data rtc_data;
629637

630638
static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0);
631639

640+
#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
641+
#if STM32_HSE_FREQ % MHZ(1) != 0
642+
#error RTC clock source HSE frequency should be whole MHz
643+
#elif STM32_HSE_FREQ < MHZ(16) && defined(LL_RCC_RTC_HSE_DIV_16)
644+
#define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_16
645+
#define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 16)
646+
#elif STM32_HSE_FREQ < MHZ(32) && defined(LL_RCC_RTC_HSE_DIV_32)
647+
#define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_32
648+
#define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 32)
649+
#elif STM32_HSE_FREQ < MHZ(64) && defined(LL_RCC_RTC_HSE_DIV_64)
650+
#define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_64
651+
#define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 64)
652+
#else
653+
#error RTC does not support HSE frequency
654+
#endif
655+
#define RTC_HSE_ASYNC_PRESCALER 125
656+
#define RTC_HSE_SYNC_PRESCALER (RTC_HSE_FREQUENCY / RTC_HSE_ASYNC_PRESCALER)
657+
#endif /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE */
658+
632659
static const struct rtc_stm32_config rtc_config = {
633660
.counter_info = {
634661
.max_top_value = UINT32_MAX,
635662
#ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
636663
/* freq = 1Hz for not subsec based driver */
637664
.freq = RTCCLK_FREQ / ((RTC_ASYNCPRE + 1) * (RTC_SYNCPRE + 1)),
638-
#else /* !CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
665+
#else /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
639666
.freq = RTCCLK_FREQ / (RTC_ASYNCPRE + 1),
640667
#endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
641668
.flags = COUNTER_CONFIG_INFO_COUNT_UP,
642669
.channels = 1,
643670
},
644671
.ll_rtc_config = {
645-
.AsynchPrescaler = RTC_ASYNCPRE,
672+
#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI || \
673+
DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE
674+
.AsynchPrescaler = DT_INST_PROP_OR(0, async_prescaler, RTC_ASYNCPRE),
646675
#if !defined(CONFIG_SOC_SERIES_STM32F1X)
647676
.HourFormat = LL_RTC_HOURFORMAT_24HOUR,
648-
.SynchPrescaler = RTC_SYNCPRE,
649-
#else /* CONFIG_SOC_SERIES_STM32F1X */
677+
.SynchPrescaler = DT_INST_PROP_OR(0, sync_prescaler, RTC_SYNCPRE),
678+
#else /* !CONFIG_SOC_SERIES_STM32F1X */
650679
.OutPutSource = LL_RTC_CALIB_OUTPUT_NONE,
651-
#endif /* CONFIG_SOC_SERIES_STM32F1X */
680+
#endif /* !CONFIG_SOC_SERIES_STM32F1X */
681+
#elif DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
682+
.AsynchPrescaler =
683+
DT_INST_PROP_OR(0, async_prescaler, _HSE_ASYNC_PRESCALER - 1),
684+
#if !defined(CONFIG_SOC_SERIES_STM32F1X)
685+
.HourFormat = LL_RTC_HOURFORMAT_24HOUR,
686+
.SynchPrescaler =
687+
DT_INST_PROP_OR(0, hse_prescaler, RTC_HSE_SYNC_PRESCALER - 1),
688+
#else /* CONFIG_SOC_SERIES_STM32F1X */
689+
.OutPutSource = LL_RTC_CALIB_OUTPUT_NONE,
690+
#endif /* !CONFIG_SOC_SERIES_STM32F1X */
691+
#else
692+
#error Invalid RTC SRC
693+
#endif
652694
},
653695
.pclken = rtc_clk,
696+
#if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
697+
.hse_prescaler = DT_INST_PROP_OR(0, hse_prescaler, RTC_HSE_PRESCALER),
698+
#endif
654699
};
655700

656701
#ifdef CONFIG_PM_DEVICE

0 commit comments

Comments
 (0)