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