1 /***************************************************************************//** 2 * \file cyhal_rtc.h 3 * 4 * \brief 5 * Provides a high level interface for interacting with the Real Time Clock on 6 * Cypress devices. This interface abstracts out the chip specific details. 7 * If any chip specific functionality is necessary, or performance is critical 8 * the low level functions can be used directly. 9 * 10 ******************************************************************************** 11 * \copyright 12 * Copyright 2018-2022 Cypress Semiconductor Corporation (an Infineon company) or 13 * an affiliate of Cypress Semiconductor Corporation 14 * 15 * SPDX-License-Identifier: Apache-2.0 16 * 17 * Licensed under the Apache License, Version 2.0 (the "License"); 18 * you may not use this file except in compliance with the License. 19 * You may obtain a copy of the License at 20 * 21 * http://www.apache.org/licenses/LICENSE-2.0 22 * 23 * Unless required by applicable law or agreed to in writing, software 24 * distributed under the License is distributed on an "AS IS" BASIS, 25 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 26 * See the License for the specific language governing permissions and 27 * limitations under the License. 28 *******************************************************************************/ 29 30 /** 31 * \addtogroup group_hal_rtc RTC (Real-Time Clock) 32 * \ingroup group_hal 33 * \{ 34 * High level interface for interacting with the real-time clock (RTC). 35 * 36 * The real time clock provides tracking of the current time and date, as 37 * well as the ability to trigger a callback at a specific time in the future. 38 * 39 * \section section_rtc_features Features 40 * * Configurable interrupt and callback assignment on RTC event \ref cyhal_rtc_event_t 41 * * Set alarm for a specific time and date \ref cyhal_rtc_set_alarm 42 * * Daylight Savings Time adjustment 43 * 44 * \section section_rtc_quickstart Quick Start 45 * 46 * Initialise the RTC using \ref cyhal_rtc_init. Set the current time and date using \ref cyhal_rtc_write. <br> 47 * See \ref subsection_rtc_snippet_1 to initialize RTC, read and write current date and time to the RTC peripheral. 48 * See \ref subsection_rtc_snippet_2 to set an alarm event on a specific time and date. 49 * 50 * \section section_rtc_snippets Code snippets 51 * \subsection subsection_rtc_snippet_1 Snippet 1: Initialize RTC, write and read current time and date 52 * 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. 53 * The current date and time is read from the RTC using \ref cyhal_rtc_read. The time structure <b> tm </b>, contains the calendar date and time which 54 * are broken down into its components. This structure is declared in standard C library time.h which is included by HAL. 55 * \snippet hal_rtc.c snippet_cyhal_rtc_read_write_data_time 56 * 57 * \subsection subsection_rtc_snippet_2 Snippet 2: RTC Alarm using Callbacks 58 * The following code snippet configures the RTC to trigger an alarm event on a specified date and time using \ref cyhal_rtc_set_alarm. 59 * A callback is registered to handle the alarm event using \ref cyhal_rtc_register_callback. 60 * \snippet hal_rtc.c snippet_cyhal_set_alarm_callback 61 */ 62 63 #pragma once 64 65 #include <stdint.h> 66 #include <stdbool.h> 67 #include <time.h> 68 #include "cy_result.h" 69 #include "cyhal_hw_types.h" 70 71 #if defined(__cplusplus) 72 extern "C" { 73 #endif 74 75 /** \addtogroup group_hal_results_rtc RTC HAL Results 76 * RTC specific return codes 77 * \ingroup group_hal_results 78 * \{ *//** 79 */ 80 81 /** RTC not initialized */ 82 #define CY_RSLT_RTC_NOT_INITIALIZED \ 83 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_RTC, 0)) 84 /** Bad argument */ 85 #define CY_RSLT_RTC_BAD_ARGUMENT \ 86 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_RTC, 1)) 87 /** Unsupported feature */ 88 #define CYHAL_RTC_RSLT_ERR_NOT_SUPPORTED \ 89 (CY_RSLT_CREATE_EX(CY_RSLT_TYPE_ERROR, CY_RSLT_MODULE_ABSTRACTION_HAL, CYHAL_RSLT_MODULE_RTC, 2)) 90 91 /** 92 * \} 93 */ 94 95 /** RTC interrupt triggers */ 96 typedef enum { 97 CYHAL_RTC_ALARM, /**< Alarm triggered event */ 98 } cyhal_rtc_event_t; 99 100 /** @brief Defines which fields should be active for the alarm. */ 101 typedef struct 102 { 103 uint8_t en_sec : 1; /**< Enable match of seconds */ 104 uint8_t en_min : 1; /**< Enable match of minutes */ 105 uint8_t en_hour : 1; /**< Enable match of hours */ 106 uint8_t en_day : 1; /**< Enable match of day of week */ 107 uint8_t en_date : 1; /**< Enable match of date in month */ 108 uint8_t en_month : 1; /**< Enable match of month */ 109 } cyhal_alarm_active_t; 110 111 /** Enumeration used to configure the DST format 112 * 113 * \note In areas of the world that practice DST, when it should begin and end is not unique. It 114 * can either be in fixed DST format or in relative DST format. 115 */ 116 typedef enum 117 { 118 CYHAL_RTC_DST_RELATIVE, /**< Relative DST format. eg: Begins on the last Sunday of March 119 and ends on the last Sunday of October. */ 120 CYHAL_RTC_DST_FIXED /**< Fixed DST format. eg: Begins on 21st March 121 and ends on 21st September. */ 122 } cyhal_rtc_dst_format_t; 123 124 /** 125 * Day Light Savings Time (DST) structure for setting when to apply. It allows to 126 * set the DST time and date using a fixed or relative time format. 127 */ 128 typedef struct 129 { 130 cyhal_rtc_dst_format_t format; /**< DST format. See /ref cyhal_rtc_dst_format_t. 131 Based on this value other structure elements 132 should be filled or could be ignored */ 133 uint32_t hour; /**< Hour in 24hour format, range[0-23] */ 134 union 135 { 136 uint32_t dayOfMonth; /**< Day of Month, range[1-31]. */ 137 struct /* format = CYHAL_RTC_DST_FIXED */ 138 { 139 uint32_t dayOfWeek; /**< Day of the week, starting on Sunday, range[0-6] */ 140 uint32_t weekOfMonth; /**< Week of month, range[0-5]. Where 5 => Last week of month */ 141 }; /**< Anonymous struct specifying the week number plus day of week */ 142 }; /**< Anonymous union for the day as either a specific day (dayOfMonth) 143 or as a week number (weekOfMonth) plus day of week (dayOfWeek) */ 144 uint32_t month; /**< Month value, range[1-12]. */ 145 } cyhal_rtc_dst_t; 146 147 /** Handler for RTC events (eg: alarm) */ 148 typedef void (*cyhal_rtc_event_callback_t)(void *callback_arg, cyhal_rtc_event_t event); 149 150 /** Initialize the RTC peripheral 151 * 152 * Power up the RTC in preparation for access. This function must be called 153 * before any other RTC functions are called. This does not change the state 154 * of the RTC. It just enables access to it. 155 * @note Before calling this, make sure all necessary System Clocks are setup 156 * correctly. Generally this means making sure the RTC has access to a crystal 157 * oscillator for optimal accuracy and operation in low power. 158 * @note Previously set time configurations are retained. This will only reset 159 * the time if no prior configuration can be determined. 160 * 161 * @param[out] obj Pointer to an RTC object. The caller must allocate the memory 162 * for this object but the init function will initialize its contents. 163 * @return The status of the init request 164 */ 165 cy_rslt_t cyhal_rtc_init(cyhal_rtc_t *obj); 166 167 /** Initialize the RTC peripheral using a configurator generated configuration struct 168 * 169 * Power up the RTC in preparation for access. This function must be called 170 * before any other RTC functions are called. This does not change the state 171 * of the RTC. It just enables access to it. 172 * NOTE: Before calling this, make sure all necessary System Clocks are setup 173 * correctly. Generally this means making sure the RTC has access to a crystal 174 * oscillator for optimal accuracy and operation in low power. 175 * NOTE: Previously set time configurations are retained. This will only reset 176 * the time if no prior configuration can be determined. 177 * 178 * @param[out] obj Pointer to an RTC object. The caller must allocate the memory 179 * for this object but the init function will initialize its contents. 180 * @param[in] cfg Configuration structure generated by a configurator. 181 * @return The status of the init request 182 */ 183 cy_rslt_t cyhal_rtc_init_cfg(cyhal_rtc_t *obj, const cyhal_rtc_configurator_t *cfg); 184 185 /** Deinitialize RTC 186 * 187 * Frees resources associated with the RTC and disables CPU access. This 188 * only affects the CPU domain and not the time keeping logic. 189 * After this function is called no other RTC functions should be called 190 * except for rtc_init. 191 * 192 * @param[in,out] obj RTC object 193 */ 194 void cyhal_rtc_free(cyhal_rtc_t *obj); 195 196 /** Check if the RTC has the time set and is counting 197 * 198 * @param[in] obj RTC object 199 * @return Whether the RTC is enabled or not 200 */ 201 bool cyhal_rtc_is_enabled(cyhal_rtc_t *obj); 202 203 /** Get the current time and date from the RTC peripheral 204 * 205 * @param[in] obj RTC object 206 * @param[out] time The current time (see: https://en.cppreference.com/w/cpp/chrono/c/tm) 207 * @return The status of the read request 208 */ 209 cy_rslt_t cyhal_rtc_read(cyhal_rtc_t *obj, struct tm *time); 210 211 /** Write the specified time and date to the RTC peripheral 212 * 213 * @param[in] obj RTC object 214 * @param[in] time The time to be set (see: https://en.cppreference.com/w/cpp/chrono/c/tm) 215 * @return The status of the write request 216 */ 217 cy_rslt_t cyhal_rtc_write(cyhal_rtc_t *obj, const struct tm *time); 218 219 /** Write the specified time and date values to the RTC peripheral 220 * @param[in] obj RTC object 221 * @param[in] sec Second to set (0-59) 222 * @param[in] min Minute to set (0-59) 223 * @param[in] hour Hour to set (0-23) 224 * @param[in] day Day of month to set (1-31) 225 * @param[in] month Month to set (1-12) 226 * @param[in] year 4-digit year to set 227 * @return The status of the write request 228 */ 229 cy_rslt_t cyhal_rtc_write_direct(cyhal_rtc_t *obj, uint32_t sec, uint32_t min, uint32_t hour, 230 uint32_t day, uint32_t month, uint32_t year); 231 232 /** Set the start and end time for Day Light Savings 233 * 234 * Calling this function will allow alarms to account for daylight saving time. 235 * This means that the RTC will be adjusted when a daylight saving time 236 * transition occurs, meaning times passed to \ref cyhal_rtc_set_alarm() 237 * will be interpreted as being in DST/not in DST as appropriate. 238 * 239 * @param[in] obj RTC object 240 * @param[in] start When Day Light Savings time should start 241 * @param[in] stop When Day Light Savings time should end 242 * @return The status of the set_dst request 243 */ 244 cy_rslt_t cyhal_rtc_set_dst(cyhal_rtc_t *obj, const cyhal_rtc_dst_t *start, const cyhal_rtc_dst_t *stop); 245 246 /** Checks to see if Day Light Savings Time is currently active. This should only be called after 247 * \ref cyhal_rtc_set_dst(). 248 * 249 * @param[in] obj RTC object 250 * @return Boolean indicating whether the current date/time is within the specified DST start/stop window. 251 */ 252 bool cyhal_rtc_is_dst(cyhal_rtc_t *obj); 253 254 /** Set an alarm (interrupt) for the specified time and date using the RTC peripheral 255 * 256 * This requires that a callback handler is registered by \ref cyhal_rtc_register_callback and that 257 * the \ref CYHAL_RTC_ALARM event is enabled by \ref cyhal_rtc_enable_event. 258 * 259 * @param[in] obj RTC object 260 * @param[in] time The alarm time to be set (see: https://en.cppreference.com/w/cpp/chrono/c/tm) 261 * @param[in] active The set of fields that are checked to trigger the alarm 262 * @return The status of the set_alarm request 263 */ 264 cy_rslt_t cyhal_rtc_set_alarm(cyhal_rtc_t *obj, const struct tm *time, cyhal_alarm_active_t active); 265 266 /** Set an alarm (interrupt) at a specified number of seconds in the future 267 * 268 * This requires that a callback handler is registered by \ref cyhal_rtc_register_callback and that 269 * the \ref CYHAL_RTC_ALARM event is enabled by \ref cyhal_rtc_enable_event. 270 * 271 * @param[in] obj RTC object 272 * @param[in] seconds The number of seconds in the future for the alarm to be 273 * set to. Because alarms cannot match the year (see \ref cyhal_alarm_active_t) 274 * the maximum number of seconds allowed is 365d*24h*60m*60s == 31,536,000s 275 * @return The status of the set_alarm_by_seconds request 276 */ 277 cy_rslt_t cyhal_rtc_set_alarm_by_seconds(cyhal_rtc_t *obj, const uint32_t seconds); 278 279 /** Register a RTC event callback handler 280 * 281 * This function will be called when one of the events enabled by \ref cyhal_rtc_enable_event occurs. 282 * 283 * @param[in] obj The RTC object 284 * @param[in] callback The callback handler which will be invoked when the alarm event fires 285 * @param[in] callback_arg Generic argument that will be provided to the callback when called 286 */ 287 void cyhal_rtc_register_callback(cyhal_rtc_t *obj, cyhal_rtc_event_callback_t callback, void *callback_arg); 288 289 /** Configure RTC event (eg: alarm) enablement. 290 * 291 * When an enabled event occurs, the function specified by \ref cyhal_rtc_register_callback will be called. 292 * 293 * @param[in] obj The RTC object 294 * @param[in] event The RTC event type 295 * @param[in] intr_priority The priority for NVIC interrupt events 296 * @param[in] enable True to turn on interrupts, False to turn off 297 */ 298 void cyhal_rtc_enable_event(cyhal_rtc_t *obj, cyhal_rtc_event_t event, uint8_t intr_priority, bool enable); 299 300 #if defined(__cplusplus) 301 } 302 #endif 303 304 #ifdef CYHAL_RTC_IMPL_HEADER 305 #include CYHAL_RTC_IMPL_HEADER 306 #endif /* CYHAL_RTC_IMPL_HEADER */ 307 308 /** \} group_hal_rtc */ 309