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)
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("clock op 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)
212 const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
213 const struct rtc_stm32_config *cfg = dev->config;
214
215 /* Enable RTC bus clock */
216 if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken[0]) != 0) {
217 LOG_ERR("clock op 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 /* Read time and date registers. Make sure value of the previous register
244 * hasn't been changed while reading the next one.
245 */
246 do {
247 rtc_date = LL_RTC_DATE_Get(RTC);
248
249 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
250 do {
251 rtc_time = LL_RTC_TIME_Get(RTC);
252 rtc_subseconds = LL_RTC_TIME_GetSubSecond(RTC);
253 } while (rtc_time != LL_RTC_TIME_Get(RTC));
254 #else /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
255 rtc_time = LL_RTC_TIME_Get(RTC);
256 #endif
257
258 } while (rtc_date != LL_RTC_DATE_Get(RTC));
259
260 /* Convert calendar datetime to UNIX timestamp */
261 /* RTC start time: 1st, Jan, 2000 */
262 /* time_t start: 1st, Jan, 1970 */
263 now.tm_year = 100 +
264 __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_YEAR(rtc_date));
265 /* tm_mon allowed values are 0-11 */
266 now.tm_mon = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MONTH(rtc_date)) - 1;
267 now.tm_mday = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_DAY(rtc_date));
268
269 now.tm_hour = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_HOUR(rtc_time));
270 now.tm_min = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_MINUTE(rtc_time));
271 now.tm_sec = __LL_RTC_CONVERT_BCD2BIN(__LL_RTC_GET_SECOND(rtc_time));
272
273 ts = timeutil_timegm(&now);
274
275 /* Return number of seconds since RTC init */
276 ts -= T_TIME_OFFSET;
277
278 __ASSERT(sizeof(time_t) == 8, "unexpected time_t definition");
279
280 ticks = ts * counter_get_frequency(dev);
281 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
282 /* The RTC counts up, except for the subsecond register which counts
283 * down starting from the sync prescaler value. Add already counted
284 * ticks.
285 */
286 ticks += RTC_SYNCPRE - rtc_subseconds;
287 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
288
289 return ticks;
290 }
291 #else /* defined(COUNTER_NO_DATE) */
rtc_stm32_read(const struct device * dev)292 tick_t rtc_stm32_read(const struct device *dev)
293 {
294 uint32_t rtc_time, ticks;
295
296 ARG_UNUSED(dev);
297
298 rtc_time = LL_RTC_TIME_Get(RTC);
299
300 ticks = rtc_time;
301
302 return ticks;
303 }
304 #endif /* !defined(COUNTER_NO_DATE) */
305
rtc_stm32_get_value(const struct device * dev,uint32_t * ticks)306 static int rtc_stm32_get_value(const struct device *dev, uint32_t *ticks)
307 {
308 *ticks = (uint32_t)rtc_stm32_read(dev);
309 return 0;
310 }
311
312 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
rtc_stm32_get_value_64(const struct device * dev,uint64_t * ticks)313 static int rtc_stm32_get_value_64(const struct device *dev, uint64_t *ticks)
314 {
315 *ticks = rtc_stm32_read(dev);
316 return 0;
317 }
318 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
319
320 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
rtc_stm32_set_int_pending(void)321 static void rtc_stm32_set_int_pending(void)
322 {
323 NVIC_SetPendingIRQ(DT_INST_IRQN(0));
324 }
325 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
326
rtc_stm32_set_alarm(const struct device * dev,uint8_t chan_id,const struct counter_alarm_cfg * alarm_cfg)327 static int rtc_stm32_set_alarm(const struct device *dev, uint8_t chan_id,
328 const struct counter_alarm_cfg *alarm_cfg)
329 {
330 #if !defined(COUNTER_NO_DATE)
331 struct tm alarm_tm;
332 time_t alarm_val_s;
333 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
334 uint32_t alarm_val_ss;
335 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
336 #else
337 uint32_t remain;
338 #endif
339 LL_RTC_AlarmTypeDef rtc_alarm;
340 struct rtc_stm32_data *data = dev->data;
341
342 tick_t now = rtc_stm32_read(dev);
343 tick_t ticks = alarm_cfg->ticks;
344
345 if (data->callback != NULL) {
346 LOG_DBG("Alarm busy\n");
347 return -EBUSY;
348 }
349
350
351 data->callback = alarm_cfg->callback;
352 data->user_data = alarm_cfg->user_data;
353
354 #if !defined(COUNTER_NO_DATE)
355 if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) {
356 /* Add +1 in order to compensate the partially started tick.
357 * Alarm will expire between requested ticks and ticks+1.
358 * In case only 1 tick is requested, it will avoid
359 * that tick+1 event occurs before alarm setting is finished.
360 */
361 ticks += now + 1;
362 alarm_val_s = (time_t)(ticks / counter_get_frequency(dev)) + T_TIME_OFFSET;
363 } else {
364 alarm_val_s = (time_t)(ticks / counter_get_frequency(dev));
365 }
366 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
367 alarm_val_ss = ticks % counter_get_frequency(dev);
368 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
369
370 #else
371 if ((alarm_cfg->flags & COUNTER_ALARM_CFG_ABSOLUTE) == 0) {
372 remain = ticks + now + 1;
373 } else {
374 remain = ticks;
375 }
376
377 /* In F1X, an interrupt occurs when the counter expires,
378 * not when the counter matches, so set -1
379 */
380 remain--;
381 #endif
382
383 #if !defined(COUNTER_NO_DATE)
384 #ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
385 LOG_DBG("Set Alarm: %d\n", ticks);
386 #else /* !CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
387 LOG_DBG("Set Alarm: %llu\n", ticks);
388 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
389
390 gmtime_r(&alarm_val_s, &alarm_tm);
391
392 /* Apply ALARM_A */
393 rtc_alarm.AlarmTime.TimeFormat = LL_RTC_TIME_FORMAT_AM_OR_24;
394 rtc_alarm.AlarmTime.Hours = alarm_tm.tm_hour;
395 rtc_alarm.AlarmTime.Minutes = alarm_tm.tm_min;
396 rtc_alarm.AlarmTime.Seconds = alarm_tm.tm_sec;
397
398 rtc_alarm.AlarmMask = LL_RTC_ALMA_MASK_NONE;
399 rtc_alarm.AlarmDateWeekDaySel = LL_RTC_ALMA_DATEWEEKDAYSEL_DATE;
400 rtc_alarm.AlarmDateWeekDay = alarm_tm.tm_mday;
401 #else
402 rtc_alarm.AlarmTime.Hours = remain / 3600;
403 remain -= rtc_alarm.AlarmTime.Hours * 3600;
404 rtc_alarm.AlarmTime.Minutes = remain / 60;
405 remain -= rtc_alarm.AlarmTime.Minutes * 60;
406 rtc_alarm.AlarmTime.Seconds = remain;
407 #endif
408
409 LL_RTC_DisableWriteProtection(RTC);
410 ll_func_disable_alarm(RTC);
411 LL_RTC_EnableWriteProtection(RTC);
412
413 if (ll_func_init_alarm(RTC, LL_RTC_FORMAT_BIN, &rtc_alarm) != SUCCESS) {
414 return -EIO;
415 }
416
417 LL_RTC_DisableWriteProtection(RTC);
418 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
419 /* Care about all bits of the subsecond register */
420 LL_RTC_ALMA_SetSubSecondMask(RTC, 0xF);
421 LL_RTC_ALMA_SetSubSecond(RTC, RTC_SYNCPRE - alarm_val_ss);
422 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
423 ll_func_enable_alarm(RTC);
424 ll_func_clear_alarm_flag(RTC);
425 ll_func_enable_interrupt_alarm(RTC);
426 LL_RTC_EnableWriteProtection(RTC);
427
428 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
429 /* The reference manual says:
430 * "Each change of the RTC_CR register is taken into account after
431 * 1 to 2 RTCCLK clock cycles due to clock synchronization."
432 * It means we need at least two cycles after programming the CR
433 * register. It is confirmed experimentally.
434 *
435 * It should happen only if one tick alarm is requested and a tick
436 * occurs while processing the function. Trigger the irq manually in
437 * this case.
438 */
439 now = rtc_stm32_read(dev);
440 if ((ticks - now < 2) || (now > ticks)) {
441 data->irq_on_late = 1;
442 rtc_stm32_set_int_pending();
443 }
444 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
445
446 return 0;
447 }
448
449
rtc_stm32_cancel_alarm(const struct device * dev,uint8_t chan_id)450 static int rtc_stm32_cancel_alarm(const struct device *dev, uint8_t chan_id)
451 {
452 struct rtc_stm32_data *data = dev->data;
453
454 LL_RTC_DisableWriteProtection(RTC);
455 ll_func_clear_alarm_flag(RTC);
456 ll_func_disable_interrupt_alarm(RTC);
457 ll_func_disable_alarm(RTC);
458 LL_RTC_EnableWriteProtection(RTC);
459
460 data->callback = NULL;
461
462 return 0;
463 }
464
465
rtc_stm32_get_pending_int(const struct device * dev)466 static uint32_t rtc_stm32_get_pending_int(const struct device *dev)
467 {
468 return ll_func_is_active_alarm(RTC) != 0;
469 }
470
471
rtc_stm32_get_top_value(const struct device * dev)472 static uint32_t rtc_stm32_get_top_value(const struct device *dev)
473 {
474 const struct counter_config_info *info = dev->config;
475
476 return info->max_top_value;
477 }
478
479
rtc_stm32_set_top_value(const struct device * dev,const struct counter_top_cfg * cfg)480 static int rtc_stm32_set_top_value(const struct device *dev,
481 const struct counter_top_cfg *cfg)
482 {
483 const struct counter_config_info *info = dev->config;
484
485 if ((cfg->ticks != info->max_top_value) ||
486 !(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
487 return -ENOTSUP;
488 } else {
489 return 0;
490 }
491
492
493 }
494
rtc_stm32_isr(const struct device * dev)495 void rtc_stm32_isr(const struct device *dev)
496 {
497 struct rtc_stm32_data *data = dev->data;
498 counter_alarm_callback_t alarm_callback = data->callback;
499
500 uint32_t now = rtc_stm32_read(dev);
501
502 if (ll_func_is_active_alarm(RTC) != 0
503 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
504 || (data->irq_on_late && ll_func_isenabled_interrupt_alarm(RTC))
505 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
506 ) {
507
508 LL_RTC_DisableWriteProtection(RTC);
509 ll_func_clear_alarm_flag(RTC);
510 ll_func_disable_interrupt_alarm(RTC);
511 ll_func_disable_alarm(RTC);
512 LL_RTC_EnableWriteProtection(RTC);
513 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
514 data->irq_on_late = 0;
515 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
516
517 if (alarm_callback != NULL) {
518 data->callback = NULL;
519 alarm_callback(dev, 0, now, data->user_data);
520 }
521 }
522
523 #if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
524 LL_C2_EXTI_ClearFlag_0_31(RTC_EXTI_LINE);
525 #elif defined(CONFIG_SOC_SERIES_STM32C0X) \
526 || defined(CONFIG_SOC_SERIES_STM32G0X) \
527 || defined(CONFIG_SOC_SERIES_STM32L5X) \
528 || defined(CONFIG_SOC_SERIES_STM32H5X)
529 LL_EXTI_ClearRisingFlag_0_31(RTC_EXTI_LINE);
530 #elif defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX)
531 /* in STM32U5 family RTC is not connected to EXTI */
532 #else
533 LL_EXTI_ClearFlag_0_31(RTC_EXTI_LINE);
534 #endif
535 }
536
537
rtc_stm32_init(const struct device * dev)538 static int rtc_stm32_init(const struct device *dev)
539 {
540 const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
541 const struct rtc_stm32_config *cfg = dev->config;
542 struct rtc_stm32_data *data = dev->data;
543
544 data->callback = NULL;
545
546 if (!device_is_ready(clk)) {
547 LOG_ERR("clock control device not ready");
548 return -ENODEV;
549 }
550
551 /* Enable RTC bus clock */
552 if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken[0]) != 0) {
553 LOG_ERR("clock op failed\n");
554 return -EIO;
555 }
556
557 /* Enable Backup access */
558 z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
559 #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || \
560 defined(PWR_DBPCR_DBP) || defined(PWR_DBPR_DBP)
561 LL_PWR_EnableBkUpAccess();
562 #endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPR_DBP */
563
564 /* Enable RTC clock source */
565 if (clock_control_configure(clk,
566 (clock_control_subsys_t) &cfg->pclken[1],
567 NULL) != 0) {
568 LOG_ERR("clock configure failed\n");
569 return -EIO;
570 }
571
572 #if !defined(CONFIG_SOC_SERIES_STM32WBAX)
573 LL_RCC_EnableRTC();
574 #endif
575
576 z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
577
578 #if !defined(CONFIG_COUNTER_RTC_STM32_SAVE_VALUE_BETWEEN_RESETS)
579 if (LL_RTC_DeInit(RTC) != SUCCESS) {
580 return -EIO;
581 }
582 #endif
583
584 if (LL_RTC_Init(RTC, ((LL_RTC_InitTypeDef *)
585 &cfg->ll_rtc_config)) != SUCCESS) {
586 return -EIO;
587 }
588
589 #ifdef RTC_CR_BYPSHAD
590 LL_RTC_DisableWriteProtection(RTC);
591 LL_RTC_EnableShadowRegBypass(RTC);
592 LL_RTC_EnableWriteProtection(RTC);
593 #endif /* RTC_CR_BYPSHAD */
594
595 #if defined(CONFIG_SOC_SERIES_STM32H7X) && defined(CONFIG_CPU_CORTEX_M4)
596 LL_C2_EXTI_EnableIT_0_31(RTC_EXTI_LINE);
597 LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE);
598 #elif defined(CONFIG_SOC_SERIES_STM32U5X) || defined(CONFIG_SOC_SERIES_STM32WBAX)
599 /* in STM32U5 family RTC is not connected to EXTI */
600 #else
601 LL_EXTI_EnableIT_0_31(RTC_EXTI_LINE);
602 LL_EXTI_EnableRisingTrig_0_31(RTC_EXTI_LINE);
603 #endif
604
605 rtc_stm32_irq_config(dev);
606
607 return 0;
608 }
609
610 static struct rtc_stm32_data rtc_data;
611
612 #if DT_INST_NUM_CLOCKS(0) == 1
613 #warning STM32 RTC needs a kernel source clock. Please define it in dts file
614 static const struct stm32_pclken rtc_clk[] = {
615 STM32_CLOCK_INFO(0, DT_DRV_INST(0)),
616 /* Use Kconfig to configure source clocks fields (Deprecated) */
617 /* Fortunately, values are consistent across enabled series */
618 #ifdef CONFIG_COUNTER_RTC_STM32_CLOCK_LSE
619 {.bus = STM32_SRC_LSE, .enr = RTC_SEL(1)}
620 #else
621 {.bus = STM32_SRC_LSI, .enr = RTC_SEL(2)}
622 #endif
623 };
624 #else
625 static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0);
626 #endif
627
628 static const struct rtc_stm32_config rtc_config = {
629 .counter_info = {
630 .max_top_value = UINT32_MAX,
631 #ifndef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
632 /* freq = 1Hz for not subsec based driver */
633 .freq = RTCCLK_FREQ / ((RTC_ASYNCPRE + 1) * (RTC_SYNCPRE + 1)),
634 #else /* !CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
635 .freq = RTCCLK_FREQ / (RTC_ASYNCPRE + 1),
636 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
637 .flags = COUNTER_CONFIG_INFO_COUNT_UP,
638 .channels = 1,
639 },
640 .ll_rtc_config = {
641 .AsynchPrescaler = RTC_ASYNCPRE,
642 #if !defined(CONFIG_SOC_SERIES_STM32F1X)
643 .HourFormat = LL_RTC_HOURFORMAT_24HOUR,
644 .SynchPrescaler = RTC_SYNCPRE,
645 #else /* CONFIG_SOC_SERIES_STM32F1X */
646 .OutPutSource = LL_RTC_CALIB_OUTPUT_NONE,
647 #endif /* CONFIG_SOC_SERIES_STM32F1X */
648 },
649 .pclken = rtc_clk,
650 };
651
652 #ifdef CONFIG_PM_DEVICE
rtc_stm32_pm_action(const struct device * dev,enum pm_device_action action)653 static int rtc_stm32_pm_action(const struct device *dev,
654 enum pm_device_action action)
655 {
656 const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
657 const struct rtc_stm32_config *cfg = dev->config;
658
659 switch (action) {
660 case PM_DEVICE_ACTION_RESUME:
661 /* Enable RTC bus clock */
662 if (clock_control_on(clk, (clock_control_subsys_t) &cfg->pclken[0]) != 0) {
663 LOG_ERR("clock op failed\n");
664 return -EIO;
665 }
666 break;
667 case PM_DEVICE_ACTION_SUSPEND:
668 break;
669 default:
670 return -ENOTSUP;
671 }
672
673 return 0;
674 }
675 #endif /* CONFIG_PM_DEVICE */
676
677 static const struct counter_driver_api rtc_stm32_driver_api = {
678 .start = rtc_stm32_start,
679 .stop = rtc_stm32_stop,
680 .get_value = rtc_stm32_get_value,
681 #ifdef CONFIG_COUNTER_RTC_STM32_SUBSECONDS
682 .get_value_64 = rtc_stm32_get_value_64,
683 #endif /* CONFIG_COUNTER_RTC_STM32_SUBSECONDS */
684 .set_alarm = rtc_stm32_set_alarm,
685 .cancel_alarm = rtc_stm32_cancel_alarm,
686 .set_top_value = rtc_stm32_set_top_value,
687 .get_pending_int = rtc_stm32_get_pending_int,
688 .get_top_value = rtc_stm32_get_top_value,
689 };
690
691 PM_DEVICE_DT_INST_DEFINE(0, rtc_stm32_pm_action);
692
693 DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, PM_DEVICE_DT_INST_GET(0),
694 &rtc_data, &rtc_config, PRE_KERNEL_1,
695 CONFIG_COUNTER_INIT_PRIORITY, &rtc_stm32_driver_api);
696
rtc_stm32_irq_config(const struct device * dev)697 static void rtc_stm32_irq_config(const struct device *dev)
698 {
699 IRQ_CONNECT(DT_INST_IRQN(0),
700 DT_INST_IRQ(0, priority),
701 rtc_stm32_isr, DEVICE_DT_INST_GET(0), 0);
702 irq_enable(DT_INST_IRQN(0));
703 }
704