1 /*
2  * Copyright 2017-2020 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 #ifndef FSL_RTC_H_
8 #define FSL_RTC_H_
9 
10 #include "fsl_common.h"
11 
12 /*!
13  * @addtogroup rtc
14  * @{
15  */
16 
17 /*******************************************************************************
18  * Definitions
19  ******************************************************************************/
20 
21 /*! @name Driver version */
22 /*! @{ */
23 #define FSL_RTC_DRIVER_VERSION (MAKE_VERSION(2, 0, 4)) /*!< Version 2.0.4 */
24 /*! @} */
25 
26 /*! @brief Structure is used to hold the date and time */
27 typedef struct _rtc_datetime
28 {
29     uint16_t year;  /*!< Range from 1970 to 2099.*/
30     uint8_t month;  /*!< Range from 1 to 12.*/
31     uint8_t day;    /*!< Range from 1 to 31 (depending on month).*/
32     uint8_t hour;   /*!< Range from 0 to 23.*/
33     uint8_t minute; /*!< Range from 0 to 59.*/
34     uint8_t second; /*!< Range from 0 to 59.*/
35 } rtc_datetime_t;
36 
37 /*! @brief List of RTC clock source */
38 typedef enum _rtc_clock_source
39 {
40     kRTC_ExternalClock = 0U, /*!< External clock source */
41     kRTC_LPOCLK        = 1U, /*!< Real-time clock source is 1 kHz (LPOCLK) */
42     kRTC_ICSIRCLK      = 2U, /*!< Internal reference clock (ICSIRCLK) */
43     kRTC_BusClock      = 3U, /*!< Bus clock */
44 } rtc_clock_source_t;
45 
46 /*! @brief List of RTC clock prescaler */
47 typedef enum _rtc_clock_prescaler
48 {
49     kRTC_ClockDivide_off     = 0U, /*!< Off */
50     kRTC_ClockDivide_1_128   = 1U, /*!< If RTCLKS = x0, it is 1; if RTCLKS = x1, it is 128 */
51     kRTC_ClockDivide_2_256   = 2U, /*!< If RTCLKS = x0, it is 2; if RTCLKS = x1, it is 256 */
52     kRTC_ClockDivide_4_512   = 3U, /*!< If RTCLKS = x0, it is 4; if RTCLKS = x1, it is 512 */
53     kRTC_ClockDivide_8_1024  = 4U, /*!< If RTCLKS = x0, it is 8; if RTCLKS = x1, it is 1024 */
54     kRTC_ClockDivide_16_2048 = 5U, /*!< If RTCLKS = x0, it is 16; if RTCLKS = x1, it is 2048 */
55     kRTC_ClockDivide_32_100  = 6U, /*!< If RTCLKS = x0, it is 32; if RTCLKS = x1, it is 100 */
56     kRTC_ClockDivide_64_1000 = 7U, /*!< If RTCLKS = x0, it is 64; if RTCLKS = x1, it is 1000 */
57 } rtc_clock_prescaler_t;
58 
59 /*! @brief List of RTC interrupts */
60 typedef enum _rtc_interrupt_enable
61 {
62     kRTC_InterruptEnable = RTC_SC_RTIE_MASK, /*!< Interrupt enable */
63 } rtc_interrupt_enable_t;
64 
65 /*! @brief List of RTC Interrupt flags */
66 typedef enum _RTC_interrupt_flags
67 {
68     kRTC_InterruptFlag = RTC_SC_RTIF_MASK, /*!< Interrupt flag */
69 } rtc_interrupt_flags_t;
70 
71 /*! @brief List of RTC Output */
72 typedef enum _RTC_output_enable
73 {
74     kRTC_OutputEnable = RTC_SC_RTCO_MASK, /*!< Output enable */
75 } rtc_output_enable_t;
76 
77 /*!
78  * @brief RTC config structure
79  *
80  * This structure holds the configuration settings for the RTC peripheral. To initialize this
81  * structure to reasonable defaults, call the RTC_GetDefaultConfig() function and pass a
82  * pointer to your config structure instance.
83  */
84 typedef struct _rtc_config
85 {
86     rtc_clock_source_t clockSource;  /* select RTC clock source */
87     rtc_clock_prescaler_t prescaler; /* select clock prescaler */
88     uint32_t time_us;                /* set entering interrupt time */
89 } rtc_config_t;
90 
91 /*! @brief RTC alarm callback function. */
92 typedef void (*rtc_alarm_callback_t)(void);
93 
94 /*! @} */
95 /*******************************************************************************
96  * API
97  ******************************************************************************/
98 
99 #if defined(__cplusplus)
100 extern "C" {
101 #endif
102 
103 /*!
104  * @addtogroup rtc
105  * @{
106  */
107 
108 /*!
109  * @name Initialization and deinitialization
110  * @{
111  */
112 
113 /*!
114  * @brief Ungates the RTC clock and configures the peripheral for basic operation.
115  *
116  * @note This API should be called at the beginning of the application using the RTC driver.
117  *
118  * @param base   RTC peripheral base address
119  * @param config Pointer to the user's RTC configuration structure.
120  */
121 void RTC_Init(RTC_Type *base, const rtc_config_t *config);
122 
123 /*!
124  * @brief Stops the timer and gate the RTC clock.
125  *
126  * @param base RTC peripheral base address
127  */
128 void RTC_Deinit(RTC_Type *base);
129 
130 /*!
131  * @brief Fills in the RTC config struct with the default settings.
132  *
133  * The default values are as follows.
134  * @code
135  *    config->clockSource = kRTC_BusClock;
136  *    config->prescaler = kRTC_ClockDivide_16_2048;
137  *    config->time_us = 1000000U;
138  * @endcode
139  * @param config Pointer to the user's RTC configuration structure.
140  */
141 void RTC_GetDefaultConfig(rtc_config_t *config);
142 
143 /*! @}*/
144 
145 /*!
146  * @name Current Time & Alarm
147  * @{
148  */
149 
150 /*!
151  * @brief Sets the RTC date and time according to the given time structure.
152  *
153  * @param datetime Pointer to the structure where the date and time details are stored.
154  *
155  * @return kStatus_Success: Success in setting the time and starting the RTC
156  *         kStatus_InvalidArgument: Error because the datetime format is incorrect
157  */
158 status_t RTC_SetDatetime(rtc_datetime_t *datetime);
159 
160 /*!
161  * @brief Gets the RTC time and stores it in the given time structure.
162  *
163  * @param datetime Pointer to the structure where the date and time details are stored.
164  */
165 void RTC_GetDatetime(rtc_datetime_t *datetime);
166 
167 /*!
168  * @brief Sets the RTC alarm time.
169  *
170  * @param second   Second value. User input the number of second.
171  *                 After seconds user input, alarm occurs.
172  */
173 void RTC_SetAlarm(uint32_t second);
174 
175 /*!
176  * @brief Returns the RTC alarm time.
177  *
178  * @param datetime Pointer to the structure where the alarm date and time details are stored.
179  */
180 void RTC_GetAlarm(rtc_datetime_t *datetime);
181 
182 /*!
183  * @brief Set the RTC alarm callback.
184  *
185  * @param callback The callback function.
186  */
187 void RTC_SetAlarmCallback(rtc_alarm_callback_t callback);
188 
189 /*! @}*/
190 
191 /*!
192  * @name Select Source clock
193  * @{
194  */
195 
196 /*!
197  * @brief Select Real-Time Clock Source and Clock Prescaler
198  *
199  * @param base   RTC peripheral base address
200  * @param clock  Select RTC clock source
201  * @param divide Select RTC clock prescaler value
202  */
RTC_SelectSourceClock(RTC_Type * base,rtc_clock_source_t clock,rtc_clock_prescaler_t divide)203 static inline void RTC_SelectSourceClock(RTC_Type *base, rtc_clock_source_t clock, rtc_clock_prescaler_t divide)
204 {
205     base->SC &= ~(RTC_SC_RTCLKS_MASK | RTC_SC_RTCPS_MASK);
206     base->SC |= RTC_SC_RTCLKS(clock) | RTC_SC_RTCPS(divide);
207 }
208 
209 /*!
210  * @brief  Get the RTC Divide value.
211  *
212  * @note This API should be called after selecting clock source and clock prescaler.
213  *
214  * @param base    RTC peripheral base address
215  * @return  The Divider value. The Divider value depends on clock source and clock prescaler
216  */
217 uint32_t RTC_GetDivideValue(RTC_Type *base);
218 
219 /*! @}*/
220 
221 /*!
222  * @name Interrupt Interface
223  * @{
224  */
225 
226 /*!
227  * @brief Enables the selected RTC interrupts.
228  *
229  * @param base    RTC peripheral base address
230  * @param mask    The interrupts to enable. This is a logical OR of members of the
231  *                enumeration ::rtc_interrupt_enable_t
232  */
RTC_EnableInterrupts(RTC_Type * base,uint32_t mask)233 static inline void RTC_EnableInterrupts(RTC_Type *base, uint32_t mask)
234 {
235     base->SC |= mask;
236 }
237 
238 /*!
239  * @brief Disables the selected RTC interrupts.
240  *
241  * @param base    PIT peripheral base address
242  * @param mask    The interrupts to disable. This is a logical OR of members of the
243  *                enumeration ::rtc_interrupt_enable_t
244  */
RTC_DisableInterrupts(RTC_Type * base,uint32_t mask)245 static inline void RTC_DisableInterrupts(RTC_Type *base, uint32_t mask)
246 {
247     base->SC &= ~mask;
248 }
249 
250 /*!
251  * @brief Gets the enabled RTC interrupts.
252  *
253  * @param base    RTC peripheral base address
254  *
255  * @return The enabled interrupts. This is the logical OR of members of the
256  *         enumeration ::rtc_interrupt_enable_t
257  */
RTC_GetEnabledInterrupts(RTC_Type * base)258 static inline uint32_t RTC_GetEnabledInterrupts(RTC_Type *base)
259 {
260     return (base->SC & RTC_SC_RTIE_MASK);
261 }
262 
263 /*!
264  * @brief Gets the RTC interrupt flags.
265  *
266  * @param base    RTC peripheral base address
267  *
268  * @return The interrupt flags. This is the logical OR of members of the
269  *         enumeration ::rtc_interrupt_flags_t
270  */
RTC_GetInterruptFlags(RTC_Type * base)271 static inline uint32_t RTC_GetInterruptFlags(RTC_Type *base)
272 {
273     return (base->SC & RTC_SC_RTIF_MASK);
274 }
275 
276 /*!
277  * @brief  Clears the RTC interrupt flags.
278  *
279  * @param base    RTC peripheral base address
280  * @param mask    The interrupt flags to clear. This is a logical OR of members of the
281  *                enumeration ::rtc_interrupt_flags_t
282  */
RTC_ClearInterruptFlags(RTC_Type * base,uint32_t mask)283 static inline void RTC_ClearInterruptFlags(RTC_Type *base, uint32_t mask)
284 {
285     base->SC |= mask;
286 }
287 
288 /*! @}*/
289 
290 /*!
291  * @name Output Interface
292  * @{
293  */
294 
295 /*!
296  * @brief  Enable the RTC output. If RTC output is enabled, the RTCO pinout will be
297  *         toggled when RTC counter overflows
298  *
299  * @param base    RTC peripheral base address
300  * @param mask    The Output to enable. This is a logical OR of members of the
301  *                enumeration ::rtc_output_enable_t
302  */
RTC_EnableOutput(RTC_Type * base,uint32_t mask)303 static inline void RTC_EnableOutput(RTC_Type *base, uint32_t mask)
304 {
305     base->SC |= mask;
306 }
307 
308 /*!
309  * @brief  Disable the RTC output.
310  *
311  * @param base    RTC peripheral base address
312  * @param mask    The Output to disable. This is a logical OR of members of the
313  *                enumeration ::rtc_output_enable_t
314  */
RTC_DisableOutput(RTC_Type * base,uint32_t mask)315 static inline void RTC_DisableOutput(RTC_Type *base, uint32_t mask)
316 {
317     base->SC &= ~mask;
318 }
319 
320 /*! @}*/
321 
322 /*!
323  * @name Set module value and Get Count value
324  * @{
325  */
326 
327 /*!
328  * @brief  Set the RTC module value.
329  *
330  * @param base    RTC peripheral base address
331  * @param value   The Module Value. The RTC Modulo register allows the compare value
332  *                to be set to any value from 0x0000 to 0xFFFF
333  */
RTC_SetModuloValue(RTC_Type * base,uint32_t value)334 static inline void RTC_SetModuloValue(RTC_Type *base, uint32_t value)
335 {
336     assert(value <= RTC_MOD_MOD_MASK);
337     base->MOD = value;
338 }
339 
340 /*!
341  * @brief  Get the RTC Count value.
342  *
343  * @param base    RTC peripheral base address
344  * @return  The Count Value. The Count Value is allowed from 0x0000 to 0xFFFF
345  */
RTC_GetCountValue(RTC_Type * base)346 static inline uint16_t RTC_GetCountValue(RTC_Type *base)
347 {
348     volatile const uint8_t *addr;
349     addr = (volatile const uint8_t *)(&base->CNT);
350     return (uint16_t)((uint16_t) * (addr) | (uint16_t)((uint16_t) * (addr + 1) << 8U));
351 }
352 
353 /*! @}*/
354 
355 #if defined(__cplusplus)
356 }
357 #endif
358 
359 /*! @}*/
360 
361 #endif /* FSL_RTC_H_ */
362