Line data Source code
1 1 : /*
2 : * Copyright (c) 2023 Trackunit Corporation
3 : * Copyright (c) 2023 Bjarki Arge Andreasen
4 : *
5 : * SPDX-License-Identifier: Apache-2.0
6 : */
7 :
8 : /**
9 : * @file drivers/rtc.h
10 : * @ingroup rtc_interface
11 : * @brief Main header file for real-time clock (RTC) driver API.
12 : */
13 :
14 : #ifndef ZEPHYR_INCLUDE_DRIVERS_RTC_H_
15 : #define ZEPHYR_INCLUDE_DRIVERS_RTC_H_
16 :
17 : /**
18 : * @brief Interfaces for real-time clocks (RTC).
19 : * @defgroup rtc_interface RTC
20 : * @since 3.4
21 : * @version 0.1.0
22 : * @ingroup io_interfaces
23 : * @{
24 : */
25 :
26 : #include <zephyr/kernel.h>
27 : #include <zephyr/device.h>
28 : #include <errno.h>
29 :
30 : #ifdef __cplusplus
31 : extern "C" {
32 : #endif
33 :
34 : /**
35 : * @brief Mask for alarm time fields to enable when setting alarm time
36 : * @name RTC Alarm Time Mask
37 : * @anchor RTC_ALARM_TIME_MASK
38 : * @{
39 : */
40 0 : #define RTC_ALARM_TIME_MASK_SECOND BIT(0)
41 0 : #define RTC_ALARM_TIME_MASK_MINUTE BIT(1)
42 0 : #define RTC_ALARM_TIME_MASK_HOUR BIT(2)
43 0 : #define RTC_ALARM_TIME_MASK_MONTHDAY BIT(3)
44 0 : #define RTC_ALARM_TIME_MASK_MONTH BIT(4)
45 0 : #define RTC_ALARM_TIME_MASK_YEAR BIT(5)
46 0 : #define RTC_ALARM_TIME_MASK_WEEKDAY BIT(6)
47 0 : #define RTC_ALARM_TIME_MASK_YEARDAY BIT(7)
48 0 : #define RTC_ALARM_TIME_MASK_NSEC BIT(8)
49 : /**
50 : * @}
51 : */
52 :
53 : /**
54 : * @brief Structure for storing date and time values with sub-second precision.
55 : *
56 : * @details The structure is 1-1 mapped to the struct tm for the members
57 : * \p tm_sec to \p tm_isdst making it compatible with the standard time library.
58 : *
59 : * @note Use \ref rtc_time_to_tm() to safely cast from a \ref rtc_time
60 : * pointer to a \ref tm pointer.
61 : */
62 1 : struct rtc_time {
63 1 : int tm_sec; /**< Seconds [0, 59] */
64 1 : int tm_min; /**< Minutes [0, 59] */
65 1 : int tm_hour; /**< Hours [0, 23] */
66 1 : int tm_mday; /**< Day of the month [1, 31] */
67 1 : int tm_mon; /**< Month [0, 11] */
68 1 : int tm_year; /**< Year - 1900 */
69 1 : int tm_wday; /**< Day of the week [0, 6] (Sunday = 0) (Unknown = -1) */
70 1 : int tm_yday; /**< Day of the year [0, 365] (Unknown = -1) */
71 1 : int tm_isdst; /**< Daylight saving time flag [-1] (Unknown = -1) */
72 1 : int tm_nsec; /**< Nanoseconds [0, 999999999] (Unknown = 0) */
73 : };
74 :
75 : /**
76 : * @typedef rtc_update_callback
77 : * @brief RTC update event callback
78 : *
79 : * @param dev Device instance invoking the handler
80 : * @param user_data Optional user data provided when update irq callback is set
81 : */
82 1 : typedef void (*rtc_update_callback)(const struct device *dev, void *user_data);
83 :
84 : /**
85 : * @typedef rtc_alarm_callback
86 : * @brief RTC alarm triggered callback
87 : *
88 : * @param dev Device instance invoking the handler
89 : * @param id Alarm id
90 : * @param user_data Optional user data passed with the alarm configuration
91 : */
92 1 : typedef void (*rtc_alarm_callback)(const struct device *dev, uint16_t id, void *user_data);
93 :
94 : /**
95 : * @cond INTERNAL_HIDDEN
96 : *
97 : * For internal driver use only, skip these in public documentation.
98 : */
99 :
100 : /**
101 : * @typedef rtc_api_set_time
102 : * @brief API for setting RTC time
103 : */
104 : typedef int (*rtc_api_set_time)(const struct device *dev, const struct rtc_time *timeptr);
105 :
106 : /**
107 : * @typedef rtc_api_get_time
108 : * @brief API for getting RTC time
109 : */
110 : typedef int (*rtc_api_get_time)(const struct device *dev, struct rtc_time *timeptr);
111 :
112 : /**
113 : * @typedef rtc_api_alarm_get_supported_fields
114 : * @brief API for getting the supported fields of the RTC alarm time
115 : */
116 : typedef int (*rtc_api_alarm_get_supported_fields)(const struct device *dev, uint16_t id,
117 : uint16_t *mask);
118 :
119 : /**
120 : * @typedef rtc_api_alarm_set_time
121 : * @brief API for setting RTC alarm time
122 : */
123 : typedef int (*rtc_api_alarm_set_time)(const struct device *dev, uint16_t id, uint16_t mask,
124 : const struct rtc_time *timeptr);
125 :
126 : /**
127 : * @typedef rtc_api_alarm_get_time
128 : * @brief API for getting RTC alarm time
129 : */
130 : typedef int (*rtc_api_alarm_get_time)(const struct device *dev, uint16_t id, uint16_t *mask,
131 : struct rtc_time *timeptr);
132 :
133 : /**
134 : * @typedef rtc_api_alarm_is_pending
135 : * @brief API for testing if RTC alarm is pending
136 : */
137 : typedef int (*rtc_api_alarm_is_pending)(const struct device *dev, uint16_t id);
138 :
139 : /**
140 : * @typedef rtc_api_alarm_set_callback
141 : * @brief API for setting RTC alarm callback
142 : */
143 : typedef int (*rtc_api_alarm_set_callback)(const struct device *dev, uint16_t id,
144 : rtc_alarm_callback callback, void *user_data);
145 :
146 : /**
147 : * @typedef rtc_api_update_set_callback
148 : * @brief API for setting RTC update callback
149 : */
150 : typedef int (*rtc_api_update_set_callback)(const struct device *dev,
151 : rtc_update_callback callback, void *user_data);
152 :
153 : /**
154 : * @typedef rtc_api_set_calibration
155 : * @brief API for setting RTC calibration
156 : */
157 : typedef int (*rtc_api_set_calibration)(const struct device *dev, int32_t calibration);
158 :
159 : /**
160 : * @typedef rtc_api_get_calibration
161 : * @brief API for getting RTC calibration
162 : */
163 : typedef int (*rtc_api_get_calibration)(const struct device *dev, int32_t *calibration);
164 :
165 : /**
166 : * @brief RTC driver API
167 : */
168 : __subsystem struct rtc_driver_api {
169 : rtc_api_set_time set_time;
170 : rtc_api_get_time get_time;
171 : #if defined(CONFIG_RTC_ALARM) || defined(__DOXYGEN__)
172 : rtc_api_alarm_get_supported_fields alarm_get_supported_fields;
173 : rtc_api_alarm_set_time alarm_set_time;
174 : rtc_api_alarm_get_time alarm_get_time;
175 : rtc_api_alarm_is_pending alarm_is_pending;
176 : rtc_api_alarm_set_callback alarm_set_callback;
177 : #endif /* CONFIG_RTC_ALARM */
178 : #if defined(CONFIG_RTC_UPDATE) || defined(__DOXYGEN__)
179 : rtc_api_update_set_callback update_set_callback;
180 : #endif /* CONFIG_RTC_UPDATE */
181 : #if defined(CONFIG_RTC_CALIBRATION) || defined(__DOXYGEN__)
182 : rtc_api_set_calibration set_calibration;
183 : rtc_api_get_calibration get_calibration;
184 : #endif /* CONFIG_RTC_CALIBRATION */
185 : };
186 :
187 : /** @endcond */
188 :
189 : /**
190 : * @brief API for setting RTC time.
191 : *
192 : * @param dev Device instance
193 : * @param timeptr The time to set
194 : *
195 : * @return 0 if successful
196 : * @return -EINVAL if RTC time is invalid or exceeds hardware capabilities
197 : * @return -errno code if failure
198 : */
199 1 : __syscall int rtc_set_time(const struct device *dev, const struct rtc_time *timeptr);
200 :
201 : static inline int z_impl_rtc_set_time(const struct device *dev, const struct rtc_time *timeptr)
202 : {
203 : return DEVICE_API_GET(rtc, dev)->set_time(dev, timeptr);
204 : }
205 :
206 : /**
207 : * @brief API for getting RTC time.
208 : *
209 : * @param dev Device instance
210 : * @param timeptr Destination for the time
211 : *
212 : * @return 0 if successful
213 : * @return -ENODATA if RTC time has not been set
214 : * @return -errno code if failure
215 : */
216 1 : __syscall int rtc_get_time(const struct device *dev, struct rtc_time *timeptr);
217 :
218 : static inline int z_impl_rtc_get_time(const struct device *dev, struct rtc_time *timeptr)
219 : {
220 : return DEVICE_API_GET(rtc, dev)->get_time(dev, timeptr);
221 : }
222 :
223 : /**
224 : * @name RTC Interface Alarm
225 : * @{
226 : */
227 : #if defined(CONFIG_RTC_ALARM) || defined(__DOXYGEN__)
228 :
229 : /**
230 : * @brief API for getting the supported fields of the RTC alarm time.
231 : *
232 : * @param dev Device instance
233 : * @param id Id of the alarm
234 : * @param mask Mask of fields in the alarm time which are supported
235 : *
236 : * @note Bits in the mask param are defined here @ref RTC_ALARM_TIME_MASK.
237 : *
238 : * @return 0 if successful
239 : * @return -EINVAL if id is out of range or time is invalid
240 : * @return -ENOTSUP if API is not supported by hardware
241 : * @return -errno code if failure
242 : */
243 1 : __syscall int rtc_alarm_get_supported_fields(const struct device *dev, uint16_t id,
244 : uint16_t *mask);
245 :
246 : static inline int z_impl_rtc_alarm_get_supported_fields(const struct device *dev, uint16_t id,
247 : uint16_t *mask)
248 : {
249 : if (DEVICE_API_GET(rtc, dev)->alarm_get_supported_fields == NULL) {
250 : return -ENOSYS;
251 : }
252 :
253 : return DEVICE_API_GET(rtc, dev)->alarm_get_supported_fields(dev, id, mask);
254 : }
255 :
256 : /**
257 : * @brief API for setting RTC alarm time.
258 : *
259 : * @details To enable an RTC alarm, one or more fields of the RTC alarm time
260 : * must be enabled. The mask designates which fields of the RTC alarm time to
261 : * enable. If the mask parameter is 0, the alarm will be disabled. The RTC
262 : * alarm will trigger when all enabled fields of the alarm time match the RTC
263 : * time.
264 : *
265 : * @param dev Device instance
266 : * @param id Id of the alarm
267 : * @param mask Mask of fields in the alarm time to enable
268 : * @param timeptr The alarm time to set
269 : *
270 : * @note The timeptr param may be NULL if the mask param is 0
271 : * @note Only the enabled fields in the timeptr param need to be configured
272 : * @note Bits in the mask param are defined here @ref RTC_ALARM_TIME_MASK
273 : *
274 : * @return 0 if successful
275 : * @return -EINVAL if id is out of range or time is invalid
276 : * @return -ENOTSUP if API is not supported by hardware
277 : * @return -errno code if failure
278 : */
279 1 : __syscall int rtc_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
280 : const struct rtc_time *timeptr);
281 :
282 : static inline int z_impl_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask,
283 : const struct rtc_time *timeptr)
284 : {
285 : if (DEVICE_API_GET(rtc, dev)->alarm_set_time == NULL) {
286 : return -ENOSYS;
287 : }
288 :
289 : return DEVICE_API_GET(rtc, dev)->alarm_set_time(dev, id, mask, timeptr);
290 : }
291 :
292 : /**
293 : * @brief API for getting RTC alarm time.
294 : *
295 : * @param dev Device instance
296 : * @param id Id of the alarm
297 : * @param mask Destination for mask of fields which are enabled in the alarm time
298 : * @param timeptr Destination for the alarm time
299 : *
300 : * @note Bits in the mask param are defined here @ref RTC_ALARM_TIME_MASK
301 : *
302 : * @return 0 if successful
303 : * @return -EINVAL if id is out of range
304 : * @return -ENOTSUP if API is not supported by hardware
305 : * @return -errno code if failure
306 : */
307 1 : __syscall int rtc_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
308 : struct rtc_time *timeptr);
309 :
310 : static inline int z_impl_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask,
311 : struct rtc_time *timeptr)
312 : {
313 : if (DEVICE_API_GET(rtc, dev)->alarm_get_time == NULL) {
314 : return -ENOSYS;
315 : }
316 :
317 : return DEVICE_API_GET(rtc, dev)->alarm_get_time(dev, id, mask, timeptr);
318 : }
319 :
320 : /**
321 : * @brief API for testing if RTC alarm is pending.
322 : *
323 : * @details Test whether or not the alarm with id is pending. If the alarm
324 : * is pending, the pending status is cleared.
325 : *
326 : * @param dev Device instance
327 : * @param id Id of the alarm to test
328 : *
329 : * @return 1 if alarm was pending
330 : * @return 0 if alarm was not pending
331 : * @return -EINVAL if id is out of range
332 : * @return -ENOTSUP if API is not supported by hardware
333 : * @return -errno code if failure
334 : */
335 1 : __syscall int rtc_alarm_is_pending(const struct device *dev, uint16_t id);
336 :
337 : static inline int z_impl_rtc_alarm_is_pending(const struct device *dev, uint16_t id)
338 : {
339 : if (DEVICE_API_GET(rtc, dev)->alarm_is_pending == NULL) {
340 : return -ENOSYS;
341 : }
342 :
343 : return DEVICE_API_GET(rtc, dev)->alarm_is_pending(dev, id);
344 : }
345 :
346 : /**
347 : * @brief API for setting alarm callback.
348 : *
349 : * @details Setting the alarm callback for an alarm, will enable the
350 : * alarm callback. When the callback for an alarm is enabled, the
351 : * alarm triggered event will invoke the callback, after which the
352 : * alarm pending status will be cleared automatically. The alarm will
353 : * remain enabled until manually disabled using
354 : * \ref rtc_alarm_set_time().
355 : *
356 : * To disable the alarm callback for an alarm, the \p callback and
357 : * \p user_data parameters must be set to NULL. When the alarm
358 : * callback for an alarm is disabled, the alarm triggered event will
359 : * set the alarm status to "pending". To check if the alarm status is
360 : * "pending", use \ref rtc_alarm_is_pending().
361 : *
362 : * @param dev Device instance
363 : * @param id Id of the alarm for which the callback shall be set
364 : * @param callback Callback called when alarm occurs
365 : * @param user_data Optional user data passed to callback
366 : *
367 : * @return 0 if successful
368 : * @return -EINVAL if id is out of range
369 : * @return -ENOTSUP if API is not supported by hardware
370 : * @return -errno code if failure
371 : */
372 1 : static inline int rtc_alarm_set_callback(const struct device *dev, uint16_t id,
373 : rtc_alarm_callback callback, void *user_data)
374 : {
375 : if (DEVICE_API_GET(rtc, dev)->alarm_set_callback == NULL) {
376 : return -ENOSYS;
377 : }
378 :
379 : return DEVICE_API_GET(rtc, dev)->alarm_set_callback(dev, id, callback, user_data);
380 : }
381 :
382 : #endif /* CONFIG_RTC_ALARM */
383 : /**
384 : * @}
385 : */
386 :
387 : /**
388 : * @name RTC Interface Update
389 : * @{
390 : */
391 : #if defined(CONFIG_RTC_UPDATE) || defined(__DOXYGEN__)
392 :
393 : /**
394 : * @brief API for setting update callback.
395 : *
396 : * @details Setting the update callback will enable the update
397 : * callback. The update callback will be invoked every time the
398 : * RTC clock is updated by 1 second. It can be used to
399 : * synchronize the RTC clock with other clock sources.
400 : *
401 : * To disable the update callback for the RTC clock, the
402 : * \p callback and \p user_data parameters must be set to NULL.
403 : *
404 : * @param dev Device instance
405 : * @param callback Callback called when update occurs
406 : * @param user_data Optional user data passed to callback
407 : *
408 : * @return 0 if successful
409 : * @return -ENOTSUP if API is not supported by hardware
410 : * @return -errno code if failure
411 : */
412 1 : static inline int rtc_update_set_callback(const struct device *dev,
413 : rtc_update_callback callback, void *user_data)
414 : {
415 : if (DEVICE_API_GET(rtc, dev)->update_set_callback == NULL) {
416 : return -ENOSYS;
417 : }
418 :
419 : return DEVICE_API_GET(rtc, dev)->update_set_callback(dev, callback, user_data);
420 : }
421 :
422 : #endif /* CONFIG_RTC_UPDATE */
423 : /**
424 : * @}
425 : */
426 :
427 : /**
428 : * @name RTC Interface Calibration
429 : * @{
430 : */
431 : #if defined(CONFIG_RTC_CALIBRATION) || defined(__DOXYGEN__)
432 :
433 : /**
434 : * @brief API for setting RTC calibration.
435 : *
436 : * @details Calibration is applied to the RTC clock input. A
437 : * positive calibration value will increase the frequency of
438 : * the RTC clock, a negative value will decrease the
439 : * frequency of the RTC clock.
440 : *
441 : * @see rtc_calibration_from_frequency()
442 : *
443 : * @param dev Device instance
444 : * @param calibration Calibration to set in parts per billion
445 : *
446 : * @return 0 if successful
447 : * @return -EINVAL if calibration is out of range
448 : * @return -ENOTSUP if API is not supported by hardware
449 : * @return -errno code if failure
450 : */
451 1 : __syscall int rtc_set_calibration(const struct device *dev, int32_t calibration);
452 :
453 : static inline int z_impl_rtc_set_calibration(const struct device *dev, int32_t calibration)
454 : {
455 : if (DEVICE_API_GET(rtc, dev)->set_calibration == NULL) {
456 : return -ENOSYS;
457 : }
458 :
459 : return DEVICE_API_GET(rtc, dev)->set_calibration(dev, calibration);
460 : }
461 :
462 : /**
463 : * @brief API for getting RTC calibration.
464 : *
465 : * @param dev Device instance
466 : * @param calibration Destination for calibration in parts per billion
467 : *
468 : * @return 0 if successful
469 : * @return -ENOTSUP if API is not supported by hardware
470 : * @return -errno code if failure
471 : */
472 1 : __syscall int rtc_get_calibration(const struct device *dev, int32_t *calibration);
473 :
474 : static inline int z_impl_rtc_get_calibration(const struct device *dev, int32_t *calibration)
475 : {
476 : if (DEVICE_API_GET(rtc, dev)->get_calibration == NULL) {
477 : return -ENOSYS;
478 : }
479 :
480 : return DEVICE_API_GET(rtc, dev)->get_calibration(dev, calibration);
481 : }
482 :
483 : #endif /* CONFIG_RTC_CALIBRATION */
484 : /**
485 : * @}
486 : */
487 :
488 : /**
489 : * @name RTC Interface Helpers
490 : * @{
491 : */
492 :
493 : /**
494 : * @brief Forward declaration of struct tm for \ref rtc_time_to_tm().
495 : */
496 : struct tm;
497 :
498 : /**
499 : * @brief Convenience function for safely casting a \ref rtc_time pointer
500 : * to a \ref tm pointer.
501 : */
502 1 : static inline struct tm *rtc_time_to_tm(struct rtc_time *timeptr)
503 : {
504 : return (struct tm *)timeptr;
505 : }
506 :
507 : /**
508 : * @brief Determine required calibration to 1 Hertz from frequency.
509 : *
510 : * @param frequency Frequency of the RTC in nano Hertz
511 : *
512 : * @return The required calibration in parts per billion
513 : */
514 1 : static inline int32_t rtc_calibration_from_frequency(uint32_t frequency)
515 : {
516 : __ASSERT_NO_MSG(frequency > 0);
517 :
518 : return (int32_t)((1000000000000000000LL / frequency) - 1000000000);
519 : }
520 :
521 : /**
522 : * @}
523 : */
524 :
525 : /**
526 : * @}
527 : */
528 :
529 : #ifdef __cplusplus
530 : }
531 : #endif
532 :
533 : #include <zephyr/syscalls/rtc.h>
534 :
535 : #endif /* ZEPHYR_INCLUDE_DRIVERS_RTC_H_ */
|