1 /*
2 * Copyright (c) 2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2018, 2020 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.0.4. */
25 #define FSL_POWER_DRIVER_VERSION (MAKE_VERSION(2, 0, 4))
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 typedef enum pd_bits
35 {
36 kPDRUNCFG_PD_IRC_OUT = SYSCON_PDRUNCFG_IRCOUT_PD_MASK,
37 kPDRUNCFG_PD_IRC = SYSCON_PDRUNCFG_IRC_PD_MASK,
38 kPDRUNCFG_PD_FLASH = SYSCON_PDRUNCFG_FLASH_PD_MASK,
39 kPDRUNCFG_PD_BOD = SYSCON_PDRUNCFG_BOD_PD_MASK,
40 kPDRUNCFG_PD_SYSOSC = SYSCON_PDRUNCFG_SYSOSC_PD_MASK,
41 kPDRUNCFG_PD_WDT_OSC = SYSCON_PDRUNCFG_WDTOSC_PD_MASK,
42 kPDRUNCFG_PD_SYSPLL = SYSCON_PDRUNCFG_SYSPLL_PD_MASK,
43 kPDRUNCFG_PD_ACMP = SYSCON_PDRUNCFG_ACMP_MASK,
44
45 /*
46 This enum member has no practical meaning,it is used to avoid MISRA issue,
47 user should not trying to use it.
48 */
49 kPDRUNCFG_ForceUnsigned = (int)0x80000000U,
50 } pd_bit_t;
51
52 /*! @brief Deep sleep and power down mode wake up configurations */
53 enum _power_wakeup
54 {
55 kPDAWAKECFG_Wakeup_IRC_OUT = SYSCON_PDAWAKECFG_IRCOUT_PD_MASK,
56 kPDAWAKECFG_Wakeup_IRC = SYSCON_PDAWAKECFG_IRC_PD_MASK,
57 kPDAWAKECFG_Wakeup_FLASH = SYSCON_PDAWAKECFG_FLASH_PD_MASK,
58 kPDAWAKECFG_Wakeup_BOD = SYSCON_PDAWAKECFG_BOD_PD_MASK,
59 kPDAWAKECFG_Wakeup_SYSOSC = SYSCON_PDAWAKECFG_SYSOSC_PD_MASK,
60 kPDAWAKECFG_Wakeup_WDT_OSC = SYSCON_PDAWAKECFG_WDTOSC_PD_MASK,
61 kPDAWAKECFG_Wakeup_SYSPLL = SYSCON_PDAWAKECFG_SYSPLL_PD_MASK,
62 kPDAWAKECFG_Wakeup_ACMP = SYSCON_PDAWAKECFG_ACMP_MASK,
63 };
64
65 /*! @brief Deep sleep/power down mode active part */
66 enum _power_deep_sleep_active
67 {
68 kPDSLEEPCFG_DeepSleepBODActive = SYSCON_PDSLEEPCFG_BOD_PD_MASK,
69 kPDSLEEPCFG_DeepSleepWDTOscActive = SYSCON_PDSLEEPCFG_WDTOSC_PD_MASK,
70 };
71
72 /*! @brief pmu general purpose register index */
73 typedef enum _power_gen_reg
74 {
75 kPmu_GenReg0 = 0U, /*!< general purpose register0 */
76 kPmu_GenReg1 = 1U, /*!< general purpose register1 */
77 kPmu_GenReg2 = 2U, /*!< general purpose register2 */
78 kPmu_GenReg3 = 3U, /*!< general purpose register3 */
79 kPmu_GenReg4 = 4U, /*!< DPDCTRL bit 31-4 */
80 } power_gen_reg_t;
81
82 /* Power mode configuration API parameter */
83 typedef enum _power_mode_config
84 {
85 kPmu_Sleep = 0U,
86 kPmu_Deep_Sleep = 1U,
87 kPmu_PowerDown = 2U,
88 kPmu_Deep_PowerDown = 3U,
89 } power_mode_cfg_t;
90
91 /*******************************************************************************
92 * API
93 ******************************************************************************/
94
95 #ifdef __cplusplus
96 extern "C" {
97 #endif
98
99 /*!
100 * @name SYSCON Power Configuration
101 * @{
102 */
103
104 /*!
105 * @brief API to enable PDRUNCFG bit in the Syscon. Note that enabling the bit powers down the peripheral
106 *
107 * @param en peripheral for which to enable the PDRUNCFG bit
108 * @return none
109 */
POWER_EnablePD(pd_bit_t en)110 static inline void POWER_EnablePD(pd_bit_t en)
111 {
112 SYSCON->PDRUNCFG |= (uint32_t)en;
113 }
114
115 /*!
116 * @brief API to disable PDRUNCFG bit in the Syscon. Note that disabling the bit powers up the peripheral
117 *
118 * @param en peripheral for which to disable the PDRUNCFG bit
119 * @return none
120 */
POWER_DisablePD(pd_bit_t en)121 static inline void POWER_DisablePD(pd_bit_t en)
122 {
123 SYSCON->PDRUNCFG &= ~(uint32_t)en;
124 }
125
126 /*!
127 * @brief API to config wakeup configurations for deep sleep mode and power down mode.
128 *
129 * @param mask: wake up configurations for deep sleep mode and power down mode, reference _power_wakeup.
130 * @param powerDown: true is power down the mask part, false is powered part.
131 */
POWER_WakeUpConfig(uint32_t mask,bool powerDown)132 static inline void POWER_WakeUpConfig(uint32_t mask, bool powerDown)
133 {
134 if (powerDown)
135 {
136 SYSCON->PDAWAKECFG |= mask;
137 }
138 else
139 {
140 SYSCON->PDAWAKECFG &= ~mask;
141 }
142 }
143
144 /*!
145 * @brief API to config active part for deep sleep mode and power down mode.
146 *
147 * @param mask: active part configurations for deep sleep mode and power down mode, reference _power_deep_sleep_active.
148 * @param powerDown: true is power down the mask part, false is powered part.
149 */
POWER_DeepSleepConfig(uint32_t mask,bool powerDown)150 static inline void POWER_DeepSleepConfig(uint32_t mask, bool powerDown)
151 {
152 if (powerDown)
153 {
154 SYSCON->PDSLEEPCFG |= mask;
155 }
156 else
157 {
158 SYSCON->PDSLEEPCFG &= ~mask;
159 }
160 }
161
162 /* @} */
163
164 /*!
165 * @name ARM core Power Configuration
166 * @{
167 */
168
169 /*!
170 * @brief API to enable deep sleep bit in the ARM Core.
171 *
172 * @return none
173 */
POWER_EnableDeepSleep(void)174 static inline void POWER_EnableDeepSleep(void)
175 {
176 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
177 }
178
179 /*!
180 * @brief API to disable deep sleep bit in the ARM Core.
181 *
182 * @return none
183 */
POWER_DisableDeepSleep(void)184 static inline void POWER_DisableDeepSleep(void)
185 {
186 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
187 }
188
189 /* @} */
190
191 /*!
192 * @name PMU functionality
193 * @{
194 */
195
196 /*!
197 * @brief API to enter sleep power mode.
198 *
199 * @return none
200 */
201 void POWER_EnterSleep(void);
202
203 /*!
204 * @brief API to enter deep sleep power mode.
205 *
206 * @param activePart: should be a single or combine value of _power_deep_sleep_active .
207 * @return none
208 */
209 void POWER_EnterDeepSleep(uint32_t activePart);
210
211 /*!
212 * @brief API to enter power down mode.
213 *
214 * @param activePart: should be a single or combine value of _power_deep_sleep_active .
215 * @return none
216 */
217 void POWER_EnterPowerDown(uint32_t activePart);
218
219 /*!
220 * @brief API to enter deep power down mode.
221 *
222 * @return none
223 */
224 void POWER_EnterDeepPowerDownMode(void);
225
226 /*!
227 * @brief API to get sleep mode flag.
228 *
229 * @return sleep mode flag: 0 is active mode, 1 is sleep mode entered.
230 */
POWER_GetSleepModeFlag(void)231 static inline uint32_t POWER_GetSleepModeFlag(void)
232 {
233 return (PMU->PCON & PMU_PCON_SLEEPFLAG_MASK) >> PMU_PCON_SLEEPFLAG_SHIFT;
234 }
235
236 /*!
237 * @brief API to clear sleep mode flag.
238 *
239 */
POWER_ClrSleepModeFlag(void)240 static inline void POWER_ClrSleepModeFlag(void)
241 {
242 PMU->PCON |= PMU_PCON_SLEEPFLAG_MASK;
243 }
244
245 /*!
246 * @brief API to get deep power down mode flag.
247 *
248 * @return sleep mode flag: 0 not deep power down, 1 is deep power down mode entered.
249 */
POWER_GetDeepPowerDownModeFlag(void)250 static inline uint32_t POWER_GetDeepPowerDownModeFlag(void)
251 {
252 return (PMU->PCON & PMU_PCON_DPDFLAG_MASK) >> PMU_PCON_DPDFLAG_SHIFT;
253 }
254
255 /*!
256 * @brief API to clear deep power down mode flag.
257 *
258 */
POWER_ClrDeepPowerDownModeFlag(void)259 static inline void POWER_ClrDeepPowerDownModeFlag(void)
260 {
261 PMU->PCON |= PMU_PCON_DPDFLAG_MASK;
262 }
263
264 /*!
265 * @brief API to enable non deep power down mode.
266 *
267 * @param enable: true is enable non deep power down, otherwise disable.
268 */
POWER_EnableNonDpd(bool enable)269 static inline void POWER_EnableNonDpd(bool enable)
270 {
271 if (enable)
272 {
273 PMU->PCON |= PMU_PCON_NODPD_MASK;
274 }
275 else
276 {
277 PMU->PCON &= ~PMU_PCON_NODPD_MASK;
278 }
279 }
280
281 /*!
282 * @brief API to enable LPO.
283 *
284 * @param enable: true to enable LPO, false to disable LPO.
285 */
POWER_EnableLPO(bool enable)286 static inline void POWER_EnableLPO(bool enable)
287 {
288 if (enable)
289 {
290 PMU->DPDCTRL |= PMU_DPDCTRL_LPOSCEN_MASK;
291 }
292 else
293 {
294 PMU->DPDCTRL &= ~PMU_DPDCTRL_LPOSCEN_MASK;
295 }
296 }
297
298 /*!
299 * @brief API to enable LPO in deep power down mode.
300 *
301 * @param enable: true to enable LPO, false to disable LPO.
302 */
POWER_EnableLPOInDeepPowerDownMode(bool enable)303 static inline void POWER_EnableLPOInDeepPowerDownMode(bool enable)
304 {
305 if (enable)
306 {
307 PMU->DPDCTRL |= PMU_DPDCTRL_LPOSCDPDEN_MASK;
308 }
309 else
310 {
311 PMU->DPDCTRL &= ~PMU_DPDCTRL_LPOSCDPDEN_MASK;
312 }
313 }
314
315 /*!
316 * @brief API to retore data to general purpose register which can be retain during deep power down mode.
317 * Note the kPMU_GenReg4 can retore 3 byte data only, so the general purpose register can store 19bytes data.
318 * @param index: general purpose data register index.
319 * @param data: data to restore.
320 */
POWER_SetRetainData(power_gen_reg_t index,uint32_t data)321 static inline void POWER_SetRetainData(power_gen_reg_t index, uint32_t data)
322 {
323 if (index <= kPmu_GenReg3)
324 {
325 PMU->GPREG[index] = data;
326 }
327 else
328 {
329 /* only 28 bits can store in GPDATA field */
330 PMU->DPDCTRL = (PMU->DPDCTRL & (~PMU_DPDCTRL_GPDATA_MASK)) | PMU_DPDCTRL_GPDATA(data);
331 }
332 }
333
334 /*!
335 * @brief API to get data from general purpose register which retain during deep power down mode.
336 * Note the kPMU_GenReg4 can retore 3 byte data only, so the general purpose register can store 19bytes data.
337 * @param index: general purpose data register index.
338 * @return data stored in the general purpose register.
339 */
POWER_GetRetainData(power_gen_reg_t index)340 static inline uint32_t POWER_GetRetainData(power_gen_reg_t index)
341 {
342 if (index == kPmu_GenReg4)
343 {
344 return (PMU->DPDCTRL & PMU_DPDCTRL_GPDATA_MASK) >> PMU_DPDCTRL_GPDATA_SHIFT;
345 }
346
347 return PMU->GPREG[index];
348 }
349
350 /*!
351 * @brief API to enable wake up pin for deep power down mode.
352 *
353 * @param enable: true is enable, otherwise disable.
354 * @param enHysteresis: true is enable Hysteresis for the pin, otherwise disable.
355 */
POWER_EnableWakeupPinForDeepPowerDown(bool enable,bool enHysteresis)356 static inline void POWER_EnableWakeupPinForDeepPowerDown(bool enable, bool enHysteresis)
357 {
358 PMU->DPDCTRL = (PMU->DPDCTRL & (~(PMU_DPDCTRL_WAKEUPHYS_MASK | PMU_DPDCTRL_WAKEPAD_DISABLE_MASK))) |
359 PMU_DPDCTRL_WAKEPAD_DISABLE(!enable) | PMU_DPDCTRL_WAKEUPHYS(enHysteresis);
360 }
361
362 /* @} */
363
364 #ifdef __cplusplus
365 }
366 #endif
367
368 /*!
369 * @}
370 */
371
372 #endif /* _FSL_POWER_H_ */
373