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