1 /*
2 * Copyright (c) 2023 Prevas A/S
3 * Copyright (c) 2023 Syslinbit
4 * Copyright (c) 2024 STMicroelectronics
5 * Copyright (c) 2025 Alexander Kozhinov <ak.alexander.kozhinov@gmail.com>
6 *
7 * SPDX-License-Identifier: Apache-2.0
8 *
9 */
10
11 #define DT_DRV_COMPAT st_stm32_rtc
12
13 #include <errno.h>
14 #include <zephyr/device.h>
15 #include <zephyr/kernel.h>
16 #include <zephyr/init.h>
17 #include <zephyr/devicetree.h>
18 #include <zephyr/spinlock.h>
19 #include <zephyr/drivers/rtc.h>
20 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
21 #include <zephyr/drivers/clock_control.h>
22 #include <zephyr/sys/util.h>
23 #include <soc.h>
24 #include <stm32_ll_pwr.h>
25 #include <stm32_ll_rcc.h>
26 #include <stm32_ll_rtc.h>
27 #ifdef CONFIG_RTC_ALARM
28 #include <zephyr/drivers/interrupt_controller/intc_exti_stm32.h>
29 #endif /* CONFIG_RTC_ALARM */
30
31 #include <zephyr/logging/log.h>
32 #ifdef CONFIG_RTC_ALARM
33 #include <zephyr/irq.h>
34 #endif /* CONFIG_RTC_ALARM */
35
36 #include <stm32_backup_domain.h>
37 #include <stm32_hsem.h>
38
39 #include <stdbool.h>
40 #include "rtc_utils.h"
41
42 #include "rtc_ll_stm32.h"
43
44 LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL);
45
46 #if (defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SUBSECOND_SUPPORT)) \
47 || defined(CONFIG_SOC_SERIES_STM32F2X)
48 /* subsecond counting is not supported by some STM32L1x MCUs (Cat.1) & by STM32F2x SoC series */
49 #define HW_SUBSECOND_SUPPORT (0)
50 #else
51 #define HW_SUBSECOND_SUPPORT (1)
52 #endif
53
54 /* RTC start time: 1st, Jan, 2000 */
55 #define RTC_YEAR_REF 2000
56 /* struct tm start time: 1st, Jan, 1900 */
57 #define TM_YEAR_REF 1900
58
59 /* Convert part per billion calibration value to a number of clock pulses added or removed each
60 * 2^20 clock cycles so it is suitable for the CALR register fields
61 *
62 * nb_pulses = ppb * 2^20 / 10^9 = ppb * 2^11 / 5^9 = ppb * 2048 / 1953125
63 */
64 #define PPB_TO_NB_PULSES(ppb) DIV_ROUND_CLOSEST((ppb) * 2048, 1953125)
65
66 /* Convert CALR register value (number of clock pulses added or removed each 2^20 clock cycles)
67 * to part ber billion calibration value
68 *
69 * ppb = nb_pulses * 10^9 / 2^20 = nb_pulses * 5^9 / 2^11 = nb_pulses * 1953125 / 2048
70 */
71 #define NB_PULSES_TO_PPB(pulses) DIV_ROUND_CLOSEST((pulses) * 1953125, 2048)
72
73 /* CALP field can only be 512 or 0 as in reality CALP is a single bit field representing 512 pulses
74 * added every 2^20 clock cycles
75 */
76 #define MAX_CALP (512)
77 #define MAX_CALM (511)
78
79 #define MAX_PPB NB_PULSES_TO_PPB(MAX_CALP)
80 #define MIN_PPB -NB_PULSES_TO_PPB(MAX_CALM)
81
82 /* Timeout in microseconds used to wait for flags */
83 #define RTC_TIMEOUT 1000000
84
85 #ifdef STM32_RTC_ALARM_ENABLED
86 #define RTC_STM32_ALARMS_COUNT DT_INST_PROP(0, alarms_count)
87
88 #define RTC_STM32_ALRM_A 0U
89 #define RTC_STM32_ALRM_B 1U
90
91 /* Zephyr mask supported by RTC device, values from RTC_ALARM_TIME_MASK */
92 #define RTC_STM32_SUPPORTED_ALARM_FIELDS \
93 (RTC_ALARM_TIME_MASK_SECOND | RTC_ALARM_TIME_MASK_MINUTE \
94 | RTC_ALARM_TIME_MASK_HOUR | RTC_ALARM_TIME_MASK_WEEKDAY \
95 | RTC_ALARM_TIME_MASK_MONTHDAY)
96
97 #define RTC_STM32_EXTI_LINE_NUM DT_INST_PROP_OR(0, alrm_exti_line, 0)
98
99 #endif /* STM32_RTC_ALARM_ENABLED */
100
101 struct rtc_stm32_config {
102 uint32_t async_prescaler;
103 uint32_t sync_prescaler;
104 const struct stm32_pclken *pclken;
105 #if DT_INST_NODE_HAS_PROP(0, calib_out_freq)
106 uint32_t cal_out_freq;
107 #endif
108 #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
109 uint32_t hse_prescaler;
110 #endif
111 };
112
113 #ifdef STM32_RTC_ALARM_ENABLED
114 struct rtc_stm32_alrm {
115 LL_RTC_AlarmTypeDef ll_rtc_alrm;
116 /* user-defined alarm mask, values from RTC_ALARM_TIME_MASK */
117 uint16_t user_mask;
118 rtc_alarm_callback user_callback;
119 void *user_data;
120 bool is_pending;
121 };
122 #endif /* STM32_RTC_ALARM_ENABLED */
123
124 struct rtc_stm32_data {
125 struct k_spinlock lock;
126 #ifdef STM32_RTC_ALARM_ENABLED
127 struct rtc_stm32_alrm rtc_alrm_a;
128 struct rtc_stm32_alrm rtc_alrm_b;
129 #endif /* STM32_RTC_ALARM_ENABLED */
130 };
131
132 #ifdef STM32_RTC_ALARM_ENABLED
133
exti_enable_rtc_alarm_it(uint32_t line_num)134 static inline void exti_enable_rtc_alarm_it(uint32_t line_num)
135 {
136 #if defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX)
137 /* in STM32U5 & STM32WBAX series, RTC Alarm event is not routed to EXTI */
138 #else
139 int ret;
140
141 ret = stm32_exti_enable(line_num, STM32_EXTI_TRIG_RISING, STM32_EXTI_MODE_IT);
142 if (ret != 0) {
143 LOG_ERR("Failed to enable EXTI line number %d (error %d)", line_num, ret);
144 }
145 #endif
146 }
147
exti_clear_rtc_alarm_flag(uint32_t line_num)148 static inline void exti_clear_rtc_alarm_flag(uint32_t line_num)
149 {
150 #if defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX)
151 /* in STM32U5 & STM32WBAX series, RTC Alarm (EXTI event) is not routed to EXTI */
152 #else
153 if (stm32_exti_is_pending(line_num)) {
154 stm32_exti_clear_pending(line_num);
155 }
156 #endif
157 }
158
159 #endif /* STM32_RTC_ALARM_ENABLED */
160
rtc_stm32_configure(const struct device * dev)161 static int rtc_stm32_configure(const struct device *dev)
162 {
163 const struct rtc_stm32_config *cfg = dev->config;
164
165 int err = 0;
166
167 uint32_t hour_format = LL_RTC_GetHourFormat(RTC);
168 uint32_t sync_prescaler = LL_RTC_GetSynchPrescaler(RTC);
169 uint32_t async_prescaler = LL_RTC_GetAsynchPrescaler(RTC);
170
171 LL_RTC_DisableWriteProtection(RTC);
172
173 /* configuration process requires to stop the RTC counter so do it
174 * only if needed to avoid inducing time drift at each reset
175 */
176 if ((hour_format != LL_RTC_HOURFORMAT_24HOUR) ||
177 (sync_prescaler != cfg->sync_prescaler) ||
178 (async_prescaler != cfg->async_prescaler)) {
179 ErrorStatus status = LL_RTC_EnterInitMode(RTC);
180
181 if (status == SUCCESS) {
182 LL_RTC_SetHourFormat(RTC, LL_RTC_HOURFORMAT_24HOUR);
183 LL_RTC_SetSynchPrescaler(RTC, cfg->sync_prescaler);
184 LL_RTC_SetAsynchPrescaler(RTC, cfg->async_prescaler);
185 } else {
186 err = -EIO;
187 }
188
189 LL_RTC_DisableInitMode(RTC);
190 }
191
192 #if DT_INST_NODE_HAS_PROP(0, calib_out_freq)
193 LL_RTC_CAL_SetOutputFreq(RTC, cfg->cal_out_freq);
194 #else
195 LL_RTC_CAL_SetOutputFreq(RTC, LL_RTC_CALIB_OUTPUT_NONE);
196 #endif
197
198 #ifdef RTC_CR_BYPSHAD
199 LL_RTC_EnableShadowRegBypass(RTC);
200 #endif /* RTC_CR_BYPSHAD */
201
202 LL_RTC_EnableWriteProtection(RTC);
203
204 return err;
205 }
206
207 #ifdef STM32_RTC_ALARM_ENABLED
rtc_stm32_init_alarm(RTC_TypeDef * rtc,uint32_t format,LL_RTC_AlarmTypeDef * ll_alarm_struct,uint16_t id)208 static inline ErrorStatus rtc_stm32_init_alarm(RTC_TypeDef *rtc, uint32_t format,
209 LL_RTC_AlarmTypeDef *ll_alarm_struct, uint16_t id)
210 {
211 ll_alarm_struct->AlarmDateWeekDaySel = RTC_STM32_ALRM_DATEWEEKDAYSEL_DATE;
212 /*
213 * RTC write protection is disabled & enabled again inside LL_RTC_ALMx_Init functions
214 * The LL_RTC_ALMx_Init does convert bin2bcd by itself
215 */
216 if (id == RTC_STM32_ALRM_A) {
217 return LL_RTC_ALMA_Init(rtc, format, ll_alarm_struct);
218 }
219 #if RTC_STM32_ALARMS_COUNT > 1
220 if (id == RTC_STM32_ALRM_B) {
221 return LL_RTC_ALMB_Init(rtc, format, ll_alarm_struct);
222 }
223 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
224
225 return 0;
226 }
227
rtc_stm32_clear_alarm_flag(RTC_TypeDef * rtc,uint16_t id)228 static inline void rtc_stm32_clear_alarm_flag(RTC_TypeDef *rtc, uint16_t id)
229 {
230 if (id == RTC_STM32_ALRM_A) {
231 LL_RTC_ClearFlag_ALRA(rtc);
232 return;
233 }
234 #if RTC_STM32_ALARMS_COUNT > 1
235 if (id == RTC_STM32_ALRM_B) {
236 LL_RTC_ClearFlag_ALRB(rtc);
237 }
238 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
239 }
240
rtc_stm32_is_active_alarm(RTC_TypeDef * rtc,uint16_t id)241 static inline uint32_t rtc_stm32_is_active_alarm(RTC_TypeDef *rtc, uint16_t id)
242 {
243 if (id == RTC_STM32_ALRM_A) {
244 return LL_RTC_IsActiveFlag_ALRA(rtc);
245 }
246 #if RTC_STM32_ALARMS_COUNT > 1
247 if (id == RTC_STM32_ALRM_B) {
248 return LL_RTC_IsActiveFlag_ALRB(rtc);
249 }
250 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
251
252 return 0;
253 }
254
rtc_stm32_enable_interrupt_alarm(RTC_TypeDef * rtc,uint16_t id)255 static inline void rtc_stm32_enable_interrupt_alarm(RTC_TypeDef *rtc, uint16_t id)
256 {
257 if (id == RTC_STM32_ALRM_A) {
258 LL_RTC_EnableIT_ALRA(rtc);
259 return;
260 }
261 #if RTC_STM32_ALARMS_COUNT > 1
262 if (id == RTC_STM32_ALRM_B) {
263 LL_RTC_EnableIT_ALRB(rtc);
264 }
265 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
266 }
267
rtc_stm32_disable_interrupt_alarm(RTC_TypeDef * rtc,uint16_t id)268 static inline void rtc_stm32_disable_interrupt_alarm(RTC_TypeDef *rtc, uint16_t id)
269 {
270 if (id == RTC_STM32_ALRM_A) {
271 LL_RTC_DisableIT_ALRA(rtc);
272 return;
273 }
274 #if RTC_STM32_ALARMS_COUNT > 1
275 if (id == RTC_STM32_ALRM_B) {
276 LL_RTC_DisableIT_ALRB(rtc);
277 }
278 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
279 }
280
rtc_stm32_enable_alarm(RTC_TypeDef * rtc,uint16_t id)281 static inline void rtc_stm32_enable_alarm(RTC_TypeDef *rtc, uint16_t id)
282 {
283 if (id == RTC_STM32_ALRM_A) {
284 LL_RTC_ALMA_Enable(rtc);
285 return;
286 }
287 #if RTC_STM32_ALARMS_COUNT > 1
288 if (id == RTC_STM32_ALRM_B) {
289 LL_RTC_ALMB_Enable(rtc);
290 }
291 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
292 }
293
rtc_stm32_disable_alarm(RTC_TypeDef * rtc,uint16_t id)294 static inline void rtc_stm32_disable_alarm(RTC_TypeDef *rtc, uint16_t id)
295 {
296 if (id == RTC_STM32_ALRM_A) {
297 LL_RTC_ALMA_Disable(rtc);
298 return;
299 }
300 #if RTC_STM32_ALARMS_COUNT > 1
301 if (id == RTC_STM32_ALRM_B) {
302 LL_RTC_ALMB_Disable(rtc);
303 }
304 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
305 }
306
rtc_stm32_isr(const struct device * dev)307 void rtc_stm32_isr(const struct device *dev)
308 {
309 struct rtc_stm32_data *data = dev->data;
310 struct rtc_stm32_alrm *p_rtc_alrm;
311 int id = 0;
312
313 for (id = 0; id < RTC_STM32_ALARMS_COUNT; id++) {
314 if (rtc_stm32_is_active_alarm(RTC, (uint16_t)id) != 0) {
315 stm32_backup_domain_enable_access();
316 LL_RTC_DisableWriteProtection(RTC);
317 rtc_stm32_clear_alarm_flag(RTC, (uint16_t)id);
318 LL_RTC_EnableWriteProtection(RTC);
319 stm32_backup_domain_disable_access();
320
321 if (id == RTC_STM32_ALRM_A) {
322 p_rtc_alrm = &(data->rtc_alrm_a);
323 } else {
324 p_rtc_alrm = &(data->rtc_alrm_b);
325 }
326
327 p_rtc_alrm->is_pending = true;
328
329 if (p_rtc_alrm->user_callback != NULL) {
330 p_rtc_alrm->user_callback(dev, (uint16_t)id, p_rtc_alrm->user_data);
331 }
332 }
333 }
334
335 exti_clear_rtc_alarm_flag(RTC_STM32_EXTI_LINE_NUM);
336 }
337
rtc_stm32_irq_config(const struct device * dev)338 static void rtc_stm32_irq_config(const struct device *dev)
339 {
340 IRQ_CONNECT(DT_INST_IRQN(0),
341 DT_INST_IRQ(0, priority),
342 rtc_stm32_isr, DEVICE_DT_INST_GET(0), 0);
343 irq_enable(DT_INST_IRQN(0));
344 }
345 #endif /* STM32_RTC_ALARM_ENABLED */
346
rtc_stm32_init(const struct device * dev)347 static int rtc_stm32_init(const struct device *dev)
348 {
349 const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
350 const struct rtc_stm32_config *cfg = dev->config;
351 __maybe_unused struct rtc_stm32_data *data = dev->data;
352
353 int err = 0;
354
355 if (!device_is_ready(clk)) {
356 LOG_ERR("clock control device not ready");
357 return -ENODEV;
358 }
359
360 /* Enable RTC bus clock */
361 if (clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken[0]) != 0) {
362 LOG_ERR("clock op failed\n");
363 return -EIO;
364 }
365
366 #if defined(CONFIG_SOC_SERIES_STM32WB0X)
367 /**
368 * The STM32WB0 series has no bit for clock gating of RTC's APB
369 * interface. On the other hand, the RTCEN bit that would control
370 * whether the RTC IP is clock gated or not exists, and has been
371 * placed in APB0ENR. The call to clock_control_on() that just
372 * completed should have set this bit to 1.
373 *
374 * However, according to RefMan, the software must wait two slow
375 * clock cycles before the IP is actually usable, due to clock
376 * resynchronization delays. Sadly, there is no hardware register
377 * we can poll to wait until RTC is ready...
378 *
379 * In worst case scenario of 24 kHz LSI, we have to wait for:
380 * tREADY = (2 cycles / 24'000 Hz) ≅ 84µs
381 *
382 * Spin until that much time has elapsed, and RTC should be up.
383 *
384 * N.B.: we can't use k_busy_wait because it uses the SysTick
385 * as time base, but SysTick is initialized after the RTC...
386 */
387 const uint32_t cycles_to_waste =
388 84 * (CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / USEC_PER_SEC);
389 volatile uint32_t i = cycles_to_waste;
390
391 while (--i > 0) {
392 /* Do nothing - loop itself burns enough cycles */
393 }
394 #endif /* CONFIG_SOC_SERIES_STM32WB0X */
395
396 stm32_backup_domain_enable_access();
397
398 #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
399 /* Must be configured before selecting the RTC clock source */
400 LL_RCC_SetRTC_HSEPrescaler(cfg->hse_prescaler);
401 #endif
402 /* Enable RTC clock source */
403 if (cfg->pclken[1].enr != NO_SEL) {
404 err = clock_control_configure(clk, (clock_control_subsys_t)&cfg->pclken[1], NULL);
405
406 if (err < 0) {
407 stm32_backup_domain_disable_access();
408 LOG_ERR("clock configure failed\n");
409 return -EIO;
410 }
411 }
412
413 /*
414 * On STM32WBAX series, there is no bit in BCDR register to enable RTC.
415 * Enabling RTC is done directly via the RCC APB register bit.
416 * On STM32WB0 series, LL_RCC_EnableRTC is not provided by STM32CubeWB0,
417 * but RTC IP clock has already been turned on - skip the call as well.
418 */
419 #if !defined(CONFIG_SOC_SERIES_STM32WBAX) && !defined(CONFIG_SOC_SERIES_STM32WB0X)
420 z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
421
422 LL_RCC_EnableRTC();
423
424 z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
425 #endif /* CONFIG_SOC_SERIES_STM32WBAX */
426
427 err = rtc_stm32_configure(dev);
428
429 stm32_backup_domain_disable_access();
430
431 #ifdef STM32_RTC_ALARM_ENABLED
432 rtc_stm32_irq_config(dev);
433
434 exti_enable_rtc_alarm_it(RTC_STM32_EXTI_LINE_NUM);
435
436 K_SPINLOCK(&data->lock) {
437 memset(&(data->rtc_alrm_a), 0, sizeof(struct rtc_stm32_alrm));
438 memset(&(data->rtc_alrm_b), 0, sizeof(struct rtc_stm32_alrm));
439 }
440 #endif /* CONFIG_RTC_ALARM */
441
442 return err;
443 }
444
rtc_stm32_set_time(const struct device * dev,const struct rtc_time * timeptr)445 static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *timeptr)
446 {
447 struct rtc_stm32_data *data = dev->data;
448 LL_RTC_TimeTypeDef rtc_time;
449 LL_RTC_DateTypeDef rtc_date;
450 uint32_t real_year = timeptr->tm_year + TM_YEAR_REF;
451
452 if (real_year < RTC_YEAR_REF) {
453 /* RTC does not support years before 2000 */
454 return -EINVAL;
455 }
456
457 if (timeptr->tm_wday == -1) {
458 /* day of the week is expected */
459 return -EINVAL;
460 }
461
462 /* Enter Init mode inside the LL_RTC_Time and Date Init functions */
463 rtc_time.Hours = bin2bcd(timeptr->tm_hour);
464 rtc_time.Minutes = bin2bcd(timeptr->tm_min);
465 rtc_time.Seconds = bin2bcd(timeptr->tm_sec);
466
467 /* Set Date after Time to be sure the DR is correctly updated on stm32F2 serie. */
468 rtc_date.Year = bin2bcd((real_year - RTC_YEAR_REF));
469 rtc_date.Month = bin2bcd((timeptr->tm_mon + 1));
470 rtc_date.Day = bin2bcd(timeptr->tm_mday);
471 rtc_date.WeekDay = ((timeptr->tm_wday == 0) ? (LL_RTC_WEEKDAY_SUNDAY) : (timeptr->tm_wday));
472 /* WeekDay sunday (tm_wday = 0) is not represented by the same value in hardware,
473 * all the other values are consistent with what is expected by hardware.
474 */
475
476 LOG_DBG("Setting clock");
477
478 k_spinlock_key_t key = k_spin_lock(&data->lock);
479
480 stm32_backup_domain_enable_access();
481
482 LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BCD, &rtc_time);
483 LL_RTC_DATE_Init(RTC, LL_RTC_FORMAT_BCD, &rtc_date);
484
485 stm32_backup_domain_disable_access();
486
487 #ifdef CONFIG_SOC_SERIES_STM32F2X
488 /*
489 * Because stm32F2 serie has no shadow registers,
490 * wait until TR and DR registers are synchronised : flag RS
491 */
492 while (LL_RTC_IsActiveFlag_RS(RTC) != 1) {
493 ;
494 }
495 #endif /* CONFIG_SOC_SERIES_STM32F2X */
496
497 LOG_DBG("Calendar set : %d/%d/%d - %dh%dm%ds",
498 LL_RTC_DATE_GetDay(RTC),
499 LL_RTC_DATE_GetMonth(RTC),
500 LL_RTC_DATE_GetYear(RTC),
501 LL_RTC_TIME_GetHour(RTC),
502 LL_RTC_TIME_GetMinute(RTC),
503 LL_RTC_TIME_GetSecond(RTC)
504 );
505
506 k_spin_unlock(&data->lock, key);
507
508 return 0;
509 }
510
rtc_stm32_get_time(const struct device * dev,struct rtc_time * timeptr)511 static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr)
512 {
513 struct rtc_stm32_data *data = dev->data;
514
515 uint32_t rtc_date, rtc_time;
516
517 #if HW_SUBSECOND_SUPPORT
518 const struct rtc_stm32_config *cfg = dev->config;
519 uint32_t rtc_subsecond;
520 #endif /* HW_SUBSECOND_SUPPORT */
521
522 if (timeptr == NULL) {
523 LOG_ERR("NULL rtc_time pointer");
524 return -EINVAL;
525 }
526
527 k_spinlock_key_t key = k_spin_lock(&data->lock);
528
529 if (!LL_RTC_IsActiveFlag_INITS(RTC)) {
530 /* INITS flag is set when the calendar has been initialiazed. This flag is
531 * reset only on backup domain reset, so it can be read after a system
532 * reset to check if the calendar has been initialized.
533 */
534 k_spin_unlock(&data->lock, key);
535 return -ENODATA;
536 }
537
538 do {
539 /* read date, time and subseconds and relaunch if a day increment occurred
540 * while doing so as it will result in an erroneous result otherwise
541 */
542 rtc_date = LL_RTC_DATE_Get(RTC);
543 do {
544 /* read time and subseconds and relaunch if a second increment occurred
545 * while doing so as it will result in an erroneous result otherwise
546 */
547 rtc_time = LL_RTC_TIME_Get(RTC);
548 #if HW_SUBSECOND_SUPPORT
549 rtc_subsecond = LL_RTC_TIME_GetSubSecond(RTC);
550 #endif /* HW_SUBSECOND_SUPPORT */
551 } while (rtc_time != LL_RTC_TIME_Get(RTC));
552 } while (rtc_date != LL_RTC_DATE_Get(RTC));
553
554 k_spin_unlock(&data->lock, key);
555
556 /* tm_year is the value since 1900 and Rtc year is from 2000 */
557 timeptr->tm_year = bcd2bin(__LL_RTC_GET_YEAR(rtc_date)) + (RTC_YEAR_REF - TM_YEAR_REF);
558 /* tm_mon allowed values are 0-11 */
559 timeptr->tm_mon = bcd2bin(__LL_RTC_GET_MONTH(rtc_date)) - 1;
560 timeptr->tm_mday = bcd2bin(__LL_RTC_GET_DAY(rtc_date));
561
562 int hw_wday = __LL_RTC_GET_WEEKDAY(rtc_date);
563
564 if (hw_wday == LL_RTC_WEEKDAY_SUNDAY) {
565 /* LL_RTC_WEEKDAY_SUNDAY = 7 but a 0 is expected in tm_wday for sunday */
566 timeptr->tm_wday = 0;
567 } else {
568 /* all other values are consistent between hardware and rtc_time structure */
569 timeptr->tm_wday = hw_wday;
570 }
571
572 timeptr->tm_hour = bcd2bin(__LL_RTC_GET_HOUR(rtc_time));
573 timeptr->tm_min = bcd2bin(__LL_RTC_GET_MINUTE(rtc_time));
574 timeptr->tm_sec = bcd2bin(__LL_RTC_GET_SECOND(rtc_time));
575
576 #if HW_SUBSECOND_SUPPORT
577 uint64_t temp = ((uint64_t)(cfg->sync_prescaler - rtc_subsecond)) * 1000000000L;
578
579 timeptr->tm_nsec = temp / (cfg->sync_prescaler + 1);
580 #else
581 timeptr->tm_nsec = 0;
582 #endif
583 /* unknown values */
584 timeptr->tm_yday = -1;
585 timeptr->tm_isdst = -1;
586
587 /* __LL_RTC_GET_YEAR(rtc_date)is the real year (from 2000) */
588 LOG_DBG("Calendar get : %d/%d/%d - %dh%dm%ds",
589 timeptr->tm_mday,
590 timeptr->tm_mon,
591 __LL_RTC_GET_YEAR(rtc_date),
592 timeptr->tm_hour,
593 timeptr->tm_min,
594 timeptr->tm_sec);
595
596 return 0;
597 }
598
599 #ifdef STM32_RTC_ALARM_ENABLED
rtc_stm32_init_ll_alrm_struct(LL_RTC_AlarmTypeDef * p_rtc_alarm,const struct rtc_time * timeptr,uint16_t mask)600 static void rtc_stm32_init_ll_alrm_struct(LL_RTC_AlarmTypeDef *p_rtc_alarm,
601 const struct rtc_time *timeptr, uint16_t mask)
602 {
603 LL_RTC_TimeTypeDef *p_rtc_alrm_time = &(p_rtc_alarm->AlarmTime);
604 uint32_t ll_mask = 0;
605
606 /*
607 * STM32 RTC Alarm LL mask should be set for all fields beyond the broadest one
608 * that's being matched with RTC calendar to trigger alarm periodically,
609 * the opposite of Zephyr RTC Alarm mask which is set for active fields.
610 */
611 ll_mask = RTC_STM32_ALRM_MASK_ALL;
612
613 if (mask & RTC_ALARM_TIME_MASK_SECOND) {
614 ll_mask &= ~RTC_STM32_ALRM_MASK_SECONDS;
615 p_rtc_alrm_time->Seconds = bin2bcd(timeptr->tm_sec);
616 }
617
618 if (mask & RTC_ALARM_TIME_MASK_MINUTE) {
619 ll_mask &= ~RTC_STM32_ALRM_MASK_MINUTES;
620 p_rtc_alrm_time->Minutes = bin2bcd(timeptr->tm_min);
621 }
622
623 if (mask & RTC_ALARM_TIME_MASK_HOUR) {
624 ll_mask &= ~RTC_STM32_ALRM_MASK_HOURS;
625 p_rtc_alrm_time->Hours = bin2bcd(timeptr->tm_hour);
626 }
627
628 if (mask & RTC_ALARM_TIME_MASK_WEEKDAY) {
629 /* the Alarm Mask field compares with the day of the week */
630 ll_mask &= ~RTC_STM32_ALRM_MASK_DATEWEEKDAY;
631 p_rtc_alarm->AlarmDateWeekDaySel = RTC_STM32_ALRM_DATEWEEKDAYSEL_WEEKDAY;
632
633 if (timeptr->tm_wday == 0) {
634 /* sunday (tm_wday = 0) is not represented by the same value in hardware */
635 p_rtc_alarm->AlarmDateWeekDay = LL_RTC_WEEKDAY_SUNDAY;
636 } else {
637 /* all the other values are consistent with what is expected by hardware */
638 p_rtc_alarm->AlarmDateWeekDay = bin2bcd(timeptr->tm_wday);
639 }
640
641 } else if (mask & RTC_ALARM_TIME_MASK_MONTHDAY) {
642 /* the Alarm compares with the day number & ignores the day of the week */
643 ll_mask &= ~RTC_STM32_ALRM_MASK_DATEWEEKDAY;
644 p_rtc_alarm->AlarmDateWeekDaySel = RTC_STM32_ALRM_DATEWEEKDAYSEL_DATE;
645 p_rtc_alarm->AlarmDateWeekDay = bin2bcd(timeptr->tm_mday);
646 }
647
648 p_rtc_alrm_time->TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
649
650 p_rtc_alarm->AlarmMask = ll_mask;
651 }
652
rtc_stm32_get_ll_alrm_time(uint16_t id,struct rtc_time * timeptr)653 static inline void rtc_stm32_get_ll_alrm_time(uint16_t id, struct rtc_time *timeptr)
654 {
655 if (id == RTC_STM32_ALRM_A) {
656 timeptr->tm_sec = bcd2bin(LL_RTC_ALMA_GetSecond(RTC));
657 timeptr->tm_min = bcd2bin(LL_RTC_ALMA_GetMinute(RTC));
658 timeptr->tm_hour = bcd2bin(LL_RTC_ALMA_GetHour(RTC));
659 timeptr->tm_wday = bcd2bin(LL_RTC_ALMA_GetWeekDay(RTC));
660 timeptr->tm_mday = bcd2bin(LL_RTC_ALMA_GetDay(RTC));
661 return;
662 }
663 #if RTC_STM32_ALARMS_COUNT > 1
664 if (id == RTC_STM32_ALRM_B) {
665 timeptr->tm_sec = bcd2bin(LL_RTC_ALMB_GetSecond(RTC));
666 timeptr->tm_min = bcd2bin(LL_RTC_ALMB_GetMinute(RTC));
667 timeptr->tm_hour = bcd2bin(LL_RTC_ALMB_GetHour(RTC));
668 timeptr->tm_wday = bcd2bin(LL_RTC_ALMB_GetWeekDay(RTC));
669 timeptr->tm_mday = bcd2bin(LL_RTC_ALMB_GetDay(RTC));
670 }
671 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
672 }
673
rtc_stm32_get_ll_alrm_mask(uint16_t id)674 static inline uint16_t rtc_stm32_get_ll_alrm_mask(uint16_t id)
675 {
676 uint32_t ll_alarm_mask = 0;
677 uint16_t zephyr_alarm_mask = 0;
678 uint32_t week_day = 0;
679
680 /*
681 * STM32 RTC Alarm LL mask is set for all fields beyond the broadest one
682 * that's being matched with RTC calendar to trigger alarm periodically,
683 * the opposite of Zephyr RTC Alarm mask which is set for active fields.
684 */
685
686 if (id == RTC_STM32_ALRM_A) {
687 ll_alarm_mask = LL_RTC_ALMA_GetMask(RTC);
688 }
689
690 #if RTC_STM32_ALARMS_COUNT > 1
691 if (id == RTC_STM32_ALRM_B) {
692 ll_alarm_mask = LL_RTC_ALMB_GetMask(RTC);
693 }
694 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
695
696 if ((ll_alarm_mask & RTC_STM32_ALRM_MASK_SECONDS) == 0x0) {
697 zephyr_alarm_mask = RTC_ALARM_TIME_MASK_SECOND;
698 }
699 if ((ll_alarm_mask & RTC_STM32_ALRM_MASK_MINUTES) == 0x0) {
700 zephyr_alarm_mask |= RTC_ALARM_TIME_MASK_MINUTE;
701 }
702 if ((ll_alarm_mask & RTC_STM32_ALRM_MASK_HOURS) == 0x0) {
703 zephyr_alarm_mask |= RTC_ALARM_TIME_MASK_HOUR;
704 }
705 if ((ll_alarm_mask & RTC_STM32_ALRM_MASK_DATEWEEKDAY) == 0x0) {
706 if (id == RTC_STM32_ALRM_A) {
707 week_day = LL_RTC_ALMA_GetWeekDay(RTC);
708 }
709 #if RTC_STM32_ALARMS_COUNT > 1
710 if (id == RTC_STM32_ALRM_B) {
711 week_day = LL_RTC_ALMB_GetWeekDay(RTC);
712 }
713 #endif /* RTC_STM32_ALARMS_COUNT > 1 */
714 if (week_day) {
715 zephyr_alarm_mask |= RTC_ALARM_TIME_MASK_WEEKDAY;
716 } else {
717 zephyr_alarm_mask |= RTC_ALARM_TIME_MASK_MONTHDAY;
718 }
719 }
720
721 return zephyr_alarm_mask;
722 }
723
rtc_stm32_alarm_get_supported_fields(const struct device * dev,uint16_t id,uint16_t * mask)724 static int rtc_stm32_alarm_get_supported_fields(const struct device *dev, uint16_t id,
725 uint16_t *mask)
726 {
727 if (mask == NULL) {
728 LOG_ERR("NULL mask pointer");
729 return -EINVAL;
730 }
731
732 if ((id != RTC_STM32_ALRM_A) && (id != RTC_STM32_ALRM_B)) {
733 LOG_ERR("invalid alarm ID %d", id);
734 return -EINVAL;
735 }
736
737 *mask = (uint16_t)RTC_STM32_SUPPORTED_ALARM_FIELDS;
738
739 return 0;
740 }
741
rtc_stm32_alarm_get_time(const struct device * dev,uint16_t id,uint16_t * mask,struct rtc_time * timeptr)742 static int rtc_stm32_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
743 struct rtc_time *timeptr)
744 {
745 struct rtc_stm32_data *data = dev->data;
746 struct rtc_stm32_alrm *p_rtc_alrm;
747 LL_RTC_AlarmTypeDef *p_ll_rtc_alarm;
748 LL_RTC_TimeTypeDef *p_ll_rtc_alrm_time;
749 int err = 0;
750
751 if ((mask == NULL) || (timeptr == NULL)) {
752 LOG_ERR("NULL pointer");
753 return -EINVAL;
754 }
755
756 k_spinlock_key_t key = k_spin_lock(&data->lock);
757
758 if (id == RTC_STM32_ALRM_A) {
759 p_rtc_alrm = &(data->rtc_alrm_a);
760 } else if (id == RTC_STM32_ALRM_B) {
761 p_rtc_alrm = &(data->rtc_alrm_b);
762 } else {
763 LOG_ERR("invalid alarm ID %d", id);
764 err = -EINVAL;
765 goto unlock;
766 }
767
768 p_ll_rtc_alarm = &(p_rtc_alrm->ll_rtc_alrm);
769 p_ll_rtc_alrm_time = &(p_ll_rtc_alarm->AlarmTime);
770
771 memset(timeptr, -1, sizeof(struct rtc_time));
772
773 rtc_stm32_get_ll_alrm_time(id, timeptr);
774
775 p_rtc_alrm->user_mask = rtc_stm32_get_ll_alrm_mask(id);
776
777 *mask = p_rtc_alrm->user_mask;
778
779 LOG_DBG("get alarm: mday = %d, wday = %d, hour = %d, min = %d, sec = %d, "
780 "mask = 0x%04x", timeptr->tm_mday, timeptr->tm_wday, timeptr->tm_hour,
781 timeptr->tm_min, timeptr->tm_sec, *mask);
782
783 unlock:
784 k_spin_unlock(&data->lock, key);
785
786 return err;
787 }
788
rtc_stm32_alarm_set_time(const struct device * dev,uint16_t id,uint16_t mask,const struct rtc_time * timeptr)789 static int rtc_stm32_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
790 const struct rtc_time *timeptr)
791 {
792 struct rtc_stm32_data *data = dev->data;
793 struct rtc_stm32_alrm *p_rtc_alrm;
794 LL_RTC_AlarmTypeDef *p_ll_rtc_alarm;
795 LL_RTC_TimeTypeDef *p_ll_rtc_alrm_time;
796 int err = 0;
797
798 k_spinlock_key_t key = k_spin_lock(&data->lock);
799
800 if (id == RTC_STM32_ALRM_A) {
801 p_rtc_alrm = &(data->rtc_alrm_a);
802 } else if (id == RTC_STM32_ALRM_B) {
803 p_rtc_alrm = &(data->rtc_alrm_b);
804 } else {
805 LOG_ERR("invalid alarm ID %d", id);
806 err = -EINVAL;
807 goto unlock;
808 }
809
810 if ((mask == 0) && (timeptr == NULL)) {
811 memset(&(p_rtc_alrm->ll_rtc_alrm), 0, sizeof(LL_RTC_AlarmTypeDef));
812 p_rtc_alrm->user_callback = NULL;
813 p_rtc_alrm->user_data = NULL;
814 p_rtc_alrm->is_pending = false;
815
816 stm32_backup_domain_enable_access();
817
818 if (rtc_stm32_is_active_alarm(RTC, id)) {
819 LL_RTC_DisableWriteProtection(RTC);
820 rtc_stm32_disable_alarm(RTC, id);
821 rtc_stm32_disable_interrupt_alarm(RTC, id);
822 LL_RTC_EnableWriteProtection(RTC);
823 }
824 LOG_DBG("Alarm %d has been disabled", id);
825 goto disable_bkup_access;
826 }
827
828 if ((mask & ~RTC_STM32_SUPPORTED_ALARM_FIELDS) != 0) {
829 LOG_ERR("unsupported alarm %d field mask 0x%04x", id, mask);
830 err = -EINVAL;
831 goto unlock;
832 }
833
834 if (timeptr == NULL) {
835 LOG_ERR("timeptr is invalid");
836 err = -EINVAL;
837 goto unlock;
838 }
839
840 if (!rtc_utils_validate_rtc_time(timeptr, mask)) {
841 LOG_DBG("One or multiple time values are invalid");
842 err = -EINVAL;
843 goto unlock;
844 }
845
846 p_ll_rtc_alarm = &(p_rtc_alrm->ll_rtc_alrm);
847 p_ll_rtc_alrm_time = &(p_ll_rtc_alarm->AlarmTime);
848
849 memset(p_ll_rtc_alrm_time, 0, sizeof(LL_RTC_TimeTypeDef));
850 rtc_stm32_init_ll_alrm_struct(p_ll_rtc_alarm, timeptr, mask);
851
852 p_rtc_alrm->user_mask = mask;
853
854 LOG_DBG("set alarm %d : second = %d, min = %d, hour = %d,"
855 " wday = %d, mday = %d, mask = 0x%04x",
856 id, timeptr->tm_sec, timeptr->tm_min, timeptr->tm_hour,
857 timeptr->tm_wday, timeptr->tm_mday, mask);
858
859 stm32_backup_domain_enable_access();
860
861 /* Disable the write protection for RTC registers */
862 LL_RTC_DisableWriteProtection(RTC);
863
864 /* Disable ALARM so that the RTC_ISR_ALRAWF/RTC_ISR_ALRBWF is 0 */
865 rtc_stm32_disable_alarm(RTC, id);
866 rtc_stm32_disable_interrupt_alarm(RTC, id);
867
868 #ifdef RTC_ISR_ALRAWF
869 if (id == RTC_STM32_ALRM_A) {
870 /* Wait till RTC ALRAWF flag is set before writing to RTC registers */
871 while (!LL_RTC_IsActiveFlag_ALRAW(RTC)) {
872 ;
873 }
874 }
875 #endif /* RTC_ISR_ALRAWF */
876
877 #ifdef RTC_ISR_ALRBWF
878 if (id == RTC_STM32_ALRM_B) {
879 /* Wait till RTC ALRBWF flag is set before writing to RTC registers */
880 while (!LL_RTC_IsActiveFlag_ALRBW(RTC)) {
881 ;
882 }
883 }
884 #endif /* RTC_ISR_ALRBWF */
885
886 /* init Alarm */
887 /* write protection is disabled & enabled again inside the LL_RTC_ALMx_Init function */
888 if (rtc_stm32_init_alarm(RTC, LL_RTC_FORMAT_BCD, p_ll_rtc_alarm, id) != SUCCESS) {
889 LOG_ERR("Could not initialize Alarm %d", id);
890 err = -ECANCELED;
891 goto disable_bkup_access;
892 }
893
894 /* Disable the write protection for RTC registers */
895 LL_RTC_DisableWriteProtection(RTC);
896
897 /* Enable Alarm */
898 rtc_stm32_enable_alarm(RTC, id);
899 /* Clear Alarm flag */
900 rtc_stm32_clear_alarm_flag(RTC, id);
901 /* Enable Alarm IT */
902 rtc_stm32_enable_interrupt_alarm(RTC, id);
903
904 exti_enable_rtc_alarm_it(RTC_STM32_EXTI_LINE_NUM);
905
906 /* Enable the write protection for RTC registers */
907 LL_RTC_EnableWriteProtection(RTC);
908
909 disable_bkup_access:
910 stm32_backup_domain_disable_access();
911
912 unlock:
913 k_spin_unlock(&data->lock, key);
914
915 if (id == RTC_STM32_ALRM_A) {
916 LOG_DBG("Alarm A : %dh%dm%ds mask = 0x%x",
917 LL_RTC_ALMA_GetHour(RTC),
918 LL_RTC_ALMA_GetMinute(RTC),
919 LL_RTC_ALMA_GetSecond(RTC),
920 LL_RTC_ALMA_GetMask(RTC));
921 }
922 #ifdef RTC_ALARM_B
923 if (id == RTC_STM32_ALRM_B) {
924 LOG_DBG("Alarm B : %dh%dm%ds mask = 0x%x",
925 LL_RTC_ALMB_GetHour(RTC),
926 LL_RTC_ALMB_GetMinute(RTC),
927 LL_RTC_ALMB_GetSecond(RTC),
928 LL_RTC_ALMB_GetMask(RTC));
929 }
930 #endif /* #ifdef RTC_ALARM_B */
931 return err;
932 }
933
rtc_stm32_alarm_set_callback(const struct device * dev,uint16_t id,rtc_alarm_callback callback,void * user_data)934 static int rtc_stm32_alarm_set_callback(const struct device *dev, uint16_t id,
935 rtc_alarm_callback callback, void *user_data)
936 {
937 struct rtc_stm32_data *data = dev->data;
938 struct rtc_stm32_alrm *p_rtc_alrm;
939 int err = 0;
940
941 k_spinlock_key_t key = k_spin_lock(&data->lock);
942
943 if (id == RTC_STM32_ALRM_A) {
944 p_rtc_alrm = &(data->rtc_alrm_a);
945 } else if (id == RTC_STM32_ALRM_B) {
946 p_rtc_alrm = &(data->rtc_alrm_b);
947 } else {
948 LOG_ERR("invalid alarm ID %d", id);
949 err = -EINVAL;
950 goto unlock;
951 }
952
953 /* Passing the callback function and userdata filled by the user */
954 p_rtc_alrm->user_callback = callback;
955 p_rtc_alrm->user_data = user_data;
956
957 unlock:
958 k_spin_unlock(&data->lock, key);
959
960 return err;
961 }
962
rtc_stm32_alarm_is_pending(const struct device * dev,uint16_t id)963 static int rtc_stm32_alarm_is_pending(const struct device *dev, uint16_t id)
964 {
965 struct rtc_stm32_data *data = dev->data;
966 struct rtc_stm32_alrm *p_rtc_alrm;
967 int ret = 0;
968
969 k_spinlock_key_t key = k_spin_lock(&data->lock);
970
971 if (id == RTC_STM32_ALRM_A) {
972 p_rtc_alrm = &(data->rtc_alrm_a);
973 } else if (id == RTC_STM32_ALRM_B) {
974 p_rtc_alrm = &(data->rtc_alrm_b);
975 } else {
976 LOG_ERR("invalid alarm ID %d", id);
977 ret = -EINVAL;
978 goto unlock;
979 }
980
981 __disable_irq();
982 ret = p_rtc_alrm->is_pending ? 1 : 0;
983 p_rtc_alrm->is_pending = false;
984 __enable_irq();
985
986 unlock:
987 k_spin_unlock(&data->lock, key);
988 return ret;
989 }
990 #endif /* STM32_RTC_ALARM_ENABLED */
991
992 #ifdef CONFIG_RTC_CALIBRATION
993 #if !defined(CONFIG_SOC_SERIES_STM32F2X) && \
994 !(defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SMOOTHCALIB_SUPPORT))
rtc_stm32_set_calibration(const struct device * dev,int32_t calibration)995 static int rtc_stm32_set_calibration(const struct device *dev, int32_t calibration)
996 {
997 ARG_UNUSED(dev);
998
999 /* Note : calibration is considered here to be ppb value to apply
1000 * on clock period (not frequency) but with an opposite sign
1001 */
1002
1003 if ((calibration > MAX_PPB) || (calibration < MIN_PPB)) {
1004 /* out of supported range */
1005 return -EINVAL;
1006 }
1007
1008 int32_t nb_pulses = PPB_TO_NB_PULSES(calibration);
1009
1010 /* we tested calibration against supported range
1011 * so theoretically nb_pulses is also within range
1012 */
1013 __ASSERT_NO_MSG(nb_pulses <= MAX_CALP);
1014 __ASSERT_NO_MSG(nb_pulses >= -MAX_CALM);
1015
1016 uint32_t calp, calm;
1017
1018 if (nb_pulses > 0) {
1019 calp = LL_RTC_CALIB_INSERTPULSE_SET;
1020 calm = MAX_CALP - nb_pulses;
1021 } else {
1022 calp = LL_RTC_CALIB_INSERTPULSE_NONE;
1023 calm = -nb_pulses;
1024 }
1025
1026 /* wait for recalibration to be ok if a previous recalibration occurred */
1027 if (!WAIT_FOR(LL_RTC_IsActiveFlag_RECALP(RTC) == 0, 100000, k_msleep(1))) {
1028 return -EIO;
1029 }
1030
1031 stm32_backup_domain_enable_access();
1032
1033 LL_RTC_DisableWriteProtection(RTC);
1034
1035 MODIFY_REG(RTC->CALR, RTC_CALR_CALP | RTC_CALR_CALM, calp | calm);
1036
1037 LL_RTC_EnableWriteProtection(RTC);
1038
1039 stm32_backup_domain_disable_access();
1040
1041 return 0;
1042 }
1043
rtc_stm32_get_calibration(const struct device * dev,int32_t * calibration)1044 static int rtc_stm32_get_calibration(const struct device *dev, int32_t *calibration)
1045 {
1046 ARG_UNUSED(dev);
1047
1048 uint32_t calr = sys_read32((mem_addr_t) &RTC->CALR);
1049
1050 bool calp_enabled = READ_BIT(calr, RTC_CALR_CALP);
1051 uint32_t calm = READ_BIT(calr, RTC_CALR_CALM);
1052
1053 int32_t nb_pulses = -((int32_t) calm);
1054
1055 if (calp_enabled) {
1056 nb_pulses += MAX_CALP;
1057 }
1058
1059 *calibration = NB_PULSES_TO_PPB(nb_pulses);
1060
1061 return 0;
1062 }
1063 #endif
1064 #endif /* CONFIG_RTC_CALIBRATION */
1065
1066 static DEVICE_API(rtc, rtc_stm32_driver_api) = {
1067 .set_time = rtc_stm32_set_time,
1068 .get_time = rtc_stm32_get_time,
1069 #ifdef STM32_RTC_ALARM_ENABLED
1070 .alarm_get_supported_fields = rtc_stm32_alarm_get_supported_fields,
1071 .alarm_set_time = rtc_stm32_alarm_set_time,
1072 .alarm_get_time = rtc_stm32_alarm_get_time,
1073 .alarm_set_callback = rtc_stm32_alarm_set_callback,
1074 .alarm_is_pending = rtc_stm32_alarm_is_pending,
1075 #endif /* STM32_RTC_ALARM_ENABLED */
1076 #ifdef CONFIG_RTC_CALIBRATION
1077 #if !defined(CONFIG_SOC_SERIES_STM32F2X) && \
1078 !(defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SMOOTHCALIB_SUPPORT))
1079 .set_calibration = rtc_stm32_set_calibration,
1080 .get_calibration = rtc_stm32_get_calibration,
1081 #else
1082 #error RTC calibration for devices without smooth calibration feature is not supported yet
1083 #endif
1084 #endif /* CONFIG_RTC_CALIBRATION */
1085 };
1086
1087 static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0);
1088
1089 BUILD_ASSERT(DT_INST_CLOCKS_HAS_IDX(0, 1), "RTC source clock not defined in the device tree");
1090
1091 #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
1092 #if STM32_HSE_FREQ % MHZ(1) != 0
1093 #error RTC clock source HSE frequency should be whole MHz
1094 #elif STM32_HSE_FREQ < MHZ(16) && defined(LL_RCC_RTC_HSE_DIV_16)
1095 #define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_16
1096 #define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 16)
1097 #elif STM32_HSE_FREQ < MHZ(32) && defined(LL_RCC_RTC_HSE_DIV_32)
1098 #define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_32
1099 #define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 32)
1100 #elif STM32_HSE_FREQ < MHZ(64) && defined(LL_RCC_RTC_HSE_DIV_64)
1101 #define RTC_HSE_PRESCALER LL_RCC_RTC_HSE_DIV_64
1102 #define RTC_HSE_FREQUENCY (STM32_HSE_FREQ / 64)
1103 #else
1104 #error RTC does not support HSE frequency
1105 #endif
1106 #define RTC_HSE_ASYNC_PRESCALER 125
1107 #define RTC_HSE_SYNC_PRESCALER (RTC_HSE_FREQUENCY / RTC_HSE_ASYNC_PRESCALER)
1108 #endif /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE */
1109
1110 static const struct rtc_stm32_config rtc_config = {
1111 #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI
1112 /* prescaler values for LSI @ 32 KHz */
1113 .async_prescaler = DT_INST_PROP_OR(0, async_prescaler, 0x7F),
1114 .sync_prescaler = DT_INST_PROP_OR(0, sync_prescaler, 0x00F9),
1115 #elif DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE
1116 /* prescaler values for LSE @ 32768 Hz */
1117 .async_prescaler = DT_INST_PROP_OR(0, async_prescaler, 0x7F),
1118 .sync_prescaler = DT_INST_PROP_OR(0, sync_prescaler, 0x00FF),
1119 #elif DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_HSE
1120 /* prescaler values for HSE */
1121 .async_prescaler = DT_INST_PROP_OR(0, async_prescaler, RTC_HSE_ASYNC_PRESCALER - 1),
1122 .sync_prescaler = DT_INST_PROP_OR(0, sync_prescaler, RTC_HSE_SYNC_PRESCALER - 1),
1123 .hse_prescaler = DT_INST_PROP_OR(0, hse_prescaler, RTC_HSE_PRESCALER),
1124 #else
1125 #error Invalid RTC SRC
1126 #endif
1127 .pclken = rtc_clk,
1128 #if DT_INST_NODE_HAS_PROP(0, calib_out_freq)
1129 .cal_out_freq = _CONCAT(_CONCAT(LL_RTC_CALIB_OUTPUT_, DT_INST_PROP(0, calib_out_freq)), HZ),
1130 #endif
1131 };
1132
1133 static struct rtc_stm32_data rtc_data;
1134
1135 DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, NULL, &rtc_data, &rtc_config, PRE_KERNEL_1,
1136 CONFIG_RTC_INIT_PRIORITY, &rtc_stm32_driver_api);
1137