LCOV - code coverage report
Current view: top level - zephyr/drivers - rtc.h Hit Total Coverage
Test: new.info Lines: 26 35 74.3 %
Date: 2024-12-22 00:14:23

          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_ */

Generated by: LCOV version 1.14