zephyr/include/zephyr/drivers/rtc.h
Yong Cong Sin bbe5e1e6eb build: namespace the generated headers with zephyr/
Namespaced the generated headers with `zephyr` to prevent
potential conflict with other headers.

Introduce a temporary Kconfig `LEGACY_GENERATED_INCLUDE_PATH`
that is enabled by default. This allows the developers to
continue the use of the old include paths for the time being
until it is deprecated and eventually removed. The Kconfig will
generate a build-time warning message, similar to the
`CONFIG_TIMER_RANDOM_GENERATOR`.

Updated the includes path of in-tree sources accordingly.

Most of the changes here are scripted, check the PR for more
info.

Signed-off-by: Yong Cong Sin <ycsin@meta.com>
2024-05-28 22:03:55 +02:00

545 lines
15 KiB
C

/*
* 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
* @since 3.4
* @version 0.1.0
* @ingroup io_interfaces
* @{
*/
#include <zephyr/types.h>
#include <zephyr/device.h>
#include <errno.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Mask for alarm time fields to enable when setting alarm time
* @name RTC Alarm Time Mask
* @anchor 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);
/**
* @cond INTERNAL_HIDDEN
*
* For internal driver use only, skip these in public documentation.
*/
/**
* @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 */
};
/** @endcond */
/**
* @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);
}
/**
* @name RTC Interface Alarm
* @{
*/
#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 */
/**
* @}
*/
/**
* @name RTC Interface Update
* @{
*/
#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 */
/**
* @}
*/
/**
* @name RTC Interface Calibration
* @{
*/
#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 */
/**
* @}
*/
/**
* @name RTC Interface Helpers
* @{
*/
/**
* @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 <zephyr/syscalls/rtc.h>
#endif /* ZEPHYR_INCLUDE_DRIVERS_RTC_H_ */