1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2018, 2020-2021 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8 #ifndef _FSL_POWER_H_
9 #define _FSL_POWER_H_
10
11 #include "fsl_common.h"
12
13 /*******************************************************************************
14 * Definitions
15 ******************************************************************************/
16
17 /*!
18 * @addtogroup power
19 * @{
20 */
21
22 /*! @name Driver version */
23 /*@{*/
24 /*! @brief power driver version 2.1.0. */
25 #define FSL_POWER_DRIVER_VERSION (MAKE_VERSION(2, 1, 0))
26 /*@}*/
27
28 /*! @brief PMU PCON reserved mask, used to clear reserved field which should not write 1*/
29 #define PMUC_PCON_RESERVED_MASK ((0xf << 4) | (0x6 << 8) | 0xfffff000u)
30
31 #define POWER_EnbaleLPO POWER_EnableLPO
32 #define POWER_EnbaleLPOInDeepPowerDownMode POWER_EnableLPOInDeepPowerDownMode
33
34 /*! @brief power down configurations mask */
35 typedef enum pd_bits
36 {
37 kPDRUNCFG_PD_FRO_OUT = SYSCON_PDRUNCFG_FROOUT_PD_MASK,
38 kPDRUNCFG_PD_FRO = SYSCON_PDRUNCFG_FRO_PD_MASK,
39 kPDRUNCFG_PD_FLASH = SYSCON_PDRUNCFG_FLASH_PD_MASK,
40 kPDRUNCFG_PD_BOD = SYSCON_PDRUNCFG_BOD_PD_MASK,
41 kPDRUNCFG_PD_ADC0 = SYSCON_PDRUNCFG_ADC_PD_MASK,
42 kPDRUNCFG_PD_SYSOSC = SYSCON_PDRUNCFG_SYSOSC_PD_MASK,
43 kPDRUNCFG_PD_WDT_OSC = SYSCON_PDRUNCFG_WDTOSC_PD_MASK,
44 kPDRUNCFG_PD_SYSPLL = SYSCON_PDRUNCFG_SYSPLL_PD_MASK,
45 kPDRUNCFG_PD_DAC0 = SYSCON_PDRUNCFG_DAC0_MASK,
46 kPDRUNCFG_PD_DAC1 = SYSCON_PDRUNCFG_DAC1_MASK,
47 kPDRUNCFG_PD_ACMP = SYSCON_PDRUNCFG_ACMP_MASK,
48
49 /*
50 This enum member has no practical meaning,it is used to avoid MISRA issue,
51 user should not trying to use it.
52 */
53 kPDRUNCFG_ForceUnsigned = (int)0x80000000U,
54 } pd_bit_t;
55
56 /*! @brief Deep sleep and power down mode wake up configurations */
57 enum _power_wakeup
58 {
59 kPDAWAKECFG_Wakeup_FRO_OUT = SYSCON_PDAWAKECFG_FROOUT_PD_MASK,
60 kPDAWAKECFG_Wakeup_FRO = SYSCON_PDAWAKECFG_FRO_PD_MASK,
61 kPDAWAKECFG_Wakeup_FLASH = SYSCON_PDAWAKECFG_FLASH_PD_MASK,
62 kPDAWAKECFG_Wakeup_BOD = SYSCON_PDAWAKECFG_BOD_PD_MASK,
63 kPDAWAKECFG_Wakeup_ADC = SYSCON_PDAWAKECFG_ADC_PD_MASK,
64 kPDAWAKECFG_Wakeup_SYSOSC = SYSCON_PDAWAKECFG_SYSOSC_PD_MASK,
65 kPDAWAKECFG_Wakeup_WDT_OSC = SYSCON_PDAWAKECFG_WDTOSC_PD_MASK,
66 kPDAWAKECFG_Wakeup_SYSPLL = SYSCON_PDAWAKECFG_SYSPLL_PD_MASK,
67 kPDAWAKECFG_Wakeup_VREFF2 = SYSCON_PDAWAKECFG_VREF2_PD_MASK,
68 kPDAWAKECFG_Wakeup_DAC0 = SYSCON_PDAWAKECFG_DAC0_MASK,
69 kPDAWAKECFG_Wakeup_DAC1 = SYSCON_PDAWAKECFG_DAC1_MASK,
70 kPDAWAKECFG_Wakeup_ACMP = SYSCON_PDAWAKECFG_ACMP_MASK,
71 };
72
73 /*! @brief Deep sleep/power down mode active part */
74 enum _power_deep_sleep_active
75 {
76 kPDSLEEPCFG_DeepSleepBODActive = SYSCON_PDSLEEPCFG_BOD_PD_MASK,
77 kPDSLEEPCFG_DeepSleepWDTOscActive = SYSCON_PDSLEEPCFG_WDTOSC_PD_MASK,
78 };
79
80 /*! @brief pmu general purpose register index */
81 typedef enum _power_gen_reg
82 {
83 kPmu_GenReg0 = 0U, /*!< general purpose register0 */
84 kPmu_GenReg1 = 1U, /*!< general purpose register1 */
85 kPmu_GenReg2 = 2U, /*!< general purpose register2 */
86 kPmu_GenReg3 = 3U, /*!< general purpose register3 */
87 kPmu_GenReg4 = 4U, /*!< DPDCTRL bit 31-8 */
88 } power_gen_reg_t;
89
90 /* Power mode configuration API parameter */
91 typedef enum _power_mode_config
92 {
93 kPmu_Sleep = 0U,
94 kPmu_Deep_Sleep = 1U,
95 kPmu_PowerDown = 2U,
96 kPmu_Deep_PowerDown = 3U,
97 } power_mode_cfg_t;
98
99 /*!
100 * @brief BOD reset level, if VDD below reset level value, the reset will be
101 * asserted.
102 */
103 typedef enum _power_bod_reset_level
104 {
105 kBod_ResetLevelReserved = 0U, /*!< BOD Reset Level reserved. */
106 kBod_ResetLevel1, /*!< BOD Reset Level1: 2.05V */
107 kBod_ResetLevel2, /*!< BOD Reset Level2: 2.35V */
108 kBod_ResetLevel3, /*!< BOD Reset Level3: 2.63V */
109 } power_bod_reset_level_t;
110
111 /*!
112 * @brief BOD interrupt level, if VDD below interrupt level value, the BOD interrupt
113 * will be asserted.
114 */
115 typedef enum _power_bod_interrupt_level
116 {
117 kBod_InterruptLevelReserved = 0U, /*!< BOD interrupt level reserved. */
118 kBod_InterruptLevel1, /*!< BOD interrupt level1: 2.25V. */
119 kBod_InterruptLevel2, /*!< BOD interrupt level2: 2.55V. */
120 kBod_InterruptLevel3, /*!< BOD interrupt level3: 2.84V. */
121 } power_bod_interrupt_level_t;
122
123 /*******************************************************************************
124 * API
125 ******************************************************************************/
126
127 #ifdef __cplusplus
128 extern "C" {
129 #endif
130
131 /*!
132 * @name SYSCON Power Configuration
133 * @{
134 */
135
136 /*!
137 * @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral
138 *
139 * @param en peripheral for which to enable the PDRUNCFG bit
140 * @return none
141 */
POWER_EnablePD(pd_bit_t en)142 static inline void POWER_EnablePD(pd_bit_t en)
143 {
144 SYSCON->PDRUNCFG |= (uint32_t)en;
145 }
146
147 /*!
148 * @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral
149 *
150 * @param en peripheral for which to disable the PDRUNCFG bit
151 * @return none
152 */
POWER_DisablePD(pd_bit_t en)153 static inline void POWER_DisablePD(pd_bit_t en)
154 {
155 SYSCON->PDRUNCFG &= ~(uint32_t)en;
156 }
157
158 /*!
159 * @brief API to config wakeup configurations for deep sleep mode and power down mode.
160 *
161 * @param mask: wake up configurations for deep sleep mode and power down mode, reference _power_wakeup.
162 * @param powerDown: true is power down the mask part, false is powered part.
163 */
POWER_WakeUpConfig(uint32_t mask,bool powerDown)164 static inline void POWER_WakeUpConfig(uint32_t mask, bool powerDown)
165 {
166 if (powerDown)
167 {
168 SYSCON->PDAWAKECFG |= mask;
169 }
170 else
171 {
172 SYSCON->PDAWAKECFG &= ~mask;
173 }
174 }
175
176 /*!
177 * @brief API to config active part for deep sleep mode and power down mode.
178 *
179 * @param mask: active part configurations for deep sleep mode and power down mode, reference _power_deep_sleep_active.
180 * @param powerDown: true is power down the mask part, false is powered part.
181 */
POWER_DeepSleepConfig(uint32_t mask,bool powerDown)182 static inline void POWER_DeepSleepConfig(uint32_t mask, bool powerDown)
183 {
184 if (powerDown)
185 {
186 SYSCON->PDSLEEPCFG |= mask;
187 }
188 else
189 {
190 SYSCON->PDSLEEPCFG &= ~mask;
191 }
192 }
193
194 /* @} */
195
196 /*!
197 * @name ARM core Power Configuration
198 * @{
199 */
200
201 /*!
202 * @brief API to enable deep sleep bit in the ARM Core.
203 *
204 * @return none
205 */
POWER_EnableDeepSleep(void)206 static inline void POWER_EnableDeepSleep(void)
207 {
208 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
209 }
210
211 /*!
212 * @brief API to disable deep sleep bit in the ARM Core.
213 *
214 * @return none
215 */
POWER_DisableDeepSleep(void)216 static inline void POWER_DisableDeepSleep(void)
217 {
218 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
219 }
220
221 /* @} */
222
223 /*!
224 * @name PMU functionality
225 * @{
226 */
227
228 /*!
229 * @brief API to enter sleep power mode.
230 *
231 * @return none
232 */
233 void POWER_EnterSleep(void);
234
235 /*!
236 * @brief API to enter deep sleep power mode.
237 *
238 * @param activePart: should be a single or combine value of _power_deep_sleep_active .
239 * @return none
240 */
241 void POWER_EnterDeepSleep(uint32_t activePart);
242
243 /*!
244 * @brief API to enter power down mode.
245 *
246 * @param activePart: should be a single or combine value of _power_deep_sleep_active .
247 * @return none
248 */
249 void POWER_EnterPowerDown(uint32_t activePart);
250
251 /*!
252 * @brief API to enter deep power down mode.
253 *
254 * @return none
255 */
256 void POWER_EnterDeepPowerDownMode(void);
257
258 /*!
259 * @brief API to get sleep mode flag.
260 *
261 * @return sleep mode flag: 0 is active mode, 1 is sleep mode entered.
262 */
POWER_GetSleepModeFlag(void)263 static inline uint32_t POWER_GetSleepModeFlag(void)
264 {
265 return (PMU->PCON & PMU_PCON_SLEEPFLAG_MASK) >> PMU_PCON_SLEEPFLAG_SHIFT;
266 }
267
268 /*!
269 * @brief API to clear sleep mode flag.
270 *
271 */
POWER_ClrSleepModeFlag(void)272 static inline void POWER_ClrSleepModeFlag(void)
273 {
274 PMU->PCON |= PMU_PCON_SLEEPFLAG_MASK;
275 }
276
277 /*!
278 * @brief API to get deep power down mode flag.
279 *
280 * @return sleep mode flag: 0 not deep power down, 1 is deep power down mode entered.
281 */
POWER_GetDeepPowerDownModeFlag(void)282 static inline uint32_t POWER_GetDeepPowerDownModeFlag(void)
283 {
284 return (PMU->PCON & PMU_PCON_DPDFLAG_MASK) >> PMU_PCON_DPDFLAG_SHIFT;
285 }
286
287 /*!
288 * @brief API to clear deep power down mode flag.
289 *
290 */
POWER_ClrDeepPowerDownModeFlag(void)291 static inline void POWER_ClrDeepPowerDownModeFlag(void)
292 {
293 PMU->PCON |= PMU_PCON_DPDFLAG_MASK;
294 }
295
296 /*!
297 * @brief API to enable non deep power down mode.
298 *
299 * @param enable: true is enable non deep power down, otherwise disable.
300 */
POWER_EnableNonDpd(bool enable)301 static inline void POWER_EnableNonDpd(bool enable)
302 {
303 if (enable)
304 {
305 PMU->PCON |= PMU_PCON_NODPD_MASK;
306 }
307 else
308 {
309 PMU->PCON &= ~PMU_PCON_NODPD_MASK;
310 }
311 }
312
313 /*!
314 * @brief API to enable LPO.
315 *
316 * @param enable: true to enable LPO, false to disable LPO.
317 */
POWER_EnableLPO(bool enable)318 static inline void POWER_EnableLPO(bool enable)
319 {
320 if (enable)
321 {
322 PMU->DPDCTRL |= PMU_DPDCTRL_LPOSCEN_MASK;
323 }
324 else
325 {
326 PMU->DPDCTRL &= ~PMU_DPDCTRL_LPOSCEN_MASK;
327 }
328 }
329
330 /*!
331 * @brief API to enable LPO in deep power down mode.
332 *
333 * @param enable: true to enable LPO, false to disable LPO.
334 */
POWER_EnableLPOInDeepPowerDownMode(bool enable)335 static inline void POWER_EnableLPOInDeepPowerDownMode(bool enable)
336 {
337 if (enable)
338 {
339 PMU->DPDCTRL |= PMU_DPDCTRL_LPOSCDPDEN_MASK;
340 }
341 else
342 {
343 PMU->DPDCTRL &= ~PMU_DPDCTRL_LPOSCDPDEN_MASK;
344 }
345 }
346
347 /*!
348 * @brief API to retore data to general purpose register which can be retain during deep power down mode.
349 * Note the kPMU_GenReg4 can retore 3 byte data only, so the general purpose register can store 19bytes data.
350 * @param index: general purpose data register index.
351 * @param data: data to restore.
352 */
POWER_SetRetainData(power_gen_reg_t index,uint32_t data)353 static inline void POWER_SetRetainData(power_gen_reg_t index, uint32_t data)
354 {
355 if (index <= kPmu_GenReg3)
356 {
357 PMU->GPREG[index] = data;
358 }
359 else
360 {
361 /* only three byte can store in GPDATA field */
362 PMU->DPDCTRL = (PMU->DPDCTRL & (~PMU_DPDCTRL_GPDATA_MASK)) | PMU_DPDCTRL_GPDATA(data);
363 }
364 }
365
366 /*!
367 * @brief API to get data from general purpose register which retain during deep power down mode.
368 * Note the kPMU_GenReg4 can retore 3 byte data only, so the general purpose register can store 19bytes data.
369 * @param index: general purpose data register index.
370 * @return data stored in the general purpose register.
371 */
POWER_GetRetainData(power_gen_reg_t index)372 static inline uint32_t POWER_GetRetainData(power_gen_reg_t index)
373 {
374 if (index == kPmu_GenReg4)
375 {
376 return (PMU->DPDCTRL & PMU_DPDCTRL_GPDATA_MASK) >> PMU_DPDCTRL_GPDATA_SHIFT;
377 }
378
379 return PMU->GPREG[index];
380 }
381
382 /*!
383 * @brief API to enable external clock input for self wake up timer.
384 *
385 * @param enable: true is enable external clock input for self-wake-up timer, otherwise disable.
386 * @param enHysteresis: true is enable Hysteresis for the pin, otherwise disable.
387 */
POWER_EnableWktClkIn(bool enable,bool enHysteresis)388 static inline void POWER_EnableWktClkIn(bool enable, bool enHysteresis)
389 {
390 PMU->DPDCTRL = (PMU->DPDCTRL & (~(PMU_DPDCTRL_WAKEUPCLKHYS_MASK | PMU_DPDCTRL_WAKECLKPAD_DISABLE_MASK))) |
391 PMU_DPDCTRL_WAKECLKPAD_DISABLE(enable) | PMU_DPDCTRL_WAKEUPCLKHYS(enHysteresis);
392 }
393
394 /*!
395 * @brief API to enable wake up pin for deep power down mode.
396 *
397 * @param enable: true is enable, otherwise disable.
398 * @param enHysteresis: true is enable Hysteresis for the pin, otherwise disable.
399 */
POWER_EnableWakeupPinForDeepPowerDown(bool enable,bool enHysteresis)400 static inline void POWER_EnableWakeupPinForDeepPowerDown(bool enable, bool enHysteresis)
401 {
402 PMU->DPDCTRL = (PMU->DPDCTRL & (~(PMU_DPDCTRL_WAKEUPHYS_MASK | PMU_DPDCTRL_WAKEPAD_DISABLE_MASK))) |
403 PMU_DPDCTRL_WAKEPAD_DISABLE(!enable) | PMU_DPDCTRL_WAKEUPHYS(enHysteresis);
404 }
405
406 /*!
407 * @brief API to enable external clock input for self wake up timer.
408 *
409 * @param enable: true is enable , otherwise disable.
410 * @param enHysteresis: true is enable Hysteresis for the pin, otherwise disable.
411 */
POWER_EnableResetPinForDeepPowerDown(bool enable,bool enHysteresis)412 static inline void POWER_EnableResetPinForDeepPowerDown(bool enable, bool enHysteresis)
413 {
414 PMU->DPDCTRL = (PMU->DPDCTRL & (~(PMU_DPDCTRL_RESETHYS_MASK | PMU_DPDCTRL_RESET_DISABLE_MASK))) |
415 PMU_DPDCTRL_RESET_DISABLE(!enable) | PMU_DPDCTRL_RESETHYS(enHysteresis);
416 }
417
418 /*!
419 * @brief Set Bod interrupt level and reset level.
420 *
421 * @param resetLevel BOD reset threshold level, please refer to @ref power_bod_reset_level_t.
422 * @param interruptLevel BOD interrupt threshold level, please refer to @ref power_bod_interrupt_level_t.
423 * @param enable Used to enable/disable the BOD interrupt and BOD reset.
424 */
POWER_SetBodLevel(power_bod_reset_level_t resetLevel,power_bod_interrupt_level_t interruptLevel,bool enable)425 static inline void POWER_SetBodLevel(power_bod_reset_level_t resetLevel,
426 power_bod_interrupt_level_t interruptLevel,
427 bool enable)
428 {
429 SYSCON->BODCTRL = SYSCON_BODCTRL_BODRSTLEV(resetLevel) | SYSCON_BODCTRL_BODINTVAL(interruptLevel) |
430 SYSCON_BODCTRL_BODRSTENA(enable);
431 }
432 /* @} */
433
434 #ifdef __cplusplus
435 }
436 #endif
437
438 /*!
439 * @}
440 */
441
442 #endif /* _FSL_POWER_H_ */
443