1 /*
2 * Copyright 2021 ~ 2022 NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8 #include "fsl_vbat.h"
9
10 /*******************************************************************************
11 * Definitions
12 ******************************************************************************/
13
14 /* Component ID definition, used by tools. */
15 #ifndef FSL_COMPONENT_ID
16 #define FSL_COMPONENT_ID "platform.drivers.vbat"
17 #endif
18
19 /*******************************************************************************
20 * Prototypes
21 ******************************************************************************/
22
23 /*******************************************************************************
24 * Variables
25 ******************************************************************************/
26
27 /*******************************************************************************
28 * Code
29 ******************************************************************************/
30
31 /*!
32 * brief Configure internal 16kHz free running oscillator, including enabel FRO16k, gate FRO16k output.
33 *
34 * param base VBAT peripheral base address.
35 * param config Pointer to vbat_fro16k_config_t structure.
36 */
VBAT_ConfigFRO16k(VBAT_Type * base,const vbat_fro16k_config_t * config)37 void VBAT_ConfigFRO16k(VBAT_Type *base, const vbat_fro16k_config_t *config)
38 {
39 assert(config != NULL);
40
41 VBAT_EnableFRO16k(base, config->enableFRO16k);
42
43 if (config->enableFRO16k)
44 {
45 VBAT_UngateFRO16k(base, true);
46 }
47 else
48 {
49 VBAT_UngateFRO16k(base, false);
50 }
51 }
52
53 /*!
54 * brief Enable/disable Bandgap.
55 *
56 * note The FRO16K must be enabled before enableing the bandgap.
57 * note This setting can be locked by VBAT_LockLdoRamSettings() function.
58 *
59 * param base VBAT peripheral base address.
60 * param enable Used to enable/disable bandgap.
61 * - \b true Enable the bandgap.
62 * - \b false Disable the bandgap.
63 *
64 * retval kStatus_Success Success to enable/disable the bandgap.
65 * retval kStatus_VBAT_Fro16kNotEnabled Fail to enable the bandgap due to FRO16k is not enabled previously.
66 */
VBAT_EnableBandgap(VBAT_Type * base,bool enable)67 status_t VBAT_EnableBandgap(VBAT_Type *base, bool enable)
68 {
69 status_t status = kStatus_Success;
70
71 if (enable)
72 {
73 if (VBAT_CheckFRO16kEnabled(base))
74 {
75 base->LDOCTLA |= VBAT_LDOCTLA_BG_EN_MASK;
76 }
77 else
78 {
79 /* FRO16K must be enabled before enabling the Bandgap. */
80 status = kStatus_VBAT_Fro16kNotEnabled;
81 }
82 }
83 else
84 {
85 base->LDOCTLA &= ~VBAT_LDOCTLA_BG_EN_MASK;
86 }
87
88 return status;
89 }
90
91 /*!
92 * brief Enable/disable Backup RAM Regulator(RAM_LDO).
93 *
94 * note This setting can be locked by VBAT_LockLdoRamSettings() function.
95 *
96 * param base VBAT peripheral base address.
97 * param enable Used to enable/disable RAM_LDO.
98 * - \b true Enable backup SRAM regulator.
99 * - \b false Disable backup SRAM regulator.
100 *
101 * retval kStatusSuccess Success to enable/disable backup SRAM regulator.
102 * retval kStatus_VBAT_Fro16kNotEnabled Fail to enable backup SRAM regulator due to FRO16k is not enabled previously.
103 * retval kStatus_VBAT_BandgapNotEnabled Fail to enable backup SRAM regulator due to the bandgap is not enabled
104 * previously.
105 */
VBAT_EnableBackupSRAMRegulator(VBAT_Type * base,bool enable)106 status_t VBAT_EnableBackupSRAMRegulator(VBAT_Type *base, bool enable)
107 {
108 status_t status = kStatus_Success;
109
110 if (enable)
111 {
112 if (VBAT_CheckFRO16kEnabled(base))
113 {
114 if (VBAT_CheckBandgapEnabled(base))
115 {
116 base->LDOCTLA |= VBAT_LDOCTLA_LDO_EN_MASK;
117 while ((base->STATUSA & VBAT_STATUSA_LDO_RDY_MASK) == 0UL)
118 {
119 }
120 }
121 else
122 {
123 /* The bandgap must be enabled previously. */
124 status = kStatus_VBAT_BandgapNotEnabled;
125 }
126 }
127 else
128 {
129 /* FRO16k must be enabled previously. */
130 status = kStatus_VBAT_Fro16kNotEnabled;
131 }
132 }
133 else
134 {
135 base->LDOCTLA &= ~VBAT_LDOCTLA_LDO_EN_MASK;
136 }
137
138 return status;
139 }
140
141 /*!
142 * brief Switch the SRAM to be powered by VBAT.
143 *
144 * param base VBAT peripheral base address.
145 *
146 * retval kStatusSuccess Success to Switch SRAM powered by VBAT.
147 * retval kStatus_VBAT_Fro16kNotEnabled Fail to switch SRAM powered by VBAT due to FRO16K not enabled previously.
148 */
VBAT_SwitchSRAMPowerByVBAT(VBAT_Type * base)149 status_t VBAT_SwitchSRAMPowerByVBAT(VBAT_Type *base)
150 {
151 status_t status = kStatus_Success;
152
153 status = VBAT_EnableBandgap(base, true);
154
155 if (status == kStatus_Success)
156 {
157 VBAT_EnableBandgapRefreshMode(base, true);
158 (void)VBAT_EnableBackupSRAMRegulator(base, true);
159
160 /* Isolate the SRAM array */
161 base->LDORAMC |= VBAT_LDORAMC_ISO_MASK;
162 /* Switch the supply to VBAT LDO. */
163 base->LDORAMC |= VBAT_LDORAMC_SWI_MASK;
164 }
165
166 return status;
167 }
168
169 /*!
170 * brief Enable/disable Bandgap timer.
171 *
172 * note The bandgap timer is available when the bandgap is enabled and are clocked by the FRO16k.
173 *
174 * param base VBAT peripheral base address.
175 * param enable Used to enable/disable bandgap timer.
176 * param timerIdMask The mask of bandgap timer Id, should be the OR'ed value of vbat_bandgap_timer_id_t.
177 *
178 * retval kStatus_Success Success to enable/disable selected bandgap timer.
179 * retval kStatus_VBAT_Fro16kNotEnabled Fail to enable/disable selected bandgap timer due to FRO16k not enabled
180 * previously. retval kStatus_VBAT_BandgapNotEnabled Fail to enable/disable selected bandgap timer due to bandgap not
181 * enabled previously.
182 */
VBAT_EnableBandgapTimer(VBAT_Type * base,bool enable,uint8_t timerIdMask)183 status_t VBAT_EnableBandgapTimer(VBAT_Type *base, bool enable, uint8_t timerIdMask)
184 {
185 status_t status = kStatus_Success;
186
187 if (enable)
188 {
189 if (VBAT_CheckFRO16kEnabled(base))
190 {
191 if (VBAT_CheckBandgapEnabled(base))
192 {
193 if ((timerIdMask & (uint8_t)kVBAT_BandgapTimer0) != 0U)
194 {
195 base->LDOTIMER0 |= VBAT_LDOTIMER0_TIMEN_MASK;
196 }
197
198 if ((timerIdMask & (uint8_t)kVBAT_BandgapTimer1) != 0U)
199 {
200 base->LDOTIMER1 |= VBAT_LDOTIMER1_TIMEN_MASK;
201 }
202 }
203 else
204 {
205 /* Bandgap must be enabled previously. */
206 status = kStatus_VBAT_BandgapNotEnabled;
207 }
208 }
209 else
210 {
211 /* FRO16K must be enabled previously. */
212 status = kStatus_VBAT_Fro16kNotEnabled;
213 }
214 }
215 else
216 {
217 if ((timerIdMask & (uint8_t)kVBAT_BandgapTimer0) != 0U)
218 {
219 base->LDOTIMER0 &= ~VBAT_LDOTIMER0_TIMEN_MASK;
220 }
221
222 if ((timerIdMask & (uint8_t)kVBAT_BandgapTimer1) != 0U)
223 {
224 base->LDOTIMER1 &= ~VBAT_LDOTIMER1_TIMEN_MASK;
225 }
226 }
227
228 return status;
229 }
230
231 /*!
232 * brief Set bandgap timer timeout value.
233 *
234 * param base VBAT peripheral base address.
235 * param timeoutPeriod Bandgap timer timeout value, please refer to vbat_bandgap_timer_timeout_period_t.
236 * param timerIdMask The mask of bandgap timer Id, should be the OR'ed value of vbat_bandgap_timer_id_t.
237 */
VBAT_SetBandgapTimerTimeoutValue(VBAT_Type * base,vbat_bandgap_timer_timeout_period_t timeoutPeriod,uint8_t timerIdMask)238 void VBAT_SetBandgapTimerTimeoutValue(VBAT_Type *base,
239 vbat_bandgap_timer_timeout_period_t timeoutPeriod,
240 uint8_t timerIdMask)
241 {
242 bool timerEnabled = false;
243
244 if ((timerIdMask & (uint8_t)kVBAT_BandgapTimer0) != 0U)
245 {
246 timerEnabled = ((base->LDOTIMER0 & VBAT_LDOTIMER0_TIMEN_MASK) != 0UL) ? true : false;
247
248 if (timerEnabled)
249 {
250 base->LDOTIMER0 &= ~VBAT_LDOTIMER0_TIMEN_MASK;
251 }
252
253 base->LDOTIMER0 = ((base->LDOTIMER0 & (~VBAT_LDOTIMER0_TIMCFG_MASK)) | VBAT_LDOTIMER0_TIMCFG(timeoutPeriod));
254
255 if (timerEnabled)
256 {
257 base->LDOTIMER0 |= VBAT_LDOTIMER0_TIMEN_MASK;
258 }
259 }
260
261 if ((timerIdMask & (uint8_t)kVBAT_BandgapTimer1) != 0U)
262 {
263 timerEnabled = ((base->LDOTIMER1 & VBAT_LDOTIMER1_TIMEN_MASK) != 0UL) ? true : false;
264
265 if (timerEnabled)
266 {
267 base->LDOTIMER1 &= ~VBAT_LDOTIMER1_TIMEN_MASK;
268 }
269
270 base->LDOTIMER1 = ((base->LDOTIMER1 & (~VBAT_LDOTIMER1_TIMCFG_MASK)) | VBAT_LDOTIMER1_TIMCFG(timeoutPeriod));
271
272 if (timerEnabled)
273 {
274 base->LDOTIMER1 |= VBAT_LDOTIMER1_TIMEN_MASK;
275 }
276 }
277 }
278