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