1 /*
2  * Copyright 2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef FSL_BBNSM_H_
9 #define FSL_BBNSM_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup bbnsm
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 /*! @name Driver version */
23 /*! @{ */
24 #define FSL_BBNSM_DRIVER_VERSION (MAKE_VERSION(2, 0, 0)) /*!< Version 2.0.0 */
25 /*! @} */
26 
27 /*! @brief List of BBNSM interrupts */
28 typedef enum _bbnsm_interrupts
29 {
30     kBBNSM_RTC_AlarmInterrupt    = BBNSM_BBNSM_INT_EN_TA_INT_EN(0x2),  /*!< RTC time alarm interrupt */
31     kBBNSM_RTC_RolloverInterrupt = BBNSM_BBNSM_INT_EN_RTC_INT_EN(0x2), /*!< RTC rollover interrupt */
32 } bbnsm_interrupts_t;
33 
34 /*! @brief List of BBNSM flags */
35 typedef enum _bbnsm_status_flags
36 {
37     kBBNSM_RTC_AlarmInterruptFlag    = BBNSM_BBNSM_EVENTS_TA(0x2),       /*!< RTC time alarm interrupt flag */
38     kBBNSM_RTC_RolloverInterruptFlag = BBNSM_BBNSM_EVENTS_RTC_ROLL(0x2), /*!< RTC rollover interrupt flag */
39     kBBNSM_PWR_ON_InterruptFlag      = BBNSM_BBNSM_EVENTS_PWR_ON(0x1),   /*!< power on interrupt flag */
40     kBBNSM_PWR_OFF_InterruptFlag     = BBNSM_BBNSM_EVENTS_PWR_OFF(0x1),  /*!< power off interrupt flag */
41     kBBNSM_EMG_OFF_InterruptFlag     = BBNSM_BBNSM_EVENTS_EMG_OFF(0x1),  /*!< emergency power off interrupt flag */
42 } bbnsm_status_flags_t;
43 
44 /*!
45  * @brief BBNSM config structure
46  *
47  * This structure holds the configuration settings for the BBNSM peripheral. To initialize this
48  * structure to reasonable defaults, call the BBNSM_RTC_GetDefaultConfig() function and pass a
49  * pointer to your config structure instance.
50  *
51  * The config struct can be made const so it resides in flash
52  */
53 typedef struct _bbnsm_rtc_config
54 {
55     bool rtcCalEnable;    /*!< true: RTC calibration mechanism is enabled;
56                                 false: No calibration is used */
57     uint32_t rtcCalValue; /*!< Defines signed calibration value for RTC;
58                                 This is a 5-bit 2's complement value, range from -16 to +15 */
59 } bbnsm_rtc_config_t;
60 
61 /*******************************************************************************
62  * API
63  ******************************************************************************/
64 
65 #if defined(__cplusplus)
66 extern "C" {
67 #endif
68 
69 /*!
70  * @name Initialization and deinitialization
71  * @{
72  */
73 /*!
74  * @brief Init the BBNSM section.
75  *
76  * @param base BBNSM peripheral base address
77  */
78 void BBNSM_Init(BBNSM_Type *base);
79 
80 /*!
81  * @brief Deinit the BBNSM section.
82  *
83  * @param base BBNSM peripheral base address
84  */
85 void BBNSM_Deinit(BBNSM_Type *base);
86 
87 /*! @}*/
88 
89 /*!
90  * @brief Ungates the BBNSM clock and configures the peripheral for basic operation.
91  *
92  * @note This API should be called at the beginning of the application using the BBNSM driver.
93  *
94  * @param base   BBNSM peripheral base address
95  * @param config Pointer to the user's BBNSM rtc configuration structure.
96  */
97 void BBNSM_RTC_Init(BBNSM_Type *base, const bbnsm_rtc_config_t *config);
98 
99 /*!
100  * @brief Stops the RTC timer.
101  *
102  * @param base BBNSM peripheral base address
103  */
104 void BBNSM_RTC_Deinit(BBNSM_Type *base);
105 
106 /*!
107  * @brief Fills in the BBNSM RTC config struct with the default settings.
108  *
109  * The default values are as follows.
110  * @code
111  *    config->rtccalenable = false;
112  *    config->rtccalvalue = 0U;
113  * @endcode
114  * @param config Pointer to the user's BBNSM configuration structure.
115  */
116 void BBNSM_RTC_GetDefaultConfig(bbnsm_rtc_config_t *config);
117 
118 /*!
119  * @brief Sets the BBNSM RTC alarm time.
120  *
121  * The function sets the RTC alarm. It also checks whether the specified alarm
122  * time is greater than the present time. If not, the function does not set the alarm
123  * and returns an error.
124  * Please note, that RTC alarm has limited resolution because only 32 most
125  * significant bits of RTC counter are compared to RTC Alarm register.
126  * If the alarm time is beyond RTC resolution, the function does not set the alarm
127  * and returns an error.
128  *
129  * @param base      BBNSM peripheral base address
130  * @param alarmSeconds
131  *
132  * @return kStatus_Success: success in setting the BBNSM RTC alarm
133  *         kStatus_InvalidArgument: Error because the alarm datetime format is incorrect
134  *         kStatus_Fail: Error because the alarm time has already passed or is beyond resolution
135  */
136 status_t BBNSM_RTC_SetAlarm(BBNSM_Type *base, uint32_t alarmSeconds);
137 
138 /*!
139  * @brief Returns the BBNSM RTC alarm time.
140  *
141  * @param base     BBNSM peripheral base address
142  */
143 uint32_t BBNSM_RTC_GetAlarm(BBNSM_Type *base);
144 
145 /*! @}*/
146 
147 /*!
148  * @name Interrupt Interface
149  * @{
150  */
151 
152 /*!
153  * @brief Enables the selected BBNSM interrupts.
154  *
155  * @param base BBNSM peripheral base address
156  * @param flags The interrupts to enable. This is a logical OR of members of the
157  *             enumeration :: _bbnsm_interrupts
158  */
BBNSM_EnableInterrupts(BBNSM_Type * base,uint32_t flags)159 static inline void BBNSM_EnableInterrupts(BBNSM_Type *base, uint32_t flags)
160 {
161     uint32_t tmp = base->BBNSM_INT_EN;
162 
163     if ((tmp & BBNSM_BBNSM_INT_EN_TA_INT_EN(1)) != 0U)
164     {
165         tmp &= ~BBNSM_BBNSM_INT_EN_TA_INT_EN(
166             0x3); /* Clear TA_INT_EN field to avoid writing an invliad value(0b00) to the TA_INT_EN field */
167     }
168 
169     if ((tmp & BBNSM_BBNSM_INT_EN_RTC_INT_EN(1)) != 0U)
170     {
171         tmp &= ~BBNSM_BBNSM_INT_EN_RTC_INT_EN(
172             0x3); /* Clear RTC_INT_EN field to avoid writing an invliad value(0b00) to the RTC_INT_EN field */
173     }
174 
175     base->BBNSM_INT_EN = tmp | flags;
176 }
177 
178 /*!
179  * @brief Disables the selected BBNSM interrupts.
180  *
181  * @param base BBNSM peripheral base address
182  * @param flags The interrupts to disable. This is a logical AND of members of the
183  *             enumeration :: _bbnsm_interrupts
184  */
BBNSM_DisableInterrupts(BBNSM_Type * base,uint32_t flags)185 static inline void BBNSM_DisableInterrupts(BBNSM_Type *base, uint32_t flags)
186 {
187     uint32_t tmp = base->BBNSM_INT_EN;
188 
189     if ((tmp & kBBNSM_RTC_AlarmInterrupt) != 0U)
190     {
191         tmp &= ~BBNSM_BBNSM_INT_EN_TA_INT_EN(
192             0x3); /* Clear TA_INT_EN field to avoid writing an invliad value(0b00) to the TA_INT_EN field */
193     }
194 
195     if ((tmp & kBBNSM_RTC_RolloverInterrupt) != 0U)
196     {
197         tmp &= ~BBNSM_BBNSM_INT_EN_RTC_INT_EN(
198             0x3); /* Clear RTC_INT_EN field to avoid writing an invliad value(0b00) to the RTC_INT_EN field */
199     }
200 
201     base->BBNSM_INT_EN = tmp | ~flags;
202 }
203 
204 /*!
205  * @brief Gets the enabled BBNSM interrupts.
206  *
207  * @param base BBNSM peripheral base address
208  *
209  * @return The enabled interrupts.
210  */
211 uint32_t BBNSM_GetEnabledInterrupts(BBNSM_Type *base);
212 
213 /*! @}*/
214 
215 /*!
216  * @name Status Interface
217  * @{
218  */
219 
220 /*!
221  * @brief Gets the BBNSM status flags.
222  *
223  * @param base BBNSM peripheral base address
224  *
225  * @return The status flags.
226  */
227 uint32_t BBNSM_GetStatusFlags(BBNSM_Type *base);
228 
229 /*!
230  * @brief  Clears the BBNSM status flags.
231  *
232  * @param base BBNSM peripheral base address
233  * @param flags The status flags to clear.(W1C)
234  */
BBNSM_ClearStatusFlags(BBNSM_Type * base,uint32_t flags)235 static inline void BBNSM_ClearStatusFlags(BBNSM_Type *base, uint32_t flags)
236 {
237     base->BBNSM_EVENTS = flags;
238 }
239 
240 /*! @}*/
241 
242 /*!
243  * @name Timer Start and Stop
244  * @{
245  */
246 
247 /*!
248  * @brief Starts the BBNSM RTC time counter.
249  *
250  * @param base BBNSM peripheral base address
251  */
BBNSM_RTC_StartTimer(BBNSM_Type * base)252 static inline void BBNSM_RTC_StartTimer(BBNSM_Type *base)
253 {
254     uint32_t tmp = base->BBNSM_CTRL;
255 
256     if ((tmp & BBNSM_BBNSM_CTRL_RTC_EN(0x1)) != 0U)
257     {
258         tmp &=
259             ~BBNSM_BBNSM_CTRL_RTC_EN(0x3); /* Clear the field of RTC_EN to avoid writing 0b11 to the field of RTC_EN */
260     }
261 
262     base->BBNSM_CTRL = tmp | BBNSM_BBNSM_CTRL_RTC_EN(0x2);
263     while ((0U == (base->BBNSM_CTRL & BBNSM_BBNSM_CTRL_RTC_EN(0x2))))
264     {
265     }
266 }
267 
268 /*!
269  * @brief Stops the BBNSM RTC time counter.
270  *
271  * @param base BBNSM peripheral base address
272  */
BBNSM_RTC_StopTimer(BBNSM_Type * base)273 static inline void BBNSM_RTC_StopTimer(BBNSM_Type *base)
274 {
275     uint32_t tmp = base->BBNSM_CTRL;
276 
277     if ((tmp & BBNSM_BBNSM_CTRL_RTC_EN(0x2)) != 0U)
278     {
279         tmp &= ~BBNSM_BBNSM_CTRL_RTC_EN(
280             0x3); /* Clear RTC_EN field to avoid writing invalid value(0b11) to the RTC_EN field */
281     }
282 
283     base->BBNSM_CTRL = tmp | BBNSM_BBNSM_CTRL_RTC_EN(0x1);
284     while ((base->BBNSM_CTRL & (BBNSM_BBNSM_CTRL_RTC_EN(0x1))) == 0U)
285     {
286     }
287 }
288 
289 /*!
290  * @brief Sets the BBNSM RTC time counter.
291  *
292  * @param base BBNSM peripheral base address
293  * @param seconds RTC time in seconds
294  */
295 
296 void BBNSM_RTC_SetSeconds(BBNSM_Type *base, uint32_t seconds);
297 
298 /*!
299  * @brief Returns RTC time in seconds.
300  *
301  * This function is used internally to get actual RTC time in seconds.
302  *
303  * @param base BBNSM peripheral base address
304  *
305  * @return RTC time in seconds
306  */
307 uint32_t BBNSM_RTC_GetSeconds(BBNSM_Type *base);
308 
309 #if defined(__cplusplus)
310 }
311 #endif
312 
313 #endif /* FSL_BBNSM_H_ */
314