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