1 /*
2  * Copyright 2021 ~ 2022 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef FSL_VBAT_H_
9 #define FSL_VBAT_H_
10 
11 #include "fsl_common.h"
12 
13 /*!
14  * @addtogroup vbat
15  * @{
16  */
17 
18 /*******************************************************************************
19  * Definitions
20  ******************************************************************************/
21 
22 /*! @name Driver version */
23 /*! @{ */
24 /*! @brief VBAT driver version 2.1.0. */
25 #define FSL_VBAT_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
26 /*! @} */
27 
28 /*!
29  * @brief The enumeration of VBAT module status.
30  */
31 enum
32 {
33     kStatus_VBAT_Fro16kNotEnabled =
34         MAKE_STATUS(kStatusGroup_VBAT, 0), /*!< Internal 16kHz free running oscillator not enabled. */
35     kStatus_VBAT_BandgapNotEnabled = MAKE_STATUS(kStatusGroup_VBAT, 1), /*!< Bandgap not enabled. */
36 };
37 
38 /*!
39  * @brief The enumeration of VBAT status flags.
40  *
41  * @anchor vbat_status_flag_t
42  */
43 enum _vbat_status_flag
44 {
45     kVBAT_StatusFlagPORDetect     = VBAT_STATUSA_POR_DET_MASK,     /*!< VBAT domain has been reset */
46     kVBAT_StatusFlagWakeupPin     = VBAT_STATUSA_WAKEUP_FLAG_MASK, /*!< A falling edge is detected on the wakeup pin. */
47     kVBAT_StatusFlagBandgapTimer0 = VBAT_STATUSA_TIMER0_FLAG_MASK, /*!< Bandgap Timer0 period reached. */
48     kVBAT_StatusFlagBandgapTimer1 = VBAT_STATUSA_TIMER1_FLAG_MASK, /*!< Bandgap Timer1 period reached. */
49     kVBAT_StatusFlagLdoReady      = VBAT_STATUSA_LDO_RDY_MASK,     /*!< LDO is enabled and ready. */
50 };
51 
52 /*!
53  * @brief The enumeration of VBAT interrupt enable.
54  *
55  * @anchor vbat_interrupt_enable_t
56  */
57 enum _vbat_interrupt_enable
58 {
59     kVBAT_InterruptEnablePORDetect = VBAT_IRQENA_POR_DET_MASK,         /*!< Enable POR detect interrupt. */
60     kVBAT_InterruptEnableWakeupPin = VBAT_IRQENA_WAKEUP_FLAG_MASK,     /*!< Enable the interrupt when a falling edge is
61                                                                            detected on the wakeup pin. */
62     kVBAT_InterruptEnableBandgapTimer0 = VBAT_IRQENA_TIMER0_FLAG_MASK, /*!< Enable the interrupt if Bandgap
63                                                                            Timer0 period reached. */
64     kVBAT_InterruptEnableBandgapTimer1 = VBAT_IRQENA_TIMER1_FLAG_MASK, /*!< Enable the interrupt if Bandgap
65                                                                            Timer1 period reached. */
66     kVBAT_InterruptEnableLdoReady = VBAT_IRQENA_LDO_RDY_MASK,          /*!< Enable LDO ready interrupt. */
67 
68     kVBAT_AllInterruptsEnable =
69         (VBAT_IRQENA_POR_DET_MASK | VBAT_IRQENA_WAKEUP_FLAG_MASK | VBAT_IRQENA_TIMER0_FLAG_MASK |
70          VBAT_IRQENA_TIMER1_FLAG_MASK | VBAT_IRQENA_LDO_RDY_MASK), /*!< Enable all interrupts. */
71 };
72 
73 /*!
74  * @brief The enumeration of VBAT wakeup enable.
75  *
76  * @anchor vbat_wakeup_enable_t
77  */
78 enum _vbat_wakeup_enable
79 {
80     kVBAT_WakeupEnablePORDetect = VBAT_WAKENA_POR_DET_MASK,         /*!< Enable POR detect wakeup. */
81     kVBAT_WakeupEnableWakeupPin = VBAT_WAKENA_WAKEUP_FLAG_MASK,     /*!< Enable wakeup feature when a falling edge is
82                                                                         detected on the wakeup pin. */
83     kVBAT_WakeupEnableBandgapTimer0 = VBAT_WAKENA_TIMER0_FLAG_MASK, /*!< Enable wakeup feature when bandgap
84                                                                         timer0 period reached. */
85     kVBAT_WakeupEnableBandgapTimer1 = VBAT_WAKENA_TIMER1_FLAG_MASK, /*!< Enable wakeup feature when bandgap
86                                                                         timer1 period reached. */
87     kVBAT_WakeupEnableLdoReady = VBAT_WAKENA_LDO_RDY_MASK,          /*!< Enable wakeup when LDO ready. */
88 
89     kVBAT_AllWakeupsEnable = (VBAT_WAKENA_POR_DET_MASK | VBAT_WAKENA_WAKEUP_FLAG_MASK | VBAT_WAKENA_TIMER0_FLAG_MASK |
90                               VBAT_WAKENA_TIMER1_FLAG_MASK | VBAT_WAKENA_LDO_RDY_MASK), /*!< Enable all wakeup. */
91 };
92 
93 /*!
94  * @brief The enumeration of bandgap timer id, VBAT support two bandgap timers.
95  *
96  * @anchor vbat_bandgap_timer_id_t
97  */
98 enum _vbat_bandgap_timer_id
99 {
100     kVBAT_BandgapTimer0 = 1U << 0U, /*!< Bandgap Timer0. */
101     kVBAT_BandgapTimer1 = 1U << 1U, /*!< Bandgap Timer1. */
102 };
103 
104 /*!
105  * @brief The enumeration of bandgap refresh period.
106  */
107 typedef enum _vbat_bandgap_refresh_period
108 {
109     kVBAT_BandgapRefresh7P8125ms = 0U, /*!< Bandgap refresh every 7.8125ms. */
110     kVBAT_BandgapRefresh15P625ms = 1U, /*!< Bandgap refresh every 15.625ms. */
111     kVBAT_BandgapRefresh31P25ms  = 2U, /*!< Bandgap refresh every 31.25ms. */
112     kVBAT_BandgapRefresh62P5ms   = 3U, /*!< Bandgap refresh every 62.5ms. */
113 } vbat_bandgap_refresh_period_t;
114 
115 /*!
116  * @brief The enumeration of bandgap timer timeout period.
117  */
118 typedef enum _vbat_bandgap_timer_timeout_period
119 {
120     kVBAT_BangapTimerTimeout1s      = 0U, /*!< Bandgap timer timerout every 1s. */
121     kVBAT_BangapTimerTimeout500ms   = 1U, /*!< Bandgap timer timerout every 500ms. */
122     kVBAT_BangapTimerTimeout250ms   = 2U, /*!< Bandgap timer timerout every 250ms. */
123     kVBAT_BangapTimerTimeout125ms   = 3U, /*!< Bandgap timer timerout every 125ms. */
124     kVBAT_BangapTimerTimeout62P5ms  = 4U, /*!< Bandgap timer timerout every 62.5ms. */
125     kVBAT_BangapTimerTimeout31P25ms = 5U, /*!< Bandgap timer timerout every 31.25ms. */
126 } vbat_bandgap_timer_timeout_period_t;
127 
128 /*!
129  * @brief The structure of internal 16kHz free running oscillator attributes.
130  */
131 typedef struct _vbat_fro16k_config
132 {
133     bool enableFRO16k;       /*!< Enable/disable internal 16kHz free running oscillator. */
134     bool enableFRO16kOutput; /*!< Enable/disable FRO 16k output clock to other modules. */
135 } vbat_fro16k_config_t;
136 /*******************************************************************************
137  * API
138  ******************************************************************************/
139 
140 #if defined(__cplusplus)
141 extern "C" {
142 #endif
143 
144 /*!
145  * @name FRO16K Control Interfaces
146  * @{
147  */
148 
149 /*!
150  * @brief Configure internal 16kHz free running oscillator, including enabel FRO16k, gate FRO16k output.
151  *
152  * @param base VBAT peripheral base address.
153  * @param config Pointer to @ref vbat_fro16k_config_t structure.
154  */
155 void VBAT_ConfigFRO16k(VBAT_Type *base, const vbat_fro16k_config_t *config);
156 
157 /*!
158  * @brief Enable/disable internal 16kHz free running oscillator.
159  *
160  * @param base VBAT peripheral base address.
161  * @param enable Used to enable/disable 16kHz FRO.
162  *          - \b true Enable internal 16kHz free running oscillator.
163  *          - \b false Disable internal 16kHz free running oscillator.
164  */
VBAT_EnableFRO16k(VBAT_Type * base,bool enable)165 static inline void VBAT_EnableFRO16k(VBAT_Type *base, bool enable)
166 {
167     if (enable)
168     {
169         base->FROCTLA |= VBAT_FROCTLA_FRO_EN_MASK;
170     }
171     else
172     {
173         base->FROCTLA &= ~VBAT_FROCTLA_FRO_EN_MASK;
174     }
175 }
176 
177 /*!
178  * @brief Check if internal 16kHz free running oscillator is enabled.
179  *
180  * @param base VBAT peripheral base address.
181  *
182  * @retval true The internal 16kHz Free running oscillator is enabled.
183  * @retval false The internal 16kHz Free running oscillator is enabled.
184  */
VBAT_CheckFRO16kEnabled(VBAT_Type * base)185 static inline bool VBAT_CheckFRO16kEnabled(VBAT_Type *base)
186 {
187     return (bool)((base->FROCTLA & VBAT_FROCTLA_FRO_EN_MASK) == VBAT_FROCTLA_FRO_EN_MASK);
188 }
189 
190 /*!
191  * @brief Ungate/gate FRO 16kHz output clock to other modules.
192  *
193  * @param base VBAT peripheral base address.
194  * @param unGateFRO16k Used to gate/ungate FRO 16kHz output.
195  *              - \b true FRO 16kHz output clock to other modules is enabled.
196  *              - \b false FRO 16kHz output clock to other modules is disabled.
197  */
VBAT_UngateFRO16k(VBAT_Type * base,bool unGateFRO16k)198 static inline void VBAT_UngateFRO16k(VBAT_Type *base, bool unGateFRO16k)
199 {
200     if (unGateFRO16k)
201     {
202         base->FROCLKE |= VBAT_FROCLKE_CLKE_MASK;
203     }
204     else
205     {
206         base->FROCLKE &= ~VBAT_FROCLKE_CLKE_MASK;
207     }
208 }
209 
210 /*!
211  * @brief Lock settings of internal 16kHz free running oscillator, please note that if locked 16kHz FRO's settings can
212  * not be updated until the next POR.
213  *
214  * @note Please note that the operation to ungate/gate FRO 16kHz output clock can not be locked by this function.
215  *
216  * @param base VBAT peripheral base address.
217  */
VBAT_LockFRO16kSettings(VBAT_Type * base)218 static inline void VBAT_LockFRO16kSettings(VBAT_Type *base)
219 {
220     base->FROLCKA |= VBAT_FROLCKA_LOCK_MASK;
221 }
222 
223 /*! @} */
224 
225 /*!
226  * @name RAM_LDO Control Interfaces
227  * @{
228  */
229 
230 /*!
231  * @brief Enable/disable Bandgap.
232  *
233  * @note The FRO16K must be enabled before enabling the bandgap.
234  * @note This setting can be locked by VBAT_LockLdoRamSettings() function.
235  *
236  * @param base VBAT peripheral base address.
237  * @param enable Used to enable/disable bandgap.
238  *      - \b true Enable the bandgap.
239  *      - \b false Disable the bandgap.
240  *
241  * @retval kStatus_Success Success to enable/disable the bandgap.
242  * @retval kStatus_VBAT_Fro16kNotEnabled Fail to enable the bandgap due to FRO16k is not enabled previously.
243  */
244 status_t VBAT_EnableBandgap(VBAT_Type *base, bool enable);
245 
246 /*!
247  * @brief Check if bandgap is enabled.
248  *
249  * @param base VBAT peripheral base address.
250  *
251  * @retval true The bandgap is enabled.
252  * @retval false The bandgap is disabled.
253  */
VBAT_CheckBandgapEnabled(VBAT_Type * base)254 static inline bool VBAT_CheckBandgapEnabled(VBAT_Type *base)
255 {
256     return (bool)((base->LDOCTLA & VBAT_LDOCTLA_BG_EN_MASK) == VBAT_LDOCTLA_BG_EN_MASK);
257 }
258 
259 /*!
260  * @brief Enable/disable bandgap low power refresh mode.
261  *
262  * @note This setting can be locked by VBAT_LockLdoRamSettings() function.
263  *
264  * @param base VBAT peripheral base address.
265  * @param enableRefreshMode Used to enable/disable bandgap low power refresh mode.
266  *          - \b true Enable bandgap low power refresh mode.
267  *          - \b false Disable bandgap low power refresh mode.
268  */
VBAT_EnableBandgapRefreshMode(VBAT_Type * base,bool enableRefreshMode)269 static inline void VBAT_EnableBandgapRefreshMode(VBAT_Type *base, bool enableRefreshMode)
270 {
271     if (enableRefreshMode)
272     {
273         base->LDOCTLA |= VBAT_LDOCTLA_REFRESH_EN_MASK;
274     }
275     else
276     {
277         base->LDOCTLA &= ~VBAT_LDOCTLA_REFRESH_EN_MASK;
278     }
279 }
280 
281 /*!
282  * @brief Enable/disable Backup RAM Regulator(RAM_LDO).
283  *
284  * @note This setting can be locked by VBAT_LockLdoRamSettings() function.
285  *
286  * @param base VBAT peripheral base address.
287  * @param enable Used to enable/disable RAM_LDO.
288  *          - \b true Enable backup SRAM regulator.
289  *          - \b false Disable backup SRAM regulator.
290  *
291  * @retval kStatusSuccess Success to enable/disable backup SRAM regulator.
292  * @retval kStatus_VBAT_Fro16kNotEnabled Fail to enable backup SRAM regulator due to FRO16k is not enabled previously.
293  * @retval kStatus_VBAT_BandgapNotEnabled Fail to enable backup SRAM regulator due to the bandgap is not enabled
294  * previously.
295  */
296 status_t VBAT_EnableBackupSRAMRegulator(VBAT_Type *base, bool enable);
297 
298 /*!
299  * @brief Lock settings of RAM_LDO, please note that if locked then RAM_LDO's settings
300  * can not be updated until the next POR.
301  *
302  * @param base VBAT peripheral base address.
303  */
VBAT_LockLdoRamSettings(VBAT_Type * base)304 static inline void VBAT_LockLdoRamSettings(VBAT_Type *base)
305 {
306     base->LDOLCKA |= VBAT_LDOLCKA_LOCK_MASK;
307 }
308 
309 /*!
310  * @brief Switch the SRAM to be powered by VBAT in software mode.
311  *
312  * @note This function can be used to switch the SRAM to the VBAT retention supply at any time, but please note that the
313  * SRAM must not be accessed during this time and software must manually invoke VBAT_SwitchSRAMPowerBySocSupply() before
314  * accessing the SRAM again.
315  *
316  * @param base VBAT peripheral base address.
317  *
318  * @retval kStatusSuccess Success to Switch SRAM powered by VBAT.
319  * @retval kStatus_VBAT_Fro16kNotEnabled Fail to switch SRAM powered by VBAT due to FRO16K not enabled previously.
320  */
321 status_t VBAT_SwitchSRAMPowerByVBAT(VBAT_Type *base);
322 
323 /*!
324  * @brief Switch the RAM to be powered by Soc Supply in software mode.
325  *
326  * @param base VBAT peripheral base address.
327  */
VBAT_SwitchSRAMPowerBySocSupply(VBAT_Type * base)328 static inline void VBAT_SwitchSRAMPowerBySocSupply(VBAT_Type *base)
329 {
330     base->LDORAMC &= ~VBAT_LDORAMC_SWI_MASK;
331     base->LDORAMC &= ~VBAT_LDORAMC_ISO_MASK;
332 }
333 
334 /*!
335  * @brief Enable/disable SRAM array remains powered from Soc power, when LDO_RAM is disabled.
336  *
337  * @param base VBAT peripheral base address.
338  * @param enable Used to enable/disable SRAM array power retained.
339  *          - \b true SRAM array is retained when powered from VDD_CORE.
340  *          - \b false SRAM array is not retained when powered from VDD_CORE.
341  */
VBAT_EnableSRAMArrayRetained(VBAT_Type * base,bool enable)342 static inline void VBAT_EnableSRAMArrayRetained(VBAT_Type *base, bool enable)
343 {
344     if (enable)
345     {
346         base->LDORAMC &= ~VBAT_LDORAMC_RET_MASK;
347     }
348     else
349     {
350         base->LDORAMC |= VBAT_LDORAMC_RET_MASK;
351     }
352 }
353 
354 /*!
355  * @brief Enable/disable SRAM isolation.
356  *
357  * @param base VBAT peripheral base address.
358  * @param enable Used to enable/disable SRAM violation.
359  *          - \b true SRAM will be isolated.
360  *          - \b false SRAM state follows the SoC power modes.
361  */
VBAT_EnableSRAMIsolation(VBAT_Type * base,bool enable)362 static inline void VBAT_EnableSRAMIsolation(VBAT_Type *base, bool enable)
363 {
364     if (enable)
365     {
366         base->LDORAMC |= VBAT_LDORAMC_ISO_MASK;
367     }
368     else
369     {
370         base->LDORAMC &= ~VBAT_LDORAMC_ISO_MASK;
371     }
372 }
373 
374 /*! @} */
375 
376 /*! @name Bandgap Timer Control Interfaces
377  * @{
378  */
379 
380 /*!
381  * @brief Enable/disable Bandgap timer.
382  *
383  * @note The bandgap timer is available when the bandgap is enabled and are clocked by the FRO16k.
384  *
385  * @param base VBAT peripheral base address.
386  * @param enable Used to enable/disable bandgap timer.
387  * @param timerIdMask The mask of bandgap timer Id, should be the OR'ed value of @ref vbat_bandgap_timer_id_t.
388  *
389  * @retval kStatus_Success Success to enable/disable selected bandgap timer.
390  * @retval kStatus_VBAT_Fro16kNotEnabled Fail to enable/disable selected bandgap timer due to FRO16k not enabled
391  * previously.
392  * @retval kStatus_VBAT_BandgapNotEnabled Fail to enable/disable selected bandgap timer due to bandgap not enabled
393  * previously.
394  */
395 status_t VBAT_EnableBandgapTimer(VBAT_Type *base, bool enable, uint8_t timerIdMask);
396 
397 /*!
398  * @brief Set bandgap timer timeout value.
399  *
400  * @param base VBAT peripheral base address.
401  * @param timeoutPeriod Bandgap timer timeout value, please refer to @ref vbat_bandgap_timer_timeout_period_t.
402  * @param timerIdMask The mask of bandgap timer Id, should be the OR'ed value of @ref vbat_bandgap_timer_id_t.
403  */
404 void VBAT_SetBandgapTimerTimeoutValue(VBAT_Type *base,
405                                       vbat_bandgap_timer_timeout_period_t timeoutPeriod,
406                                       uint8_t timerIdMask);
407 
408 /*! @} */
409 
410 /*! @name Status, Interrupt, Wakeup Control Interfaces
411  * @{
412  */
413 
414 /*!
415  * @brief Get VBAT status flags
416  *
417  * @param base VBAT peripheral base address.
418  * @return The asserted status flags, should be the OR'ed value of @ref vbat_status_flag_t.
419  */
VBAT_GetStatusFlags(VBAT_Type * base)420 static inline uint32_t VBAT_GetStatusFlags(VBAT_Type *base)
421 {
422     return (uint32_t)(base->STATUSA);
423 }
424 
425 /*!
426  * @brief Clear VBAT status flags.
427  *
428  * @param base VBAT peripheral base address.
429  * @param mask The mask of status flags to be cleared, should be the OR'ed value of @ref vbat_status_flag_t except
430  *              @ref kVBAT_StatusFlagLdoReady.
431  */
VBAT_ClearStatusFlags(VBAT_Type * base,uint32_t mask)432 static inline void VBAT_ClearStatusFlags(VBAT_Type *base, uint32_t mask)
433 {
434     base->STATUSA = mask;
435 }
436 
437 /*!
438  * @brief Enable interrupts for the VBAT module, such as POR detect interrupt, Wakeup Pin interrupt and so on.
439  *
440  * @param base VBAT peripheral base address.
441  * @param mask The mask of interrupts to be enabled, should be the OR'ed value of @ref vbat_interrupt_enable_t.
442  */
VBAT_EnableInterrupts(VBAT_Type * base,uint32_t mask)443 static inline void VBAT_EnableInterrupts(VBAT_Type *base, uint32_t mask)
444 {
445     base->IRQENA |= mask;
446 }
447 
448 /*!
449  * @brief Disable interrupts for the VBAT module, such as POR detect interrupt, wakeup pin interrupt and so on.
450  *
451  * @param base VBAT peripheral base address.
452  * @param mask The mask of interrupts to be disabled, should be the OR'ed value of @ref vbat_interrupt_enable_t.
453  */
VBAT_DisableInterrupts(VBAT_Type * base,uint32_t mask)454 static inline void VBAT_DisableInterrupts(VBAT_Type *base, uint32_t mask)
455 {
456     base->IRQENA &= ~mask;
457 }
458 
459 /*!
460  * @brief Enable wakeup for the VBAT module, such as POR detect wakeup, wakeup pin wakeup and so on.
461  *
462  * @param base VBAT peripheral base address.
463  * @param mask The mask of enumerators in @ref vbat_wakeup_enable_t.
464  */
VBAT_EnableWakeup(VBAT_Type * base,uint32_t mask)465 static inline void VBAT_EnableWakeup(VBAT_Type *base, uint32_t mask)
466 {
467     base->WAKENA |= mask;
468 }
469 
470 /*!
471  * @brief Disable wakeup for VBAT module, such as POR detect wakeup, wakeup pin wakeup and so on.
472  *
473  * @param base VBAT peripheral base address.
474  * @param mask The mask of enumerators in @ref vbat_wakeup_enable_t.
475  */
VBAT_DisableWakeup(VBAT_Type * base,uint32_t mask)476 static inline void VBAT_DisableWakeup(VBAT_Type *base, uint32_t mask)
477 {
478     base->WAKENA &= ~mask;
479 }
480 
481 /*!
482  * @brief Lock VBAT interrupt and wakeup settings, please note that if locked the interrupt and wakeup settings can not
483  * be updated until the next POR.
484  *
485  * @param base VBAT peripheral base address.
486  */
VBAT_LockInterruptWakeupSettings(VBAT_Type * base)487 static inline void VBAT_LockInterruptWakeupSettings(VBAT_Type *base)
488 {
489     base->LOCKA |= VBAT_LOCKA_LOCK_MASK;
490 }
491 
492 /*! @} */
493 
494 #if defined(__cplusplus)
495 }
496 #endif
497 
498 /*!
499  * @}
500  */
501 #endif /* FSL_VBAT_H__ */
502