/***************************************************************************//**
* \file cyhal_rtc.h
*
* \brief
* Provides a high level interface for interacting with the Real Time Clock on
* Cypress devices. This interface abstracts out the chip specific details.
* If any chip specific functionality is necessary, or performance is critical
* the low level functions can be used directly.
*
********************************************************************************
* \copyright
* Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or
* an affiliate of Cypress Semiconductor Corporation
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*******************************************************************************/
/**
* \addtogroup group_hal_rtc RTC (Real-Time Clock)
* \ingroup group_hal
* \{
* High level interface for interacting with the real-time clock (RTC).
*
* The real time clock provides tracking of the current time and date, as
* well as the ability to trigger a callback at a specific time in the future.
*
* \section section_rtc_features Features
* * Configurable interrupt and callback assignment on RTC event \ref cyhal_rtc_event_t
* * Set alarm for a specific time and date \ref cyhal_rtc_set_alarm
* * Daylight Savings Time adjustment
*
* \section section_rtc_quickstart Quick Start
*
* Initialise the RTC using \ref cyhal_rtc_init. Set the current time and date using \ref cyhal_rtc_write.
* See \ref subsection_rtc_snippet_1 to initialize RTC, read and write current date and time to the RTC peripheral.
* See \ref subsection_rtc_snippet_2 to set an alarm event on a specific time and date.
*
* \section section_rtc_snippets Code snippets
* \subsection subsection_rtc_snippet_1 Snippet 1: Initialize RTC, write and read current time and date
* The following code snippet initialises the RTC using the \ref cyhal_rtc_init. The current date and time are set using \ref cyhal_rtc_write.
* The current date and time is read from the RTC using \ref cyhal_rtc_read. The time structure tm , contains the calendar date and time which
* are broken down into its components. This structure is declared in standard C library time.h which is included by HAL.
* \snippet hal_rtc.c snippet_cyhal_rtc_read_write_data_time
*
* \subsection subsection_rtc_snippet_2 Snippet 2: RTC Alarm using Callbacks
* The following code snippet configures the RTC to trigger an alarm event on a specified date and time using \ref cyhal_rtc_set_alarm.
* A callback is registered to handle the alarm event using \ref cyhal_rtc_register_callback.
* \snippet hal_rtc.c snippet_cyhal_set_alarm_callback
*/
#pragma once
#include
#include
#include
#include "cy_result.h"
#include "cyhal_hw_types.h"
#if defined(__cplusplus)
extern "C" {
#endif
/** \addtogroup group_hal_results_rtc RTC HAL Results
* RTC specific return codes
* \ingroup group_hal_results
* \{ *//**
*/
/** RTC not initialized */
#define CY_RSLT_RTC_NOT_INITIALIZED \
(CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_RTC, 0))
/** Bad argument */
#define CY_RSLT_RTC_BAD_ARGUMENT \
(CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_RTC, 1))
/** Unsupported feature */
#define CYHAL_RTC_RSLT_ERR_NOT_SUPPORTED \
(CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_RTC, 2))
/**
* \}
*/
/** RTC interrupt triggers */
typedef enum {
CYHAL_RTC_ALARM, /**< Alarm triggered event */
} cyhal_rtc_event_t;
/** @brief Defines which fields should be active for the alarm. */
typedef struct
{
uint8_t en_sec : 1; /**< Enable match of seconds */
uint8_t en_min : 1; /**< Enable match of minutes */
uint8_t en_hour : 1; /**< Enable match of hours */
uint8_t en_day : 1; /**< Enable match of day of week */
uint8_t en_date : 1; /**< Enable match of date in month */
uint8_t en_month : 1; /**< Enable match of month */
} cyhal_alarm_active_t;
/** Enumeration used to configure the DST format
*
* \note In areas of the world that practice DST, when it should begin and end is not unique. It
* can either be in fixed DST format or in relative DST format.
*/
typedef enum
{
CYHAL_RTC_DST_RELATIVE, /**< Relative DST format. eg: Begins on the last Sunday of March
and ends on the last Sunday of October. */
CYHAL_RTC_DST_FIXED /**< Fixed DST format. eg: Begins on 21st March
and ends on 21st September. */
} cyhal_rtc_dst_format_t;
/**
* Day Light Savings Time (DST) structure for setting when to apply. It allows to
* set the DST time and date using a fixed or relative time format.
*/
typedef struct
{
cyhal_rtc_dst_format_t format; /**< DST format. See /ref cyhal_rtc_dst_format_t.
Based on this value other structure elements
should be filled or could be ignored */
uint32_t hour; /**< Hour in 24hour format, range[0-23] */
union
{
uint32_t dayOfMonth; /**< Day of Month, range[1-31]. */
struct /* format = CYHAL_RTC_DST_FIXED */
{
uint32_t dayOfWeek; /**< Day of the week, starting on Sunday, range[0-6] */
uint32_t weekOfMonth; /**< Week of month, range[0-5]. Where 5 => Last week of month */
}; /**< Anonymous struct specifying the week number plus day of week */
}; /**< Anonymous union for the day as either a specific day (dayOfMonth)
or as a week number (weekOfMonth) plus day of week (dayOfWeek) */
uint32_t month; /**< Month value, range[1-12]. */
} cyhal_rtc_dst_t;
/** Handler for RTC events (eg: alarm) */
typedef void (*cyhal_rtc_event_callback_t)(void *callback_arg, cyhal_rtc_event_t event);
/** Initialize the RTC peripheral
*
* Power up the RTC in preparation for access. This function must be called
* before any other RTC functions are called. This does not change the state
* of the RTC. It just enables access to it.
* @note Before calling this, make sure all necessary System Clocks are setup
* correctly. Generally this means making sure the RTC has access to a crystal
* oscillator for optimal accuracy and operation in low power.
* @note Previously set time configurations are retained. This will only reset
* the time if no prior configuration can be determined.
*
* @param[out] obj Pointer to an RTC object. The caller must allocate the memory
* for this object but the init function will initialize its contents.
* @return The status of the init request
*/
cy_rslt_t cyhal_rtc_init(cyhal_rtc_t *obj);
/** Initialize the RTC peripheral using a configurator generated configuration struct
*
* Power up the RTC in preparation for access. This function must be called
* before any other RTC functions are called. This does not change the state
* of the RTC. It just enables access to it.
* NOTE: Before calling this, make sure all necessary System Clocks are setup
* correctly. Generally this means making sure the RTC has access to a crystal
* oscillator for optimal accuracy and operation in low power.
* NOTE: Previously set time configurations are retained. This will only reset
* the time if no prior configuration can be determined.
*
* @param[out] obj Pointer to an RTC object. The caller must allocate the memory
* for this object but the init function will initialize its contents.
* @param[in] cfg Configuration structure generated by a configurator.
* @return The status of the init request
*/
cy_rslt_t cyhal_rtc_init_cfg(cyhal_rtc_t *obj, const cyhal_rtc_configurator_t *cfg);
/** Deinitialize RTC
*
* Frees resources associated with the RTC and disables CPU access. This
* only affects the CPU domain and not the time keeping logic.
* After this function is called no other RTC functions should be called
* except for rtc_init.
*
* @param[in,out] obj RTC object
*/
void cyhal_rtc_free(cyhal_rtc_t *obj);
/** Check if the RTC has the time set and is counting
*
* @param[in] obj RTC object
* @return Whether the RTC is enabled or not
*/
bool cyhal_rtc_is_enabled(cyhal_rtc_t *obj);
/** Get the current time and date from the RTC peripheral
*
* @param[in] obj RTC object
* @param[out] time The current time (see: https://en.cppreference.com/w/cpp/chrono/c/tm)
* @return The status of the read request
*/
cy_rslt_t cyhal_rtc_read(cyhal_rtc_t *obj, struct tm *time);
/** Write the specified time and date to the RTC peripheral
*
* @param[in] obj RTC object
* @param[in] time The time to be set (see: https://en.cppreference.com/w/cpp/chrono/c/tm)
* @return The status of the write request
*/
cy_rslt_t cyhal_rtc_write(cyhal_rtc_t *obj, const struct tm *time);
/** Write the specified time and date values to the RTC peripheral
* @param[in] obj RTC object
* @param[in] sec Second to set (0-59)
* @param[in] min Minute to set (0-59)
* @param[in] hour Hour to set (0-23)
* @param[in] day Day of month to set (1-31)
* @param[in] month Month to set (1-12)
* @param[in] year 4-digit year to set
* @return The status of the write request
*/
cy_rslt_t cyhal_rtc_write_direct(cyhal_rtc_t *obj, uint32_t sec, uint32_t min, uint32_t hour,
uint32_t day, uint32_t month, uint32_t year);
/** Set the start and end time for Day Light Savings
*
* Calling this function will allow alarms to account for daylight saving time.
* This means that the RTC will be adjusted when a daylight saving time
* transition occurs, meaning times passed to \ref cyhal_rtc_set_alarm()
* will be interpreted as being in DST/not in DST as appropriate.
*
* @param[in] obj RTC object
* @param[in] start When Day Light Savings time should start
* @param[in] stop When Day Light Savings time should end
* @return The status of the set_dst request
*/
cy_rslt_t cyhal_rtc_set_dst(cyhal_rtc_t *obj, const cyhal_rtc_dst_t *start, const cyhal_rtc_dst_t *stop);
/** Checks to see if Day Light Savings Time is currently active. This should only be called after
* \ref cyhal_rtc_set_dst().
*
* @param[in] obj RTC object
* @return Boolean indicating whether the current date/time is within the specified DST start/stop window.
*/
bool cyhal_rtc_is_dst(cyhal_rtc_t *obj);
/** Set an alarm (interrupt) for the specified time and date using the RTC peripheral
*
* This requires that a callback handler is registered by \ref cyhal_rtc_register_callback and that
* the \ref CYHAL_RTC_ALARM event is enabled by \ref cyhal_rtc_enable_event.
*
* @param[in] obj RTC object
* @param[in] time The alarm time to be set (see: https://en.cppreference.com/w/cpp/chrono/c/tm)
* @param[in] active The set of fields that are checked to trigger the alarm
* @return The status of the set_alarm request
*/
cy_rslt_t cyhal_rtc_set_alarm(cyhal_rtc_t *obj, const struct tm *time, cyhal_alarm_active_t active);
/** Set an alarm (interrupt) at a specified number of seconds in the future
*
* This requires that a callback handler is registered by \ref cyhal_rtc_register_callback and that
* the \ref CYHAL_RTC_ALARM event is enabled by \ref cyhal_rtc_enable_event.
*
* @param[in] obj RTC object
* @param[in] seconds The number of seconds in the future for the alarm to be
* set to. Because alarms cannot match the year (see \ref cyhal_alarm_active_t)
* the maximum number of seconds allowed is 365d*24h*60m*60s == 31,536,000s
* @return The status of the set_alarm_by_seconds request
*/
cy_rslt_t cyhal_rtc_set_alarm_by_seconds(cyhal_rtc_t *obj, const uint32_t seconds);
/** Register a RTC event callback handler
*
* This function will be called when one of the events enabled by \ref cyhal_rtc_enable_event occurs.
*
* @param[in] obj The RTC object
* @param[in] callback The callback handler which will be invoked when the alarm event fires
* @param[in] callback_arg Generic argument that will be provided to the callback when called
*/
void cyhal_rtc_register_callback(cyhal_rtc_t *obj, cyhal_rtc_event_callback_t callback, void *callback_arg);
/** Configure RTC event (eg: alarm) enablement.
*
* When an enabled event occurs, the function specified by \ref cyhal_rtc_register_callback will be called.
*
* @param[in] obj The RTC object
* @param[in] event The RTC event type
* @param[in] intr_priority The priority for NVIC interrupt events
* @param[in] enable True to turn on interrupts, False to turn off
*/
void cyhal_rtc_enable_event(cyhal_rtc_t *obj, cyhal_rtc_event_t event, uint8_t intr_priority, bool enable);
#if defined(__cplusplus)
}
#endif
#ifdef CYHAL_RTC_IMPL_HEADER
#include CYHAL_RTC_IMPL_HEADER
#endif /* CYHAL_RTC_IMPL_HEADER */
/** \} group_hal_rtc */