1 /*
2 * Copyright (c) 2018 Workaround GmbH
3 * Copyright (c) 2018 Allterco Robotics
4 * Copyright (c) 2018 Linaro Limited
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 *
8 * Source file for the STM32 RTC driver
9 *
10 */
11
12 #define DT_DRV_COMPAT st_stm32_rtc
13
14 #include <time.h>
15
16 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
17 #include <zephyr/drivers/clock_control.h>
18 #include <zephyr/sys/util.h>
19 #include <zephyr/kernel.h>
20 #include <soc.h>
21 #include <stm32_ll_exti.h>
22 #include <stm32_ll_pwr.h>
23 #include <stm32_ll_rcc.h>
24 #include <stm32_ll_rtc.h>
25 #include <zephyr/drivers/counter.h>
26 #include <zephyr/sys/timeutil.h>
27 #include <zephyr/pm/device.h>
28
29 #include <zephyr/logging/log.h>
30 #include <zephyr/irq.h>
31
32 #include "stm32_hsem.h"
33
34 LOG_MODULE_REGISTER(counter_rtc_stm32, CONFIG_COUNTER_LOG_LEVEL);
35
36 /* Seconds from 1970-01-01T00:00:00 to 2000-01-01T00:00:00 */
37 #define T_TIME_OFFSET 946684800
38
39 #if defined(CONFIG_SOC_SERIES_STM32L4X)
40 #define RTC_EXTI_LINE LL_EXTI_LINE_18
41 #elif defined(CONFIG_SOC_SERIES_STM32C0X) \
42 || defined(CONFIG_SOC_SERIES_STM32G0X)
43 #define RTC_EXTI_LINE LL_EXTI_LINE_19
44 #elif defined(CONFIG_SOC_SERIES_STM32F4X) \
45 || defined(CONFIG_SOC_SERIES_STM32F0X) \
46 || defined(CONFIG_SOC_SERIES_STM32F1X) \
47 || defined(CONFIG_SOC_SERIES_STM32F2X) \
48 || defined(CONFIG_SOC_SERIES_STM32F3X) \
49 || defined(CONFIG_SOC_SERIES_STM32F7X) \
50 || defined(CONFIG_SOC_SERIES_STM32WBX) \
51 || defined(CONFIG_SOC_SERIES_STM32G4X) \
52 || defined(CONFIG_SOC_SERIES_STM32L0X) \
53 || defined(CONFIG_SOC_SERIES_STM32L1X) \
54 || defined(CONFIG_SOC_SERIES_STM32L5X) \
55 || defined(CONFIG_SOC_SERIES_STM32H7X) \
56 || defined(CONFIG_SOC_SERIES_STM32H5X) \
57 || defined(CONFIG_SOC_SERIES_STM32WLX)
58 #define RTC_EXTI_LINE LL_EXTI_LINE_17
59 #endif
60
61 #if defined(CONFIG_SOC_SERIES_STM32F1X)
62 #define COUNTER_NO_DATE
63 #endif
64
65 #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI
66 /* LSI */
67 #define RTCCLK_FREQ STM32_LSI_FREQ
68 #else
69 /* LSE */
70 #define RTCCLK_FREQ STM32_LSE_FREQ
71 #endif /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI */
72
73 #if !defined(CONFIG_SOC_SERIES_STM32F1X)
74 #ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
75 #define RTC_ASYNCPRE BIT_MASK(7)
76 #else /* !CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
77 /* Get the highest possible clock for the subsecond register */
78 #define RTC_ASYNCPRE 1
79 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
80 #else /* CONFIG_SOC_SERIES_STM32F1X */
81 #define RTC_ASYNCPRE (RTCCLK_FREQ - 1)
82 #endif /* CONFIG_SOC_SERIES_STM32F1X */
83
84 /* Adjust the second sync prescaler to get 1Hz on ck_spre */
85 #define RTC_SYNCPRE ((RTCCLK_FREQ / (1 + RTC_ASYNCPRE)) - 1)
86
87 #ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
88 typedef uint32_t tick_t;
89 #else
90 typedef uint64_t tick_t;
91 #endif
92
93 struct rtc_stm32_config {
94 struct counter_config_info counter_info;
95 LL_RTC_InitTypeDef ll_rtc_config;
96 const struct stm32_pclken *pclken;
97 };
98
99 struct rtc_stm32_data {
100 counter_alarm_callback_t callback;
101 uint32_t ticks;
102 void *user_data;
103 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
104 bool irq_on_late;
105 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
106 };
107
ll_func_init_alarm(RTC_TypeDef * rtc,uint32_t format,LL_RTC_AlarmTypeDef * alarmStruct)108 static inline ErrorStatus ll_func_init_alarm(RTC_TypeDef *rtc, uint32_t format,
109 LL_RTC_AlarmTypeDef *alarmStruct)
110 {
111 #if defined(CONFIG_SOC_SERIES_STM32F1X)
112 return LL_RTC_ALARM_Init(rtc, format, alarmStruct);
113 #else
114 return LL_RTC_ALMA_Init(rtc, format, alarmStruct);
115 #endif
116 }
117
ll_func_clear_alarm_flag(RTC_TypeDef * rtc)118 static inline void ll_func_clear_alarm_flag(RTC_TypeDef *rtc)
119 {
120 #if defined(CONFIG_SOC_SERIES_STM32F1X)
121 LL_RTC_ClearFlag_ALR(rtc);
122 #else
123 LL_RTC_ClearFlag_ALRA(rtc);
124 #endif
125 }
126
ll_func_is_active_alarm(RTC_TypeDef * rtc)127 static inline uint32_t ll_func_is_active_alarm(RTC_TypeDef *rtc)
128 {
129 #if defined(CONFIG_SOC_SERIES_STM32F1X)
130 return LL_RTC_IsActiveFlag_ALR(rtc);
131 #else
132 return LL_RTC_IsActiveFlag_ALRA(rtc);
133 #endif
134 }
135
ll_func_enable_interrupt_alarm(RTC_TypeDef * rtc)136 static inline void ll_func_enable_interrupt_alarm(RTC_TypeDef *rtc)
137 {
138 #if defined(CONFIG_SOC_SERIES_STM32F1X)
139 LL_RTC_EnableIT_ALR(rtc);
140 #else
141 LL_RTC_EnableIT_ALRA(rtc);
142 #endif
143 }
144
ll_func_disable_interrupt_alarm(RTC_TypeDef * rtc)145 static inline void ll_func_disable_interrupt_alarm(RTC_TypeDef *rtc)
146 {
147 #if defined(CONFIG_SOC_SERIES_STM32F1X)
148 LL_RTC_DisableIT_ALR(rtc);
149 #else
150 LL_RTC_DisableIT_ALRA(rtc);
151 #endif
152 }
153
154 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
ll_func_isenabled_interrupt_alarm(RTC_TypeDef * rtc)155 static inline uint32_t ll_func_isenabled_interrupt_alarm(RTC_TypeDef *rtc)
156 {
157 #if defined(CONFIG_SOC_SERIES_STM32F1X)
158 return LL_RTC_IsEnabledIT_ALR(rtc);
159 #else
160 return LL_RTC_IsEnabledIT_ALRA(rtc);
161 #endif
162 }
163 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
164
ll_func_enable_alarm(RTC_TypeDef * rtc)165 static inline void ll_func_enable_alarm(RTC_TypeDef *rtc)
166 {
167 #if defined(CONFIG_SOC_SERIES_STM32F1X)
168 ARG_UNUSED(rtc);
169 #else
170 LL_RTC_ALMA_Enable(rtc);
171 #endif
172 }
173
ll_func_disable_alarm(RTC_TypeDef * rtc)174 static inline void ll_func_disable_alarm(RTC_TypeDef *rtc)
175 {
176 #if defined(CONFIG_SOC_SERIES_STM32F1X)
177 ARG_UNUSED(rtc);
178 #else
179 LL_RTC_ALMA_Disable(rtc);
180 #endif
181 }
182
183 static void rtc_stm32_irq_config(const struct device *dev);
184
185
rtc_stm32_start(const struct device * dev)186 static int rtc_stm32_start(const struct device *dev)
187 {
188 #if defined(CONFIG_SOC_SERIES_STM32WBAX) || defined(CONFIG_SOC_SERIES_STM32U5X)
189 const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
190 const struct rtc_stm32_config *cfg = dev->config;
191
192 /* Enable RTC bus clock */
193 if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken[0]) != 0) {
194 LOG_ERR("RTC clock enabling failed\n");
195 return -EIO;
196 }
197 #else
198 ARG_UNUSED(dev);
199
200 z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
201 LL_RCC_EnableRTC();
202 z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
203 #endif
204
205 return 0;
206 }
207
208
rtc_stm32_stop(const struct device * dev)209 static int rtc_stm32_stop(const struct device *dev)
210 {
211 #if defined(CONFIG_SOC_SERIES_STM32WBAX) || defined(CONFIG_SOC_SERIES_STM32U5X)
212 const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
213 const struct rtc_stm32_config *cfg = dev->config;
214
215 /* Disable RTC bus clock */
216 if (clock_control_off(clk, (clock_control_subsys_t) &cfg->pclken[0]) != 0) {
217 LOG_ERR("RTC clock disabling failed\n");
218 return -EIO;
219 }
220 #else
221 ARG_UNUSED(dev);
222
223 z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
224 LL_RCC_DisableRTC();
225 z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
226 #endif
227
228 return 0;
229 }
230
231 #if !defined(COUNTER_NO_DATE)
rtc_stm32_read(const struct device * dev)232 tick_t rtc_stm32_read(const struct device *dev)
233 {
234 struct tm now = { 0 };
235 time_t ts;
236 uint32_t rtc_date, rtc_time;
237 tick_t ticks;
238 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
239 uint32_t rtc_subseconds;
240 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
241 ARG_UNUSED(dev);
242
243 /* Enable Backup access */
244 #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || \
245 defined(PWR_DBPCR_DBP) || defined(PWR_DBPR_DBP)
246 LL_PWR_EnableBkUpAccess();
247 #endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPR_DBP */
248
249 /* Read time and date registers. Make sure value of the previous register
250 * hasn't been changed while reading the next one.
251 */
252 do {
253 rtc_date = LL_RTC_DATE_Get(RTC);
254
255 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
256 do {
257 rtc_time = LL_RTC_TIME_Get(RTC);
258 rtc_subseconds = LL_RTC_TIME_GetSubSecond(RTC);
259 } while (rtc_time != LL_RTC_TIME_Get(RTC));
260 #else /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
261 rtc_time = LL_RTC_TIME_Get(RTC);
262 #endif
263
264 } while (rtc_date != LL_RTC_DATE_Get(RTC));
265
266 /* Convert calendar datetime to UNIX timestamp */
267 /* RTC start time: 1st, Jan, 2000 */
268 /* time_t start: 1st, Jan, 1970 */
269 now.tm_year = 100 +
270 __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_YEAR(rtc_date));
271 /* tm_mon allowed values are 0-11 */
272 now.tm_mon = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MONTH(rtc_date)) - 1;
273 now.tm_mday = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_DAY(rtc_date));
274
275 now.tm_hour = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_HOUR(rtc_time));
276 now.tm_min = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MINUTE(rtc_time));
277 now.tm_sec = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_SECOND(rtc_time));
278
279 ts = timeutil_timegm(&now);
280
281 /* Return number of seconds since RTC init */
282 ts -= T_TIME_OFFSET;
283
284 __ASSERT(sizeof(time_t) == 8, "unexpected time_t definition");
285
286 ticks = ts * counter_get_frequency(dev);
287 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
288 /* The RTC counts up, except for the subsecond register which counts
289 * down starting from the sync prescaler value. Add already counted
290 * ticks.
291 */
292 ticks += RTC_SYNCPRE - rtc_subseconds;
293 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
294
295 return ticks;
296 }
297 #else /* defined(COUNTER_NO_DATE) */
rtc_stm32_read(const struct device * dev)298 tick_t rtc_stm32_read(const struct device *dev)
299 {
300 uint32_t rtc_time, ticks;
301
302 ARG_UNUSED(dev);
303
304 /* Enable Backup access */
305 #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || \
306 defined(PWR_DBPCR_DBP) || defined(PWR_DBPR_DBP)
307 LL_PWR_EnableBkUpAccess();
308 #endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPR_DBP */
309
310 rtc_time = LL_RTC_TIME_Get(RTC);
311
312 ticks = rtc_time;
313
314 return ticks;
315 }
316 #endif /* !defined(COUNTER_NO_DATE) */
317
rtc_stm32_get_value(const struct device * dev,uint32_t * ticks)318 static int rtc_stm32_get_value(const struct device *dev, uint32_t *ticks)
319 {
320 *ticks = (uint32_t)rtc_stm32_read(dev);
321 return 0;
322 }
323
324 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
rtc_stm32_get_value_64(const struct device * dev,uint64_t * ticks)325 static int rtc_stm32_get_value_64(const struct device *dev, uint64_t *ticks)
326 {
327 *ticks = rtc_stm32_read(dev);
328 return 0;
329 }
330 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
331
332 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
rtc_stm32_set_int_pending(void)333 static void rtc_stm32_set_int_pending(void)
334 {
335 NVIC_SetPendingIRQ(DT_INST_IRQN(0));
336 }
337 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
338
rtc_stm32_set_alarm(const struct device * dev,uint8_t chan_id,const struct counter_alarm_cfg * alarm_cfg)339 static int rtc_stm32_set_alarm(const struct device *dev, uint8_t chan_id,
340 const struct counter_alarm_cfg *alarm_cfg)
341 {
342 #if !defined(COUNTER_NO_DATE)
343 struct tm alarm_tm;
344 time_t alarm_val_s;
345 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
346 uint32_t alarm_val_ss;
347 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
348 #else
349 uint32_t remain;
350 #endif
351 LL_RTC_AlarmTypeDef rtc_alarm;
352 struct rtc_stm32_data *data = dev->data;
353
354 tick_t now = rtc_stm32_read(dev);
355 tick_t ticks = alarm_cfg->ticks;
356
357 if (data->callback != NULL) {
358 LOG_DBG("Alarm busy\n");
359 return -EBUSY;
360 }
361
362
363 data->callback = alarm_cfg->callback;
364 data->user_data = alarm_cfg->user_data;
365
366 #if !defined(COUNTER_NO_DATE)
367 if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) {
368 /* Add +1 in order to compensate the partially started tick.
369 * Alarm will expire between requested ticks and ticks+1.
370 * In case only 1 tick is requested, it will avoid
371 * that tick+1 event occurs before alarm setting is finished.
372 */
373 ticks += now + 1;
374 alarm_val_s = (time_t)(ticks / counter_get_frequency(dev)) + T_TIME_OFFSET;
375 } else {
376 alarm_val_s = (time_t)(ticks / counter_get_frequency(dev));
377 }
378 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
379 alarm_val_ss = ticks % counter_get_frequency(dev);
380 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
381
382 #else
383 if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) {
384 remain = ticks + now + 1;
385 } else {
386 remain = ticks;
387 }
388
389 /* In F1X, an interrupt occurs when the counter expires,
390 * not when the counter matches, so set -1
391 */
392 remain--;
393 #endif
394
395 #if !defined(COUNTER_NO_DATE)
396 #ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
397 LOG_DBG("Set Alarm: %d\n", ticks);
398 #else /* !CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
399 LOG_DBG("Set Alarm: %llu\n", ticks);
400 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
401
402 gmtime_r(&alarm_val_s, &alarm_tm);
403
404 /* Apply ALARM_A */
405 rtc_alarm.AlarmTime.TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
406 rtc_alarm.AlarmTime.Hours = alarm_tm.tm_hour;
407 rtc_alarm.AlarmTime.Minutes = alarm_tm.tm_min;
408 rtc_alarm.AlarmTime.Seconds = alarm_tm.tm_sec;
409
410 rtc_alarm.AlarmMask = LL_RTC_ALMA_MASK_NONE;
411 rtc_alarm.AlarmDateWeekDaySel = LL_RTC_ALMA_DATEWEEKDAYSEL_DATE;
412 rtc_alarm.AlarmDateWeekDay = alarm_tm.tm_mday;
413 #else
414 rtc_alarm.AlarmTime.Hours = remain / 3600;
415 remain -= rtc_alarm.AlarmTime.Hours * 3600;
416 rtc_alarm.AlarmTime.Minutes = remain / 60;
417 remain -= rtc_alarm.AlarmTime.Minutes * 60;
418 rtc_alarm.AlarmTime.Seconds = remain;
419 #endif
420
421 LL_RTC_DisableWriteProtection(RTC);
422 ll_func_disable_alarm(RTC);
423 LL_RTC_EnableWriteProtection(RTC);
424
425 if (ll_func_init_alarm(RTC, LL_RTC_FORMAT_BIN, &rtc_alarm) != SUCCESS) {
426 return -EIO;
427 }
428
429 LL_RTC_DisableWriteProtection(RTC);
430 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
431 /* Care about all bits of the subsecond register */
432 LL_RTC_ALMA_SetSubSecondMask(RTC, 0xF);
433 LL_RTC_ALMA_SetSubSecond(RTC, RTC_SYNCPRE - alarm_val_ss);
434 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
435 ll_func_enable_alarm(RTC);
436 ll_func_clear_alarm_flag(RTC);
437 ll_func_enable_interrupt_alarm(RTC);
438 LL_RTC_EnableWriteProtection(RTC);
439
440 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
441 /* The reference manual says:
442 * "Each change of the RTC_CR register is taken into account after
443 * 1 to 2 RTCCLK clock cycles due to clock synchronization."
444 * It means we need at least two cycles after programming the CR
445 * register. It is confirmed experimentally.
446 *
447 * It should happen only if one tick alarm is requested and a tick
448 * occurs while processing the function. Trigger the irq manually in
449 * this case.
450 */
451 now = rtc_stm32_read(dev);
452 if ((ticks - now < 2) || (now > ticks)) {
453 data->irq_on_late = 1;
454 rtc_stm32_set_int_pending();
455 }
456 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
457
458 return 0;
459 }
460
461
rtc_stm32_cancel_alarm(const struct device * dev,uint8_t chan_id)462 static int rtc_stm32_cancel_alarm(const struct device *dev, uint8_t chan_id)
463 {
464 struct rtc_stm32_data *data = dev->data;
465
466 LL_RTC_DisableWriteProtection(RTC);
467 ll_func_clear_alarm_flag(RTC);
468 ll_func_disable_interrupt_alarm(RTC);
469 ll_func_disable_alarm(RTC);
470 LL_RTC_EnableWriteProtection(RTC);
471
472 data->callback = NULL;
473
474 return 0;
475 }
476
477
rtc_stm32_get_pending_int(const struct device * dev)478 static uint32_t rtc_stm32_get_pending_int(const struct device *dev)
479 {
480 return ll_func_is_active_alarm(RTC) != 0;
481 }
482
483
rtc_stm32_get_top_value(const struct device * dev)484 static uint32_t rtc_stm32_get_top_value(const struct device *dev)
485 {
486 const struct counter_config_info *info = dev->config;
487
488 return info->max_top_value;
489 }
490
491
rtc_stm32_set_top_value(const struct device * dev,const struct counter_top_cfg * cfg)492 static int rtc_stm32_set_top_value(const struct device *dev,
493 const struct counter_top_cfg *cfg)
494 {
495 const struct counter_config_info *info = dev->config;
496
497 if ((cfg->ticks != info->max_top_value) ||
498 !(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
499 return -ENOTSUP;
500 } else {
501 return 0;
502 }
503
504
505 }
506
rtc_stm32_isr(const struct device * dev)507 void rtc_stm32_isr(const struct device *dev)
508 {
509 struct rtc_stm32_data *data = dev->data;
510 counter_alarm_callback_t alarm_callback = data->callback;
511
512 uint32_t now = rtc_stm32_read(dev);
513
514 if (ll_func_is_active_alarm(RTC) != 0
515 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
516 || (data->irq_on_late && ll_func_isenabled_interrupt_alarm(RTC))
517 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
518 ) {
519
520 LL_RTC_DisableWriteProtection(RTC);
521 ll_func_clear_alarm_flag(RTC);
522 ll_func_disable_interrupt_alarm(RTC);
523 ll_func_disable_alarm(RTC);
524 LL_RTC_EnableWriteProtection(RTC);
525 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
526 data->irq_on_late = 0;
527 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
528
529 if (alarm_callback != NULL) {
530 data->callback = NULL;
531 alarm_callback(dev, 0, now, data->user_data);
532 }
533 }
534
535 #if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
536 LL_C2_EXTI_ClearFlag_0_31(RTC_EXTI_LINE);
537 #elif defined(CONFIG_SOC_SERIES_STM32C0X) \
538 || defined(CONFIG_SOC_SERIES_STM32G0X) \
539 || defined(CONFIG_SOC_SERIES_STM32L5X) \
540 || defined(CONFIG_SOC_SERIES_STM32H5X)
541 LL_EXTI_ClearRisingFlag_0_31(RTC_EXTI_LINE);
542 #elif defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX)
543 /* in STM32U5 family RTC is not connected to EXTI */
544 #else
545 LL_EXTI_ClearFlag_0_31(RTC_EXTI_LINE);
546 #endif
547 }
548
549
rtc_stm32_init(const struct device * dev)550 static int rtc_stm32_init(const struct device *dev)
551 {
552 const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
553 const struct rtc_stm32_config *cfg = dev->config;
554 struct rtc_stm32_data *data = dev->data;
555
556 data->callback = NULL;
557
558 if (!device_is_ready(clk)) {
559 LOG_ERR("clock control device not ready");
560 return -ENODEV;
561 }
562
563 /* Enable RTC bus clock */
564 if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken[0]) != 0) {
565 LOG_ERR("clock op failed\n");
566 return -EIO;
567 }
568
569 /* Enable Backup access */
570 z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
571 #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || \
572 defined(PWR_DBPCR_DBP) || defined(PWR_DBPR_DBP)
573 LL_PWR_EnableBkUpAccess();
574 #endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPR_DBP */
575
576 /* Enable RTC clock source */
577 if (clock_control_configure(clk,
578 (clock_control_subsys_t) &cfg->pclken[1],
579 NULL) != 0) {
580 LOG_ERR("clock configure failed\n");
581 return -EIO;
582 }
583
584 #if !defined(CONFIG_SOC_SERIES_STM32WBAX)
585 LL_RCC_EnableRTC();
586 #endif
587
588 z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
589
590 #if !defined(CONFIG_COUNTER_RTC_STM32_SAVE_VALUE_BETWEEN_RESETS)
591 if (LL_RTC_DeInit(RTC) != SUCCESS) {
592 return -EIO;
593 }
594 #endif
595
596 if (LL_RTC_Init(RTC, ((LL_RTC_InitTypeDef *)
597 &cfg->ll_rtc_config)) != SUCCESS) {
598 return -EIO;
599 }
600
601 #ifdef RTC_CR_BYPSHAD
602 LL_RTC_DisableWriteProtection(RTC);
603 LL_RTC_EnableShadowRegBypass(RTC);
604 LL_RTC_EnableWriteProtection(RTC);
605 #endif /* RTC_CR_BYPSHAD */
606
607 #if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
608 LL_C2_EXTI_EnableIT_0_31(RTC_EXTI_LINE);
609 LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE);
610 #elif defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX)
611 /* in STM32U5 family RTC is not connected to EXTI */
612 #else
613 LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE);
614 LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE);
615 #endif
616
617 rtc_stm32_irq_config(dev);
618
619 return 0;
620 }
621
622 static struct rtc_stm32_data rtc_data;
623
624 static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0);
625
626 static const struct rtc_stm32_config rtc_config = {
627 .counter_info = {
628 .max_top_value = UINT32_MAX,
629 #ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
630 /* freq = 1Hz for not subsec based driver */
631 .freq = RTCCLK_FREQ / ((RTC_ASYNCPRE + 1) * (RTC_SYNCPRE + 1)),
632 #else /* !CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
633 .freq = RTCCLK_FREQ / (RTC_ASYNCPRE + 1),
634 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
635 .flags = COUNTER_CONFIG_INFO_COUNT_UP,
636 .channels = 1,
637 },
638 .ll_rtc_config = {
639 .AsynchPrescaler = RTC_ASYNCPRE,
640 #if !defined(CONFIG_SOC_SERIES_STM32F1X)
641 .HourFormat = LL_RTC_HOURFORMAT_24HOUR,
642 .SynchPrescaler = RTC_SYNCPRE,
643 #else /* CONFIG_SOC_SERIES_STM32F1X */
644 .OutPutSource = LL_RTC_CALIB_OUTPUT_NONE,
645 #endif /* CONFIG_SOC_SERIES_STM32F1X */
646 },
647 .pclken = rtc_clk,
648 };
649
650 #ifdef CONFIG_PM_DEVICE
rtc_stm32_pm_action(const struct device * dev,enum pm_device_action action)651 static int rtc_stm32_pm_action(const struct device *dev,
652 enum pm_device_action action)
653 {
654 const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
655 const struct rtc_stm32_config *cfg = dev->config;
656
657 switch (action) {
658 case PM_DEVICE_ACTION_RESUME:
659 /* Enable RTC bus clock */
660 if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken[0]) != 0) {
661 LOG_ERR("clock op failed\n");
662 return -EIO;
663 }
664 break;
665 case PM_DEVICE_ACTION_SUSPEND:
666 break;
667 default:
668 return -ENOTSUP;
669 }
670
671 return 0;
672 }
673 #endif /* CONFIG_PM_DEVICE */
674
675 static DEVICE_API(counter, rtc_stm32_driver_api) = {
676 .start = rtc_stm32_start,
677 .stop = rtc_stm32_stop,
678 .get_value = rtc_stm32_get_value,
679 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
680 .get_value_64 = rtc_stm32_get_value_64,
681 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
682 .set_alarm = rtc_stm32_set_alarm,
683 .cancel_alarm = rtc_stm32_cancel_alarm,
684 .set_top_value = rtc_stm32_set_top_value,
685 .get_pending_int = rtc_stm32_get_pending_int,
686 .get_top_value = rtc_stm32_get_top_value,
687 };
688
689 PM_DEVICE_DT_INST_DEFINE(0, rtc_stm32_pm_action);
690
691 DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, PM_DEVICE_DT_INST_GET(0),
692 &rtc_data, &rtc_config, PRE_KERNEL_1,
693 CONFIG_COUNTER_INIT_PRIORITY, &rtc_stm32_driver_api);
694
rtc_stm32_irq_config(const struct device * dev)695 static void rtc_stm32_irq_config(const struct device *dev)
696 {
697 IRQ_CONNECT(DT_INST_IRQN(0),
698 DT_INST_IRQ(0, priority),
699 rtc_stm32_isr, DEVICE_DT_INST_GET(0), 0);
700 irq_enable(DT_INST_IRQN(0));
701 }
702