1 /*
2  * Copyright (c) 2015, Freescale Semiconductor, Inc.
3  * Copyright 2016-2017 NXP
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * o Redistributions of source code must retain the above copyright notice, this list
9  *   of conditions and the following disclaimer.
10  *
11  * o Redistributions in binary form must reproduce the above copyright notice, this
12  *   list of conditions and the following disclaimer in the documentation and/or
13  *   other materials provided with the distribution.
14  *
15  * o Neither the name of the copyright holder nor the names of its
16  *   contributors may be used to endorse or promote products derived from this
17  *   software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 #ifndef _FSL_RTC_H_
31 #define _FSL_RTC_H_
32 
33 #include "fsl_common.h"
34 
35 /*!
36  * @addtogroup rtc
37  * @{
38  */
39 
40 
41 /*******************************************************************************
42  * Definitions
43  ******************************************************************************/
44 
45 /*! @name Driver version */
46 /*@{*/
47 #define FSL_RTC_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
48 /*@}*/
49 
50 /*! @brief List of RTC interrupts */
51 typedef enum _rtc_interrupt_enable
52 {
53     kRTC_TimeInvalidInterruptEnable = RTC_IER_TIIE_MASK,  /*!< Time invalid interrupt.*/
54     kRTC_TimeOverflowInterruptEnable = RTC_IER_TOIE_MASK, /*!< Time overflow interrupt.*/
55     kRTC_AlarmInterruptEnable = RTC_IER_TAIE_MASK,        /*!< Alarm interrupt.*/
56     kRTC_SecondsInterruptEnable = RTC_IER_TSIE_MASK       /*!< Seconds interrupt.*/
57 } rtc_interrupt_enable_t;
58 
59 /*! @brief List of RTC flags */
60 typedef enum _rtc_status_flags
61 {
62     kRTC_TimeInvalidFlag = RTC_SR_TIF_MASK,  /*!< Time invalid flag */
63     kRTC_TimeOverflowFlag = RTC_SR_TOF_MASK, /*!< Time overflow flag */
64     kRTC_AlarmFlag = RTC_SR_TAF_MASK         /*!< Alarm flag*/
65 } rtc_status_flags_t;
66 
67 #if (defined(FSL_FEATURE_RTC_HAS_OSC_SCXP) && FSL_FEATURE_RTC_HAS_OSC_SCXP)
68 
69 /*! @brief List of RTC Oscillator capacitor load settings */
70 typedef enum _rtc_osc_cap_load
71 {
72     kRTC_Capacitor_2p = RTC_CR_SC2P_MASK,  /*!< 2 pF capacitor load */
73     kRTC_Capacitor_4p = RTC_CR_SC4P_MASK,  /*!< 4 pF capacitor load */
74     kRTC_Capacitor_8p = RTC_CR_SC8P_MASK,  /*!< 8 pF capacitor load */
75     kRTC_Capacitor_16p = RTC_CR_SC16P_MASK /*!< 16 pF capacitor load */
76 } rtc_osc_cap_load_t;
77 
78 #endif /* FSL_FEATURE_SCG_HAS_OSC_SCXP */
79 
80 /*! @brief Structure is used to hold the date and time */
81 typedef struct _rtc_datetime
82 {
83     uint16_t year;  /*!< Range from 1970 to 2099.*/
84     uint8_t month;  /*!< Range from 1 to 12.*/
85     uint8_t day;    /*!< Range from 1 to 31 (depending on month).*/
86     uint8_t hour;   /*!< Range from 0 to 23.*/
87     uint8_t minute; /*!< Range from 0 to 59.*/
88     uint8_t second; /*!< Range from 0 to 59.*/
89 } rtc_datetime_t;
90 
91 /*!
92  * @brief RTC config structure
93  *
94  * This structure holds the configuration settings for the RTC peripheral. To initialize this
95  * structure to reasonable defaults, call the RTC_GetDefaultConfig() function and pass a
96  * pointer to your config structure instance.
97  *
98  * The config struct can be made const so it resides in flash
99  */
100 typedef struct _rtc_config
101 {
102     bool wakeupSelect;             /*!< true: Wakeup pin outputs the 32 KHz clock;
103                                         false:Wakeup pin used to wakeup the chip  */
104     bool updateMode;               /*!< true: Registers can be written even when locked under certain
105                                         conditions, false: No writes allowed when registers are locked */
106     bool supervisorAccess;         /*!< true: Non-supervisor accesses are allowed;
107                                         false: Non-supervisor accesses are not supported */
108     uint32_t compensationInterval; /*!< Compensation interval that is written to the CIR field in RTC TCR Register */
109     uint32_t compensationTime;     /*!< Compensation time that is written to the TCR field in RTC TCR Register */
110 } rtc_config_t;
111 
112 /*******************************************************************************
113  * API
114  ******************************************************************************/
115 
116 #if defined(__cplusplus)
117 extern "C" {
118 #endif
119 
120 /*!
121  * @name Initialization and deinitialization
122  * @{
123  */
124 
125 /*!
126  * @brief Ungates the RTC clock and configures the peripheral for basic operation.
127  *
128  * This function issues a software reset if the timer invalid flag is set.
129  *
130  * @note This API should be called at the beginning of the application using the RTC driver.
131  *
132  * @param base   RTC peripheral base address
133  * @param config Pointer to the user's RTC configuration structure.
134  */
135 void RTC_Init(RTC_Type *base, const rtc_config_t *config);
136 
137 /*!
138  * @brief Stops the timer and gate the RTC clock.
139  *
140  * @param base RTC peripheral base address
141  */
RTC_Deinit(RTC_Type * base)142 static inline void RTC_Deinit(RTC_Type *base)
143 {
144     /* Stop the RTC timer */
145     base->SR &= ~RTC_SR_TCE_MASK;
146 
147 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
148     /* Gate the module clock */
149     CLOCK_DisableClock(kCLOCK_Rtc0);
150 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
151 }
152 
153 /*!
154  * @brief Fills in the RTC config struct with the default settings.
155  *
156  * The default values are as follows.
157  * @code
158  *    config->wakeupSelect = false;
159  *    config->updateMode = false;
160  *    config->supervisorAccess = false;
161  *    config->compensationInterval = 0;
162  *    config->compensationTime = 0;
163  * @endcode
164  * @param config Pointer to the user's RTC configuration structure.
165  */
166 void RTC_GetDefaultConfig(rtc_config_t *config);
167 
168 /*! @}*/
169 
170 /*!
171  * @name Current Time & Alarm
172  * @{
173  */
174 
175 /*!
176  * @brief Sets the RTC date and time according to the given time structure.
177  *
178  * The RTC counter must be stopped prior to calling this function because writes to the RTC
179  * seconds register fail if the RTC counter is running.
180  *
181  * @param base     RTC peripheral base address
182  * @param datetime Pointer to the structure where the date and time details are stored.
183  *
184  * @return kStatus_Success: Success in setting the time and starting the RTC
185  *         kStatus_InvalidArgument: Error because the datetime format is incorrect
186  */
187 status_t RTC_SetDatetime(RTC_Type *base, const rtc_datetime_t *datetime);
188 
189 /*!
190  * @brief Gets the RTC time and stores it in the given time structure.
191  *
192  * @param base     RTC peripheral base address
193  * @param datetime Pointer to the structure where the date and time details are stored.
194  */
195 void RTC_GetDatetime(RTC_Type *base, rtc_datetime_t *datetime);
196 
197 /*!
198  * @brief Sets the RTC alarm time.
199  *
200  * The function checks whether the specified alarm time is greater than the present
201  * time. If not, the function does not set the alarm and returns an error.
202  *
203  * @param base      RTC peripheral base address
204  * @param alarmTime Pointer to the structure where the alarm time is stored.
205  *
206  * @return kStatus_Success: success in setting the RTC alarm
207  *         kStatus_InvalidArgument: Error because the alarm datetime format is incorrect
208  *         kStatus_Fail: Error because the alarm time has already passed
209  */
210 status_t RTC_SetAlarm(RTC_Type *base, const rtc_datetime_t *alarmTime);
211 
212 /*!
213  * @brief Returns the RTC alarm time.
214  *
215  * @param base     RTC peripheral base address
216  * @param datetime Pointer to the structure where the alarm date and time details are stored.
217  */
218 void RTC_GetAlarm(RTC_Type *base, rtc_datetime_t *datetime);
219 
220 /*! @}*/
221 
222 /*!
223  * @name Interrupt Interface
224  * @{
225  */
226 
227 /*!
228  * @brief Enables the selected RTC interrupts.
229  *
230  * @param base RTC peripheral base address
231  * @param mask The interrupts to enable. This is a logical OR of members of the
232  *             enumeration ::rtc_interrupt_enable_t
233  */
RTC_EnableInterrupts(RTC_Type * base,uint32_t mask)234 static inline void RTC_EnableInterrupts(RTC_Type *base, uint32_t mask)
235 {
236     base->IER |= mask;
237 }
238 
239 /*!
240  * @brief Disables the selected RTC interrupts.
241  *
242  * @param base RTC peripheral base address
243  * @param mask The interrupts to enable. This is a logical OR of members of the
244  *             enumeration ::rtc_interrupt_enable_t
245  */
RTC_DisableInterrupts(RTC_Type * base,uint32_t mask)246 static inline void RTC_DisableInterrupts(RTC_Type *base, uint32_t mask)
247 {
248     base->IER &= ~mask;
249 }
250 
251 /*!
252  * @brief Gets the enabled RTC interrupts.
253  *
254  * @param base RTC peripheral base address
255  *
256  * @return The enabled interrupts. This is the logical OR of members of the
257  *         enumeration ::rtc_interrupt_enable_t
258  */
RTC_GetEnabledInterrupts(RTC_Type * base)259 static inline uint32_t RTC_GetEnabledInterrupts(RTC_Type *base)
260 {
261     return (base->IER & (RTC_IER_TIIE_MASK | RTC_IER_TOIE_MASK | RTC_IER_TAIE_MASK | RTC_IER_TSIE_MASK));
262 }
263 
264 /*! @}*/
265 
266 /*!
267  * @name Status Interface
268  * @{
269  */
270 
271 /*!
272  * @brief Gets the RTC status flags.
273  *
274  * @param base RTC peripheral base address
275  *
276  * @return The status flags. This is the logical OR of members of the
277  *         enumeration ::rtc_status_flags_t
278  */
RTC_GetStatusFlags(RTC_Type * base)279 static inline uint32_t RTC_GetStatusFlags(RTC_Type *base)
280 {
281     return (base->SR & (RTC_SR_TIF_MASK | RTC_SR_TOF_MASK | RTC_SR_TAF_MASK));
282 }
283 
284 /*!
285  * @brief  Clears the RTC status flags.
286  *
287  * @param base RTC peripheral base address
288  * @param mask The status flags to clear. This is a logical OR of members of the
289  *             enumeration ::rtc_status_flags_t
290  */
291 void RTC_ClearStatusFlags(RTC_Type *base, uint32_t mask);
292 
293 /*! @}*/
294 
295 /*!
296  * @name Timer Start and Stop
297  * @{
298  */
299 
300 /*!
301  * @brief Starts the RTC time counter.
302  *
303  * After calling this function, the timer counter increments once a second provided SR[TOF] or
304  * SR[TIF] are not set.
305  *
306  * @param base RTC peripheral base address
307  */
RTC_StartTimer(RTC_Type * base)308 static inline void RTC_StartTimer(RTC_Type *base)
309 {
310     base->SR |= RTC_SR_TCE_MASK;
311 }
312 
313 /*!
314  * @brief Stops the RTC time counter.
315  *
316  * RTC's seconds register can be written to only when the timer is stopped.
317  *
318  * @param base RTC peripheral base address
319  */
RTC_StopTimer(RTC_Type * base)320 static inline void RTC_StopTimer(RTC_Type *base)
321 {
322     base->SR &= ~RTC_SR_TCE_MASK;
323 }
324 
325 /*! @}*/
326 
327 #if (defined(FSL_FEATURE_RTC_HAS_OSC_SCXP) && FSL_FEATURE_RTC_HAS_OSC_SCXP)
328 
329 /*!
330  * @brief This function sets the specified capacitor configuration for the RTC oscillator.
331  *
332  * @param base    RTC peripheral base address
333  * @param capLoad Oscillator loads to enable. This is a logical OR of members of the
334  *                enumeration ::rtc_osc_cap_load_t
335  */
RTC_SetOscCapLoad(RTC_Type * base,uint32_t capLoad)336 static inline void RTC_SetOscCapLoad(RTC_Type *base, uint32_t capLoad)
337 {
338     uint32_t reg = base->CR;
339 
340     reg &= ~(RTC_CR_SC2P_MASK | RTC_CR_SC4P_MASK | RTC_CR_SC8P_MASK | RTC_CR_SC16P_MASK);
341     reg |= capLoad;
342 
343     base->CR = reg;
344 }
345 
346 #endif /* FSL_FEATURE_SCG_HAS_OSC_SCXP */
347 
348 /*!
349  * @brief Performs a software reset on the RTC module.
350  *
351  * This resets all RTC registers except for the SWR bit and the RTC_WAR and RTC_RAR
352  * registers. The SWR bit is cleared by software explicitly clearing it.
353  *
354  * @param base RTC peripheral base address
355  */
RTC_Reset(RTC_Type * base)356 static inline void RTC_Reset(RTC_Type *base)
357 {
358     base->CR |= RTC_CR_SWR_MASK;
359     base->CR &= ~RTC_CR_SWR_MASK;
360 
361     /* Set TSR register to 0x1 to avoid the timer invalid (TIF) bit being set in the SR register */
362     base->TSR = 1U;
363 }
364 
365 #if defined(FSL_FEATURE_RTC_HAS_MONOTONIC) && (FSL_FEATURE_RTC_HAS_MONOTONIC)
366 
367 /*!
368  * @name Monotonic counter functions
369  * @{
370  */
371 
372 /*!
373  * @brief Reads the values of the Monotonic Counter High and Monotonic Counter Low and returns
374  *        them as a single value.
375  *
376  * @param base    RTC peripheral base address
377  * @param counter Pointer to variable where the value is stored.
378  */
379 void RTC_GetMonotonicCounter(RTC_Type *base, uint64_t *counter);
380 
381 /*!
382  * @brief Writes values Monotonic Counter High and Monotonic Counter Low by decomposing
383  *        the given single value.
384  *
385  * @param base    RTC peripheral base address
386  * @param counter Counter value
387  */
388 void RTC_SetMonotonicCounter(RTC_Type *base, uint64_t counter);
389 
390 /*!
391  * @brief Increments the Monotonic Counter by one.
392  *
393  * Increments the Monotonic Counter (registers RTC_MCLR and RTC_MCHR accordingly) by setting
394  * the monotonic counter enable (MER[MCE]) and then writing to the RTC_MCLR register. A write to the
395  * monotonic counter low that causes it to overflow also increments the monotonic counter high.
396  *
397  * @param base RTC peripheral base address
398  *
399  * @return kStatus_Success: success
400  *         kStatus_Fail: error occurred, either time invalid or monotonic overflow flag was found
401  */
402 status_t RTC_IncrementMonotonicCounter(RTC_Type *base);
403 
404 /*! @}*/
405 
406 #endif /* FSL_FEATURE_RTC_HAS_MONOTONIC */
407 
408 #if defined(__cplusplus)
409 }
410 #endif
411 
412 /*! @}*/
413 
414 #endif /* _FSL_RTC_H_ */
415