1 /*
2  * Copyright (c) 2023 Prevas A/S
3  * Copyright (c) 2023 Syslinbit
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  */
8 
9 #define DT_DRV_COMPAT st_stm32_rtc
10 
11 #include <errno.h>
12 #include <zephyr/device.h>
13 #include <zephyr/kernel.h>
14 #include <zephyr/init.h>
15 #include <zephyr/devicetree.h>
16 #include <zephyr/drivers/rtc.h>
17 #include <zephyr/drivers/clock_control/stm32_clock_control.h>
18 #include <zephyr/drivers/clock_control.h>
19 #include <zephyr/sys/util.h>
20 #include <soc.h>
21 #include <stm32_ll_pwr.h>
22 #include <stm32_ll_rcc.h>
23 #include <stm32_ll_rtc.h>
24 #include <stm32_hsem.h>
25 
26 #include <zephyr/logging/log.h>
27 
28 #include <stdbool.h>
29 
30 LOG_MODULE_REGISTER(rtc_stm32, CONFIG_RTC_LOG_LEVEL);
31 
32 #if defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SUBSECOND_SUPPORT)
33 /* subsecond counting is not supported by some STM32L1x MCUs */
34 #define HW_SUBSECOND_SUPPORT (0)
35 #else
36 #define HW_SUBSECOND_SUPPORT (1)
37 #endif
38 
39 /* RTC start time: 1st, Jan, 2000 */
40 #define RTC_YEAR_REF 2000
41 /* struct tm start time:   1st, Jan, 1900 */
42 #define TM_YEAR_REF 1900
43 
44 /* Convert part per billion calibration value to a number of clock pulses added or removed each
45  * 2^20 clock cycles so it is suitable for the CALR register fields
46  *
47  * nb_pulses = ppb * 2^20 / 10^9 = ppb * 2^11 / 5^9 = ppb * 2048 / 1953125
48  */
49 #define PPB_TO_NB_PULSES(ppb) DIV_ROUND_CLOSEST((ppb) * 2048, 1953125)
50 
51 /* Convert CALR register value (number of clock pulses added or removed each 2^20 clock cycles)
52  * to part ber billion calibration value
53  *
54  * ppb = nb_pulses * 10^9 / 2^20 = nb_pulses * 5^9 / 2^11 = nb_pulses * 1953125 / 2048
55  */
56 #define NB_PULSES_TO_PPB(pulses) DIV_ROUND_CLOSEST((pulses) * 1953125, 2048)
57 
58 /* CALP field can only be 512 or 0 as in reality CALP is a single bit field representing 512 pulses
59  * added every 2^20 clock cycles
60  */
61 #define MAX_CALP (512)
62 #define MAX_CALM (511)
63 
64 #define MAX_PPB NB_PULSES_TO_PPB(MAX_CALP)
65 #define MIN_PPB -NB_PULSES_TO_PPB(MAX_CALM)
66 
67 /* Timeout in microseconds used to wait for flags */
68 #define RTC_TIMEOUT 1000000
69 
70 struct rtc_stm32_config {
71 	uint32_t async_prescaler;
72 	uint32_t sync_prescaler;
73 	const struct stm32_pclken *pclken;
74 };
75 
76 struct rtc_stm32_data {
77 	struct k_mutex lock;
78 };
79 
rtc_stm32_enter_initialization_mode(bool kernel_available)80 static int rtc_stm32_enter_initialization_mode(bool kernel_available)
81 {
82 	if (kernel_available) {
83 		LL_RTC_EnableInitMode(RTC);
84 		bool success = WAIT_FOR(LL_RTC_IsActiveFlag_INIT(RTC), RTC_TIMEOUT, k_msleep(1));
85 
86 		if (!success) {
87 			return -EIO;
88 		}
89 	} else {
90 		/* kernel is not available so use the blocking but otherwise equivalent function
91 		 * provided by LL
92 		 */
93 		ErrorStatus status = LL_RTC_EnterInitMode(RTC);
94 
95 		if (status != SUCCESS) {
96 			return -EIO;
97 		}
98 	}
99 
100 	return 0;
101 }
102 
rtc_stm32_leave_initialization_mode(void)103 static inline void rtc_stm32_leave_initialization_mode(void)
104 {
105 	LL_RTC_DisableInitMode(RTC);
106 }
107 
rtc_stm32_configure(const struct device * dev)108 static int rtc_stm32_configure(const struct device *dev)
109 {
110 	const struct rtc_stm32_config *cfg = dev->config;
111 
112 	int err = 0;
113 
114 	uint32_t hour_format     = LL_RTC_GetHourFormat(RTC);
115 	uint32_t sync_prescaler  = LL_RTC_GetSynchPrescaler(RTC);
116 	uint32_t async_prescaler = LL_RTC_GetAsynchPrescaler(RTC);
117 
118 	LL_RTC_DisableWriteProtection(RTC);
119 
120 	/* configuration process requires to stop the RTC counter so do it
121 	 * only if needed to avoid inducing time drift at each reset
122 	 */
123 	if ((hour_format != LL_RTC_HOURFORMAT_24HOUR) ||
124 	    (sync_prescaler != cfg->sync_prescaler) ||
125 	    (async_prescaler != cfg->async_prescaler)) {
126 		err = rtc_stm32_enter_initialization_mode(false);
127 		if (err == 0) {
128 			LL_RTC_SetHourFormat(RTC, LL_RTC_HOURFORMAT_24HOUR);
129 			LL_RTC_SetSynchPrescaler(RTC, cfg->sync_prescaler);
130 			LL_RTC_SetAsynchPrescaler(RTC, cfg->async_prescaler);
131 		}
132 
133 		rtc_stm32_leave_initialization_mode();
134 	}
135 
136 #ifdef RTC_CR_BYPSHAD
137 	LL_RTC_EnableShadowRegBypass(RTC);
138 #endif /* RTC_CR_BYPSHAD */
139 
140 	LL_RTC_EnableWriteProtection(RTC);
141 
142 	return err;
143 }
144 
rtc_stm32_init(const struct device * dev)145 static int rtc_stm32_init(const struct device *dev)
146 {
147 	const struct device *const clk = DEVICE_DT_GET(STM32_CLOCK_CONTROL_NODE);
148 	const struct rtc_stm32_config *cfg = dev->config;
149 	struct rtc_stm32_data *data = dev->data;
150 
151 	int err = 0;
152 
153 	if (!device_is_ready(clk)) {
154 		LOG_ERR("clock control device not ready");
155 		return -ENODEV;
156 	}
157 
158 	/* Enable RTC bus clock */
159 	if (clock_control_on(clk, (clock_control_subsys_t)&cfg->pclken[0]) != 0) {
160 		LOG_ERR("clock op failed\n");
161 		return -EIO;
162 	}
163 
164 	k_mutex_init(&data->lock);
165 
166 	/* Enable Backup access */
167 	z_stm32_hsem_lock(CFG_HW_RCC_SEMID, HSEM_LOCK_DEFAULT_RETRY);
168 #if defined(PWR_CR_DBP) || defined(PWR_CR1_DBP) || defined(PWR_DBPCR_DBP) || defined(PWR_DBPR_DBP)
169 	LL_PWR_EnableBkUpAccess();
170 #endif /* PWR_CR_DBP || PWR_CR1_DBP || PWR_DBPR_DBP */
171 
172 	/* Enable RTC clock source */
173 	if (clock_control_configure(clk, (clock_control_subsys_t)&cfg->pclken[1], NULL) != 0) {
174 		LOG_ERR("clock configure failed\n");
175 		return -EIO;
176 	}
177 
178 	LL_RCC_EnableRTC();
179 
180 	z_stm32_hsem_unlock(CFG_HW_RCC_SEMID);
181 
182 	err = rtc_stm32_configure(dev);
183 
184 	return err;
185 }
186 
rtc_stm32_set_time(const struct device * dev,const struct rtc_time * timeptr)187 static int rtc_stm32_set_time(const struct device *dev, const struct rtc_time *timeptr)
188 {
189 	struct rtc_stm32_data *data = dev->data;
190 
191 	uint32_t real_year = timeptr->tm_year + TM_YEAR_REF;
192 
193 	int err = 0;
194 
195 	if (real_year < RTC_YEAR_REF) {
196 		/* RTC does not support years before 2000 */
197 		return -EINVAL;
198 	}
199 
200 	if (timeptr->tm_wday == -1) {
201 		/* day of the week is expected */
202 		return -EINVAL;
203 	}
204 
205 	err = k_mutex_lock(&data->lock, K_NO_WAIT);
206 	if (err) {
207 		return err;
208 	}
209 
210 	LOG_INF("Setting clock");
211 	LL_RTC_DisableWriteProtection(RTC);
212 
213 	err = rtc_stm32_enter_initialization_mode(true);
214 	if (err) {
215 		k_mutex_unlock(&data->lock);
216 		return err;
217 	}
218 
219 	LL_RTC_DATE_SetYear(RTC, bin2bcd(real_year - RTC_YEAR_REF));
220 	LL_RTC_DATE_SetMonth(RTC, bin2bcd(timeptr->tm_mon + 1));
221 	LL_RTC_DATE_SetDay(RTC, bin2bcd(timeptr->tm_mday));
222 
223 	if (timeptr->tm_wday == 0) {
224 		/* sunday (tm_wday = 0) is not represented by the same value in hardware */
225 		LL_RTC_DATE_SetWeekDay(RTC, LL_RTC_WEEKDAY_SUNDAY);
226 	} else {
227 		/* all the other values are consistent with what is expected by hardware */
228 		LL_RTC_DATE_SetWeekDay(RTC, timeptr->tm_wday);
229 	}
230 
231 
232 	LL_RTC_TIME_SetHour(RTC, bin2bcd(timeptr->tm_hour));
233 	LL_RTC_TIME_SetMinute(RTC, bin2bcd(timeptr->tm_min));
234 	LL_RTC_TIME_SetSecond(RTC, bin2bcd(timeptr->tm_sec));
235 
236 	rtc_stm32_leave_initialization_mode();
237 
238 	LL_RTC_EnableWriteProtection(RTC);
239 
240 	k_mutex_unlock(&data->lock);
241 
242 	return err;
243 }
244 
rtc_stm32_get_time(const struct device * dev,struct rtc_time * timeptr)245 static int rtc_stm32_get_time(const struct device *dev, struct rtc_time *timeptr)
246 {
247 	struct rtc_stm32_data *data = dev->data;
248 
249 	uint32_t rtc_date, rtc_time;
250 
251 #if HW_SUBSECOND_SUPPORT
252 	const struct rtc_stm32_config *cfg = dev->config;
253 	uint32_t rtc_subsecond;
254 #endif
255 
256 	int err = k_mutex_lock(&data->lock, K_NO_WAIT);
257 
258 	if (err) {
259 		return err;
260 	}
261 
262 	do {
263 		/* read date, time and subseconds and relaunch if a day increment occurred
264 		 * while doing so as it will result in an erroneous result otherwise
265 		 */
266 		rtc_date = LL_RTC_DATE_Get(RTC);
267 		do {
268 			/* read time and subseconds and relaunch if a second increment occurred
269 			 * while doing so as it will result in an erroneous result otherwise
270 			 */
271 			rtc_time      = LL_RTC_TIME_Get(RTC);
272 #if HW_SUBSECOND_SUPPORT
273 			rtc_subsecond = LL_RTC_TIME_GetSubSecond(RTC);
274 #endif
275 		} while (rtc_time != LL_RTC_TIME_Get(RTC));
276 	} while (rtc_date != LL_RTC_DATE_Get(RTC));
277 
278 	k_mutex_unlock(&data->lock);
279 
280 	timeptr->tm_year = bcd2bin(__LL_RTC_GET_YEAR(rtc_date)) + RTC_YEAR_REF - TM_YEAR_REF;
281 	/* tm_mon allowed values are 0-11 */
282 	timeptr->tm_mon = bcd2bin(__LL_RTC_GET_MONTH(rtc_date)) - 1;
283 	timeptr->tm_mday = bcd2bin(__LL_RTC_GET_DAY(rtc_date));
284 
285 	int hw_wday = __LL_RTC_GET_WEEKDAY(rtc_date);
286 
287 	if (hw_wday == LL_RTC_WEEKDAY_SUNDAY) {
288 		/* LL_RTC_WEEKDAY_SUNDAY = 7 but a 0 is expected in tm_wday for sunday */
289 		timeptr->tm_wday = 0;
290 	} else {
291 		/* all other values are consistent between hardware and rtc_time structure */
292 		timeptr->tm_wday = hw_wday;
293 	}
294 
295 	timeptr->tm_hour = bcd2bin(__LL_RTC_GET_HOUR(rtc_time));
296 	timeptr->tm_min = bcd2bin(__LL_RTC_GET_MINUTE(rtc_time));
297 	timeptr->tm_sec = bcd2bin(__LL_RTC_GET_SECOND(rtc_time));
298 
299 #if HW_SUBSECOND_SUPPORT
300 	uint64_t temp = ((uint64_t)(cfg->sync_prescaler - rtc_subsecond)) * 1000000000L;
301 
302 	timeptr->tm_nsec = DIV_ROUND_CLOSEST(temp, cfg->sync_prescaler + 1);
303 #else
304 	timeptr->tm_nsec = 0;
305 #endif
306 
307 	/* unknown values */
308 	timeptr->tm_yday  = -1;
309 	timeptr->tm_isdst = -1;
310 
311 	return 0;
312 }
313 
314 #ifdef CONFIG_RTC_CALIBRATION
315 #if !defined(CONFIG_SOC_SERIES_STM32F2X) && \
316 	!(defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SMOOTHCALIB_SUPPORT))
rtc_stm32_set_calibration(const struct device * dev,int32_t calibration)317 static int rtc_stm32_set_calibration(const struct device *dev, int32_t calibration)
318 {
319 	ARG_UNUSED(dev);
320 
321 	/* Note : calibration is considered here to be ppb value to apply
322 	 *        on clock period (not frequency) but with an opposite sign
323 	 */
324 
325 	if ((calibration > MAX_PPB) || (calibration < MIN_PPB)) {
326 		/* out of supported range */
327 		return -EINVAL;
328 	}
329 
330 	int32_t nb_pulses = PPB_TO_NB_PULSES(calibration);
331 
332 	/* we tested calibration against supported range
333 	 * so theoretically nb_pulses is also within range
334 	 */
335 	__ASSERT_NO_MSG(nb_pulses <= MAX_CALP);
336 	__ASSERT_NO_MSG(nb_pulses >= -MAX_CALM);
337 
338 	uint32_t calp, calm;
339 
340 	if (nb_pulses > 0) {
341 		calp = LL_RTC_CALIB_INSERTPULSE_SET;
342 		calm = MAX_CALP - nb_pulses;
343 	} else {
344 		calp = LL_RTC_CALIB_INSERTPULSE_NONE;
345 		calm = -nb_pulses;
346 	}
347 
348 	/* wait for recalibration to be ok if a previous recalibration occurred */
349 	if (!WAIT_FOR(LL_RTC_IsActiveFlag_RECALP(RTC) == 0, 100000, k_msleep(1))) {
350 		return -EIO;
351 	}
352 
353 	LL_RTC_DisableWriteProtection(RTC);
354 
355 	MODIFY_REG(RTC->CALR, RTC_CALR_CALP | RTC_CALR_CALM, calp | calm);
356 
357 	LL_RTC_EnableWriteProtection(RTC);
358 
359 	return 0;
360 }
361 
rtc_stm32_get_calibration(const struct device * dev,int32_t * calibration)362 static int rtc_stm32_get_calibration(const struct device *dev, int32_t *calibration)
363 {
364 	ARG_UNUSED(dev);
365 
366 	uint32_t calr = sys_read32((mem_addr_t) &RTC->CALR);
367 
368 	bool calp_enabled = READ_BIT(calr, RTC_CALR_CALP);
369 	uint32_t calm = READ_BIT(calr, RTC_CALR_CALM);
370 
371 	int32_t nb_pulses = -((int32_t) calm);
372 
373 	if (calp_enabled) {
374 		nb_pulses += MAX_CALP;
375 	}
376 
377 	*calibration = NB_PULSES_TO_PPB(nb_pulses);
378 
379 	return 0;
380 }
381 #endif
382 #endif /* CONFIG_RTC_CALIBRATION */
383 
384 struct rtc_driver_api rtc_stm32_driver_api = {
385 	.set_time = rtc_stm32_set_time,
386 	.get_time = rtc_stm32_get_time,
387 	/* RTC_ALARM not supported */
388 	/* RTC_UPDATE not supported */
389 #ifdef CONFIG_RTC_CALIBRATION
390 #if !defined(CONFIG_SOC_SERIES_STM32F2X) && \
391 	!(defined(CONFIG_SOC_SERIES_STM32L1X) && !defined(RTC_SMOOTHCALIB_SUPPORT))
392 	.set_calibration = rtc_stm32_set_calibration,
393 	.get_calibration = rtc_stm32_get_calibration,
394 #else
395 #error RTC calibration for devices without smooth calibration feature is not supported yet
396 #endif
397 #endif /* CONFIG_RTC_CALIBRATION */
398 };
399 
400 static const struct stm32_pclken rtc_clk[] = STM32_DT_INST_CLOCKS(0);
401 
402 BUILD_ASSERT(DT_INST_CLOCKS_HAS_IDX(0, 1), "RTC source clock not defined in the device tree");
403 
404 static const struct rtc_stm32_config rtc_config = {
405 #if DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSI
406 	/* prescaler values for LSI @ 32 KHz */
407 	.async_prescaler = 0x7F,
408 	.sync_prescaler = 0x00F9,
409 #else /* DT_INST_CLOCKS_CELL_BY_IDX(0, 1, bus) == STM32_SRC_LSE */
410 	/* prescaler values for LSE @ 32768 Hz */
411 	.async_prescaler = 0x7F,
412 	.sync_prescaler = 0x00FF,
413 #endif
414 	.pclken = rtc_clk,
415 };
416 
417 static struct rtc_stm32_data rtc_data;
418 
419 DEVICE_DT_INST_DEFINE(0, &rtc_stm32_init, NULL, &rtc_data, &rtc_config, PRE_KERNEL_1,
420 		      CONFIG_RTC_INIT_PRIORITY, &rtc_stm32_driver_api);
421