diff --git a/doc/develop/api/overview.rst b/doc/develop/api/overview.rst index d2bc12aef48..9ece8be8375 100644 --- a/doc/develop/api/overview.rst +++ b/doc/develop/api/overview.rst @@ -245,6 +245,10 @@ between major releases are available in the :ref:`zephyr_release_notes`. - Experimental - 3.1 + * - :ref:`rtc_api` + - Experimental + - 3.4 + * - :ref:`rtio_api` - Experimental - 3.2 diff --git a/doc/hardware/peripherals/rtc.rst b/doc/hardware/peripherals/rtc.rst index 8ec4cba4015..6098f5e4a8a 100644 --- a/doc/hardware/peripherals/rtc.rst +++ b/doc/hardware/peripherals/rtc.rst @@ -6,9 +6,54 @@ Real-Time Clock (RTC) Overview ******** -This is a placeholder for API specific to real-time clocks. Currently -all RTC peripherals are implemented through :ref:`counter_api` with -device-specific API for counters with real-time support. +.. list-table:: **Glossary** + :widths: 30 80 + :header-rows: 1 + + * - Word + - Definition + * - Real-time clock + - Low power device tracking time using broken-down time + * - Real-time counter + - Low power counter which can be used to track time + * - RTC + - Acronym for real-time clock + +An RTC is a low power device which tracks time using broken-down time. +It should not be confused with low-power counters which sometimes share +the same name, acronym, or both. + +RTCs are usually optimized for low energy consumption and are usually +kept running even when the system is in a low power state. + +RTCs usually contain one or more alarms which can be configured to +trigger at a given time. These alarms are commonly used to wake up the +system from a low power state. + +History of RTCs in Zephyr +************************* + +RTCs have been supported before this API was created, using the +:ref:`counter_api` API. The unix timestamp was used to convert +between broken-down time and the unix timestamp within the RTC +drivers, which internally used the broken-down time representation. + +The disadvantages of this approach where that hardware counters can +not be set to a specific count, requiring all RTCs to use device +specific APIs to set the time, converting from unix time to +broken-down time, unnecessarily in some cases, and some common +features missing, like input clock calibration and the update +callback. + +Configuration Options +********************* + +Related configuration options: + +* :kconfig:option:`CONFIG_RTC` +* :kconfig:option:`CONFIG_RTC_ALARM` +* :kconfig:option:`CONFIG_RTC_UPDATE` +* :kconfig:option:`CONFIG_RTC_CALIBRATION` API Reference ************* diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index 98d5b55a2b9..51b16451010 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -75,3 +75,4 @@ add_subdirectory_ifdef(CONFIG_VIRTUALIZATION virtualization) add_subdirectory_ifdef(CONFIG_W1 w1) add_subdirectory_ifdef(CONFIG_WATCHDOG watchdog) add_subdirectory_ifdef(CONFIG_WIFI wifi) +add_subdirectory_ifdef(CONFIG_RTC rtc) diff --git a/drivers/Kconfig b/drivers/Kconfig index 1439d533071..1b5d60cd450 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -79,5 +79,6 @@ source "drivers/w1/Kconfig" source "drivers/watchdog/Kconfig" source "drivers/wifi/Kconfig" source "drivers/xen/Kconfig" +source "drivers/rtc/Kconfig" endmenu diff --git a/drivers/rtc/CMakeLists.txt b/drivers/rtc/CMakeLists.txt new file mode 100644 index 00000000000..7addf32d314 --- /dev/null +++ b/drivers/rtc/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2022 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_USERSPACE rtc_handlers.c) + diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig new file mode 100644 index 00000000000..0eaf1d1a9e4 --- /dev/null +++ b/drivers/rtc/Kconfig @@ -0,0 +1,26 @@ +# Copyright (c) 2022 Bjarki Arge Andreasen +# SPDX-License-Identifier: Apache-2.0 + +menuconfig RTC + bool "RTC driver support" + +if RTC + +config RTC_ALARM + bool "RTC driver alarm support" + help + This is an option which enables driver support for RTC alarms. + +config RTC_UPDATE + bool "RTC driver update event callback support" + help + This is an option which enables driver support for the RTC + update event callback. + +config RTC_CALIBRATION + bool "RTC driver clock calibration support" + help + This is an option which enables driver support for RTC clock + calibration. + +endif # RTC diff --git a/drivers/rtc/rtc_handlers.c b/drivers/rtc/rtc_handlers.c new file mode 100644 index 00000000000..a0e9cb34a8c --- /dev/null +++ b/drivers/rtc/rtc_handlers.c @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +static inline int z_vrfy_rtc_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, set_time)); + Z_OOPS(Z_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); + return z_impl_rtc_set_time(dev, timeptr); +} +#include + +static inline int z_vrfy_rtc_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, get_time)); + Z_OOPS(Z_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); + return z_impl_rtc_get_time(dev, timeptr); +} +#include + +#ifdef CONFIG_RTC_ALARM +static inline int z_vrfy_rtc_alarm_get_supported_fields(const struct device *dev, uint16_t id, + uint16_t *mask) +{ + Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_get_supported_fields)); + Z_OOPS(Z_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); + return z_impl_rtc_alarm_get_supported_fields(dev, id, mask); +} +#include + +static inline int z_vrfy_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_set_time)); + Z_OOPS(Z_SYSCALL_MEMORY_READ(timeptr, sizeof(struct rtc_time))); + return z_impl_rtc_alarm_set_time(dev, id, mask, timeptr); +} +#include + +static inline int z_vrfy_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_get_time)); + Z_OOPS(Z_SYSCALL_MEMORY_WRITE(mask, sizeof(uint16_t))); + Z_OOPS(Z_SYSCALL_MEMORY_WRITE(timeptr, sizeof(struct rtc_time))); + return z_impl_rtc_alarm_get_time(dev, id, mask, timeptr); +} +#include + +static inline int z_vrfy_rtc_alarm_is_pending(const struct device *dev, uint16_t id) +{ + Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, alarm_is_pending)); + return z_impl_rtc_alarm_is_pending(dev, id); +} +#include +#endif /* CONFIG_RTC_ALARM */ + +#ifdef CONFIG_RTC_CALIBRATION +static inline int z_vrfy_rtc_set_calibration(const struct device *dev, int32_t calibration) +{ + Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, set_calibration)); + return z_impl_rtc_set_calibration(dev, calibration); +} + +#include + +static inline int z_vrfy_rtc_get_calibration(const struct device *dev, int32_t *calibration) +{ + Z_OOPS(Z_SYSCALL_DRIVER_RTC(dev, get_calibration)); + Z_OOPS(Z_SYSCALL_MEMORY_WRITE(calibration, sizeof(int32_t))); + return z_impl_rtc_get_calibration(dev, calibration); +} +#include +#endif /* CONFIG_RTC_CALIBRATION */ diff --git a/include/zephyr/drivers/rtc.h b/include/zephyr/drivers/rtc.h new file mode 100644 index 00000000000..48da6170dab --- /dev/null +++ b/include/zephyr/drivers/rtc.h @@ -0,0 +1,540 @@ +/* + * Copyright (c) 2023 Trackunit Corporation + * Copyright (c) 2023 Bjarki Arge Andreasen + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file drivers/rtc.h + * @brief Public real time clock driver API + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_RTC_H_ +#define ZEPHYR_INCLUDE_DRIVERS_RTC_H_ + +/** + * @brief RTC Interface + * @defgroup rtc_interface RTC Interface + * @ingroup io_interfaces + * @{ + */ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Mask for alarm time fields to enable when setting alarm time + * @defgroup rtc_alarm_time_mask RTC Alarm Time Mask + * @{ + */ +#define RTC_ALARM_TIME_MASK_SECOND BIT(0) +#define RTC_ALARM_TIME_MASK_MINUTE BIT(1) +#define RTC_ALARM_TIME_MASK_HOUR BIT(2) +#define RTC_ALARM_TIME_MASK_MONTHDAY BIT(3) +#define RTC_ALARM_TIME_MASK_MONTH BIT(4) +#define RTC_ALARM_TIME_MASK_YEAR BIT(5) +#define RTC_ALARM_TIME_MASK_WEEKDAY BIT(6) +#define RTC_ALARM_TIME_MASK_YEARDAY BIT(7) +#define RTC_ALARM_TIME_MASK_NSEC BIT(8) +/** + * @} + */ + +/** + * @brief Structure for storing date and time values with sub-second precision. + * + * @details The structure is 1-1 mapped to the struct tm for the members + * \p tm_sec to \p tm_isdst making it compatible with the standard time library. + * + * @note Use \ref rtc_time_to_tm() to safely cast from a \ref rtc_time + * pointer to a \ref tm pointer. + */ +struct rtc_time { + int tm_sec; /**< Seconds [0, 59] */ + int tm_min; /**< Minutes [0, 59] */ + int tm_hour; /**< Hours [0, 23] */ + int tm_mday; /**< Day of the month [1, 31] */ + int tm_mon; /**< Month [0, 11] */ + int tm_year; /**< Year - 1900 */ + int tm_wday; /**< Day of the week [0, 6] (Sunday = 0) (Unknown = -1) */ + int tm_yday; /**< Day of the year [0, 365] (Unknown = -1) */ + int tm_isdst; /**< Daylight saving time flag [-1] (Unknown = -1) */ + int tm_nsec; /**< Nanoseconds [0, 999999999] (Unknown = 0) */ +}; + +/** + * @typedef rtc_update_callback + * @brief RTC update event callback + * + * @param dev Device instance invoking the handler + * @param user_data Optional user data provided when update irq callback is set + */ +typedef void (*rtc_update_callback)(const struct device *dev, void *user_data); + +/** + * @typedef rtc_alarm_callback + * @brief RTC alarm triggered callback + * + * @param dev Device instance invoking the handler + * @param id Alarm id + * @param user_data Optional user data passed with the alarm configuration + */ +typedef void (*rtc_alarm_callback)(const struct device *dev, uint16_t id, void *user_data); + +/** + * @typedef rtc_api_set_time + * @brief API for setting RTC time + */ +typedef int (*rtc_api_set_time)(const struct device *dev, const struct rtc_time *timeptr); + +/** + * @typedef rtc_api_get_time + * @brief API for getting RTC time + */ +typedef int (*rtc_api_get_time)(const struct device *dev, struct rtc_time *timeptr); + +/** + * @typedef rtc_api_alarm_get_supported_fields + * @brief API for getting the supported fields of the RTC alarm time + */ +typedef int (*rtc_api_alarm_get_supported_fields)(const struct device *dev, uint16_t id, + uint16_t *mask); + +/** + * @typedef rtc_api_alarm_set_time + * @brief API for setting RTC alarm time + */ +typedef int (*rtc_api_alarm_set_time)(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr); + +/** + * @typedef rtc_api_alarm_get_time + * @brief API for getting RTC alarm time + */ +typedef int (*rtc_api_alarm_get_time)(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr); + +/** + * @typedef rtc_api_alarm_is_pending + * @brief API for testing if RTC alarm is pending + */ +typedef int (*rtc_api_alarm_is_pending)(const struct device *dev, uint16_t id); + +/** + * @typedef rtc_api_alarm_set_callback + * @brief API for setting RTC alarm callback + */ +typedef int (*rtc_api_alarm_set_callback)(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data); + +/** + * @typedef rtc_api_update_set_callback + * @brief API for setting RTC update callback + */ +typedef int (*rtc_api_update_set_callback)(const struct device *dev, + rtc_update_callback callback, void *user_data); + +/** + * @typedef rtc_api_set_calibration + * @brief API for setting RTC calibration + */ +typedef int (*rtc_api_set_calibration)(const struct device *dev, int32_t calibration); + +/** + * @typedef rtc_api_get_calibration + * @brief API for getting RTC calibration + */ +typedef int (*rtc_api_get_calibration)(const struct device *dev, int32_t *calibration); + +/** + * @brief RTC driver API + */ +__subsystem struct rtc_driver_api { + rtc_api_set_time set_time; + rtc_api_get_time get_time; +#if defined(CONFIG_RTC_ALARM) || defined(__DOXYGEN__) + rtc_api_alarm_get_supported_fields alarm_get_supported_fields; + rtc_api_alarm_set_time alarm_set_time; + rtc_api_alarm_get_time alarm_get_time; + rtc_api_alarm_is_pending alarm_is_pending; + rtc_api_alarm_set_callback alarm_set_callback; +#endif /* CONFIG_RTC_ALARM */ +#if defined(CONFIG_RTC_UPDATE) || defined(__DOXYGEN__) + rtc_api_update_set_callback update_set_callback; +#endif /* CONFIG_RTC_UPDATE */ +#if defined(CONFIG_RTC_CALIBRATION) || defined(__DOXYGEN__) + rtc_api_set_calibration set_calibration; + rtc_api_get_calibration get_calibration; +#endif /* CONFIG_RTC_CALIBRATION */ +}; + +/** + * @brief API for setting RTC time. + * + * @param dev Device instance + * @param timeptr The time to set + * + * @return 0 if successful + * @return -EINVAL if RTC time is invalid or exceeds hardware capabilities + * @return -errno code if failure + */ +__syscall int rtc_set_time(const struct device *dev, const struct rtc_time *timeptr); + +static inline int z_impl_rtc_set_time(const struct device *dev, const struct rtc_time *timeptr) +{ + const struct rtc_driver_api *api = (const struct rtc_driver_api *)dev->api; + + return api->set_time(dev, timeptr); +} + +/** + * @brief API for getting RTC time. + * + * @param dev Device instance + * @param timeptr Destination for the time + * + * @return 0 if successful + * @return -ENODATA if RTC time has not been set + * @return -errno code if failure + */ +__syscall int rtc_get_time(const struct device *dev, struct rtc_time *timeptr); + +static inline int z_impl_rtc_get_time(const struct device *dev, struct rtc_time *timeptr) +{ + const struct rtc_driver_api *api = (const struct rtc_driver_api *)dev->api; + + return api->get_time(dev, timeptr); +} + +/** + * @brief RTC Interface Alarm + * @defgroup rtc_interface_alarm RTC Interface Alarm + * @ingroup rtc_interface + * @{ + */ +#if defined(CONFIG_RTC_ALARM) || defined(__DOXYGEN__) + +/** + * @brief API for getting the supported fields of the RTC alarm time. + * + * @param dev Device instance + * @param id Id of the alarm + * @param mask Mask of fields in the alarm time which are supported + * + * @note Bits in the mask param are defined here \ref rtc_alarm_time_mask + * + * @return 0 if successful + * @return -EINVAL if id is out of range or time is invalid + * @return -ENOTSUP if API is not supported by hardware + * @return -errno code if failure + */ +__syscall int rtc_alarm_get_supported_fields(const struct device *dev, uint16_t id, + uint16_t *mask); + +static inline int z_impl_rtc_alarm_get_supported_fields(const struct device *dev, uint16_t id, + uint16_t *mask) +{ + const struct rtc_driver_api *api = (const struct rtc_driver_api *)dev->api; + + if (api->alarm_get_supported_fields == NULL) { + return -ENOSYS; + } + + return api->alarm_get_supported_fields(dev, id, mask); +} + +/** + * @brief API for setting RTC alarm time. + * + * @details To enable an RTC alarm, one or more fields of the RTC alarm time + * must be enabled. The mask designates which fields of the RTC alarm time to + * enable. If the mask parameter is 0, the alarm will be disabled. The RTC + * alarm will trigger when all enabled fields of the alarm time match the RTC + * time. + * + * @param dev Device instance + * @param id Id of the alarm + * @param mask Mask of fields in the alarm time to enable + * @param timeptr The alarm time to set + * + * @note The timeptr param may be NULL if the mask param is 0 + * @note Only the enabled fields in the timeptr param need to be configured + * @note Bits in the mask param are defined here \ref rtc_alarm_time_mask + * + * @return 0 if successful + * @return -EINVAL if id is out of range or time is invalid + * @return -ENOTSUP if API is not supported by hardware + * @return -errno code if failure + */ +__syscall int rtc_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr); + +static inline int z_impl_rtc_alarm_set_time(const struct device *dev, uint16_t id, uint16_t mask, + const struct rtc_time *timeptr) +{ + const struct rtc_driver_api *api = (const struct rtc_driver_api *)dev->api; + + if (api->alarm_set_time == NULL) { + return -ENOSYS; + } + + return api->alarm_set_time(dev, id, mask, timeptr); +} + +/** + * @brief API for getting RTC alarm time. + * + * @param dev Device instance + * @param id Id of the alarm + * @param mask Destination for mask of fields which are enabled in the alarm time + * @param timeptr Destination for the alarm time + * + * @note Bits in the mask param are defined here \ref rtc_alarm_time_mask + * + * @return 0 if successful + * @return -EINVAL if id is out of range + * @return -ENOTSUP if API is not supported by hardware + * @return -errno code if failure + */ +__syscall int rtc_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr); + +static inline int z_impl_rtc_alarm_get_time(const struct device *dev, uint16_t id, uint16_t *mask, + struct rtc_time *timeptr) +{ + const struct rtc_driver_api *api = (const struct rtc_driver_api *)dev->api; + + if (api->alarm_get_time == NULL) { + return -ENOSYS; + } + + return api->alarm_get_time(dev, id, mask, timeptr); +} + +/** + * @brief API for testing if RTC alarm is pending. + * + * @details Test whether or not the alarm with id is pending. If the alarm + * is pending, the pending status is cleared. + * + * @param dev Device instance + * @param id Id of the alarm to test + * + * @return 1 if alarm was pending + * @return 0 if alarm was not pending + * @return -EINVAL if id is out of range + * @return -ENOTSUP if API is not supported by hardware + * @return -errno code if failure + */ +__syscall int rtc_alarm_is_pending(const struct device *dev, uint16_t id); + +static inline int z_impl_rtc_alarm_is_pending(const struct device *dev, uint16_t id) +{ + const struct rtc_driver_api *api = (const struct rtc_driver_api *)dev->api; + + if (api->alarm_is_pending == NULL) { + return -ENOSYS; + } + + return api->alarm_is_pending(dev, id); +} + +/** + * @brief API for setting alarm callback. + * + * @details Setting the alarm callback for an alarm, will enable the + * alarm callback. When the callback for an alarm is enabled, the + * alarm triggered event will invoke the callback, after which the + * alarm pending status will be cleared automatically. The alarm will + * remain enabled until manually disabled using + * \ref rtc_alarm_set_time(). + * + * To disable the alarm callback for an alarm, the \p callback and + * \p user_data parameters must be set to NULL. When the alarm + * callback for an alarm is disabled, the alarm triggered event will + * set the alarm status to "pending". To check if the alarm status is + * "pending", use \ref rtc_alarm_is_pending(). + * + * @param dev Device instance + * @param id Id of the alarm for which the callback shall be set + * @param callback Callback called when alarm occurs + * @param user_data Optional user data passed to callback + * + * @return 0 if successful + * @return -EINVAL if id is out of range + * @return -ENOTSUP if API is not supported by hardware + * @return -errno code if failure + */ +__syscall int rtc_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data); + +static inline int z_impl_rtc_alarm_set_callback(const struct device *dev, uint16_t id, + rtc_alarm_callback callback, void *user_data) +{ + const struct rtc_driver_api *api = (const struct rtc_driver_api *)dev->api; + + if (api->alarm_set_callback == NULL) { + return -ENOSYS; + } + + return api->alarm_set_callback(dev, id, callback, user_data); +} + +#endif /* CONFIG_RTC_ALARM */ +/** + * @} + */ + +/** + * @brief RTC Interface Update + * @defgroup rtc_interface_update RTC Interface Update + * @ingroup rtc_interface + * @{ + */ +#if defined(CONFIG_RTC_UPDATE) || defined(__DOXYGEN__) + +/** + * @brief API for setting update callback. + * + * @details Setting the update callback will enable the update + * callback. The update callback will be invoked every time the + * RTC clock is updated by 1 second. It can be used to + * synchronize the RTC clock with other clock sources. + * + * To disable the update callback for the RTC clock, the + * \p callback and \p user_data parameters must be set to NULL. + * + * @param dev Device instance + * @param callback Callback called when update occurs + * @param user_data Optional user data passed to callback + * + * @return 0 if successful + * @return -ENOTSUP if API is not supported by hardware + * @return -errno code if failure + */ +__syscall int rtc_update_set_callback(const struct device *dev, rtc_update_callback callback, + void *user_data); + +static inline int z_impl_rtc_update_set_callback(const struct device *dev, + rtc_update_callback callback, void *user_data) +{ + const struct rtc_driver_api *api = (const struct rtc_driver_api *)dev->api; + + if (api->update_set_callback == NULL) { + return -ENOSYS; + } + + return api->update_set_callback(dev, callback, user_data); +} + +#endif /* CONFIG_RTC_UPDATE */ +/** + * @} + */ + +/** + * @brief RTC Interface Calibration + * @defgroup rtc_interface_calibration RTC Interface Calibration + * @ingroup rtc_interface + * @{ + */ +#if defined(CONFIG_RTC_CALIBRATION) || defined(__DOXYGEN__) + +/** + * @brief API for setting RTC calibration. + * + * @details Calibration is applied to the RTC clock input. A + * positive calibration value will increase the frequency of + * the RTC clock, a negative value will decrease the + * frequency of the RTC clock. + * + * @param dev Device instance + * @param calibration Calibration to set in parts per billion + * + * @return 0 if successful + * @return -EINVAL if calibration is out of range + * @return -ENOTSUP if API is not supported by hardware + * @return -errno code if failure + */ +__syscall int rtc_set_calibration(const struct device *dev, int32_t calibration); + +static inline int z_impl_rtc_set_calibration(const struct device *dev, int32_t calibration) +{ + const struct rtc_driver_api *api = (const struct rtc_driver_api *)dev->api; + + if (api->set_calibration == NULL) { + return -ENOSYS; + } + + return api->set_calibration(dev, calibration); +} + +/** + * @brief API for getting RTC calibration. + * + * @param dev Device instance + * @param calibration Destination for calibration in parts per billion + * + * @return 0 if successful + * @return -ENOTSUP if API is not supported by hardware + * @return -errno code if failure + */ +__syscall int rtc_get_calibration(const struct device *dev, int32_t *calibration); + +static inline int z_impl_rtc_get_calibration(const struct device *dev, int32_t *calibration) +{ + const struct rtc_driver_api *api = (const struct rtc_driver_api *)dev->api; + + if (api->get_calibration == NULL) { + return -ENOSYS; + } + + return api->get_calibration(dev, calibration); +} + +#endif /* CONFIG_RTC_CALIBRATION */ +/** + * @} + */ + +/** + * @brief RTC Interface Helpers + * @ingroup rtc_interface + * @{ + */ + +/** + * @brief Forward declaration of struct tm for \ref rtc_time_to_tm(). + */ +struct tm; + +/** + * @brief Convenience function for safely casting a \ref rtc_time pointer + * to a \ref tm pointer. + */ +static inline struct tm *rtc_time_to_tm(struct rtc_time *timeptr) +{ + return (struct tm *)timeptr; +} + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#include + +#endif /* ZEPHYR_INCLUDE_DRIVERS_RTC_H_ */ diff --git a/include/zephyr/drivers/rtc/maxim_ds3231.h b/include/zephyr/drivers/rtc/maxim_ds3231.h index 2c97e255653..6e9a4a1cb39 100644 --- a/include/zephyr/drivers/rtc/maxim_ds3231.h +++ b/include/zephyr/drivers/rtc/maxim_ds3231.h @@ -208,7 +208,7 @@ extern "C" { /** * @brief RTC DS3231 Driver-Specific API - * @defgroup rtc_interface Real Time Clock interfaces + * @defgroup rtc_ds3231_interface RTC DS3231 Interface * @ingroup io_interfaces * @{ */