1 /*
2  * @brief LPC15xx PMU chip driver
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2014
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products.  This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights.  NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers.  This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #ifndef __PMU_15XX_H_
33 #define __PMU_15XX_H_
34 
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38 
39 /** @defgroup PMU_15XX CHIP: LPC15xx PMU driver
40  * @ingroup CHIP_15XX_Drivers
41  * @{
42  */
43 
44 /**
45  * @brief LPC15xx Power Management Unit register block structure
46  */
47 typedef struct {
48 	__IO uint32_t PCON;		/*!< Offset: 0x000 Power control Register (R/W) */
49 	__IO uint32_t GPREG[5];	/*!< Offset: 0x004 General purpose Registers 0..4 (R/W) */
50 } LPC_PMU_T;
51 
52 /**
53  * @brief LPC15xx low power mode type definitions
54  */
55 typedef enum CHIP_PMU_MCUPOWER {
56 	PMU_MCU_SLEEP = 0,		/*!< Sleep mode */
57 	PMU_MCU_DEEP_SLEEP,		/*!< Deep Sleep mode */
58 	PMU_MCU_POWER_DOWN,		/*!< Power down mode */
59 	PMU_MCU_DEEP_PWRDOWN	/*!< Deep power down mode */
60 } CHIP_PMU_MCUPOWER_T;
61 
62 /**
63  * PMU PCON register bit fields & masks
64  */
65 #define PMU_PCON_PM_DEEPPOWERDOWN       (0x1)			/*!< ARM WFI enter Deep Power-down mode */
66 #define PMU_PCON_NODPD              (1 << 3)	/*!< Disable deep power-down mode */
67 #define PMU_PCON_SLEEPFLAG          (1 << 8)	/*!< Sleep mode flag */
68 #define PMU_PCON_DPDFLAG            (1 << 11)	/*!< Deep power-down flag */
69 
70 /**
71  * PMU GPREG[4] register bit fields & masks
72  */
73 #define PMU_GPREG4_WAKEUPHYS       (1 << 0)	/** Enable wake-up pin hysteresis */
74 #define PMU_GPREG4_WAKEPAD_DISABLE  (1 << 1)	/** Disable the Wake-up */
75 #define PMU_GPREG4_DATA             ((uint32_t) 0x3fffff << 10)	/** GP register 4 data field */
76 
77 /**
78  * @brief	Write a value to a GPREG register
79  * @param	pPMU		: Pointer to PMU register block
80  * @param	regIndex	: Register index to write to, must be 0..3
81  * @param	value		: Value to write
82  * @return	None
83  */
Chip_PMU_WriteGPREG(LPC_PMU_T * pPMU,uint8_t regIndex,uint32_t value)84 STATIC INLINE void Chip_PMU_WriteGPREG(LPC_PMU_T *pPMU, uint8_t regIndex, uint32_t value)
85 {
86 	pPMU->GPREG[regIndex] = value;
87 }
88 
89 /**
90  * @brief	Write data to GPREG4 register
91  * @param	pPMU		: Pointer to PMU register block
92  * @param	value	: Data to be written to GPREG4
93  * @return	None
94  */
Chip_PMU_WriteGPREG4(LPC_PMU_T * pPMU,uint32_t value)95 STATIC INLINE void Chip_PMU_WriteGPREG4(LPC_PMU_T *pPMU, uint32_t value)
96 {
97 	uint32_t reg;
98 
99 	reg = pPMU->GPREG[4] & ~PMU_GPREG4_DATA;
100 	pPMU->GPREG[4] = reg | (value << 10);
101 }
102 
103 /**
104  * @brief	Read a value to a GPREG register
105  * @param	pPMU		: Pointer to PMU register block
106  * @param	regIndex	: Register index to read from, must be 0..3
107  * @return	Value read from the GPREG register
108  */
Chip_PMU_ReadGPREG(LPC_PMU_T * pPMU,uint8_t regIndex)109 STATIC INLINE uint32_t Chip_PMU_ReadGPREG(LPC_PMU_T *pPMU, uint8_t regIndex)
110 {
111 	return pPMU->GPREG[regIndex];
112 }
113 
114 /**
115  * @brief	Enter MCU Sleep mode
116  * @param	pPMU	: Pointer to PMU register block
117  * @return	None
118  * @note	The sleep mode affects the ARM Cortex-M0+ core only. Peripherals
119  * and memories are active.
120  */
121 void Chip_PMU_SleepState(LPC_PMU_T *pPMU);
122 
123 /**
124  * @brief	Enter MCU Deep Sleep mode
125  * @param	pPMU	: Pointer to PMU register block
126  * @return	None
127  * @note	In Deep-sleep mode, the peripherals receive no internal clocks.
128  * The flash is in stand-by mode. The SRAM memory and all peripheral registers
129  * as well as the processor maintain their internal states. The WWDT, WKT,
130  * and BOD can remain active to wake up the system on an interrupt.
131  */
132 void Chip_PMU_DeepSleepState(LPC_PMU_T *pPMU);
133 
134 /**
135  * @brief	Enter MCU Power down mode
136  * @param	pPMU	: Pointer to PMU register block
137  * @return	None
138  * @note	In Power-down mode, the peripherals receive no internal clocks.
139  * The internal SRAM memory and all peripheral registers as well as the
140  * processor maintain their internal states. The flash memory is powered
141  * down. The WWDT, WKT, and BOD can remain active to wake up the system
142  * on an interrupt.
143  */
144 void Chip_PMU_PowerDownState(LPC_PMU_T *pPMU);
145 
146 /**
147  * @brief	Enter MCU Deep Power down mode
148  * @param	pPMU	: Pointer to PMU register block
149  * @return	None
150  * @note	For maximal power savings, the entire system is shut down
151  * except for the general purpose registers in the PMU and the self
152  * wake-up timer. Only the general purpose registers in the PMU maintain
153  * their internal states. The part can wake up on a pulse on the WAKEUP
154  * pin or when the self wake-up timer times out. On wake-up, the part
155  * reboots.
156  */
157 void Chip_PMU_DeepPowerDownState(LPC_PMU_T *pPMU);
158 
159 /**
160  * @brief	Place the MCU in a low power state
161  * @param	pPMU		: Pointer to PMU register block
162  * @param	SleepMode	: Sleep mode
163  * @return	None
164  */
165 void Chip_PMU_Sleep(LPC_PMU_T *pPMU, CHIP_PMU_MCUPOWER_T SleepMode);
166 
167 /**
168  * @brief	Disables deep power-down mode
169  * @param	pPMU	: Pointer to PMU register block
170  * @return	None
171  * @note	Calling this functions prevents entry to Deep power-down
172  * mode. Once set, this can only be cleared by power-on reset.
173  */
Chip_PMU_DisableDeepPowerDown(LPC_PMU_T * pPMU)174 STATIC INLINE void Chip_PMU_DisableDeepPowerDown(LPC_PMU_T *pPMU)
175 {
176 	pPMU->PCON |= PMU_PCON_NODPD;
177 }
178 
179 /**
180  * @brief	Returns sleep/power-down flags
181  * @param	pPMU	: Pointer to PMU register block
182  * @return	Or'ed values of PMU_PCON_SLEEPFLAG and PMU_PCON_DPDFLAG
183  * @note	These indicate that the PMU is setup for entry into a low
184  * power state on the next WFI() instruction.
185  */
Chip_PMU_GetSleepFlags(LPC_PMU_T * pPMU)186 STATIC INLINE uint32_t Chip_PMU_GetSleepFlags(LPC_PMU_T *pPMU)
187 {
188 	return pPMU->PCON & (PMU_PCON_SLEEPFLAG | PMU_PCON_DPDFLAG);
189 }
190 
191 /**
192  * @brief	Clears sleep/power-down flags
193  * @param	pPMU	: Pointer to PMU register block
194  * @param	flags	: Or'ed value of PMU_PCON_SLEEPFLAG and PMU_PCON_DPDFLAG
195  * @return	Nothing
196  * @note	Use this function to clear a low power state prior to calling
197  * WFI().
198  */
Chip_PMU_ClearSleepFlags(LPC_PMU_T * pPMU,uint32_t flags)199 STATIC INLINE void Chip_PMU_ClearSleepFlags(LPC_PMU_T *pPMU, uint32_t flags)
200 {
201 	pPMU->PCON |= (flags & (PMU_PCON_SLEEPFLAG | PMU_PCON_DPDFLAG));
202 }
203 
204 /**
205  * @brief	Returns Wakeup Hysterisis enable flag
206  * @param	pPMU	: Pointer to PMU register block
207  * @return	TRUE if bit PMU_GPREG4_WAKEUPHYS is set else returns FALSE
208  * @note	This indicate that whether wakeup hysterisis
209  * is enabled or not.
210  */
Chip_PMU_GetWakeHysEnable(LPC_PMU_T * pPMU)211 STATIC INLINE bool Chip_PMU_GetWakeHysEnable(LPC_PMU_T *pPMU)
212 {
213 	return (pPMU->GPREG[4] & PMU_GPREG4_WAKEUPHYS) != 0;
214 }
215 
216 /**
217  * @brief	Sets Wakeup Hysterisis enable flag
218  * @param	pPMU	: Pointer to PMU register block
219  * @return	Nothing
220  * @note	Use this function to prevent enable wakeup hysterisis
221  * note that if Vcc goes below 2.2V then it might prevent wakeup
222  * if hysterisis is enabled
223  */
Chip_PMU_SetWakeHysEnable(LPC_PMU_T * pPMU)224 STATIC INLINE void Chip_PMU_SetWakeHysEnable(LPC_PMU_T *pPMU)
225 {
226 	pPMU->GPREG[4] |= PMU_GPREG4_WAKEUPHYS;
227 }
228 
229 /**
230  * @brief	Clears Wakeup Hysterisis enable flag
231  * @param	pPMU	: Pointer to PMU register block
232  * @return	Nothing
233  * @note	Use this function to disable wakeup hysterisis
234  */
Chip_PMU_ClearWakeHysEnable(LPC_PMU_T * pPMU)235 STATIC INLINE void Chip_PMU_ClearWakeHysEnable(LPC_PMU_T *pPMU)
236 {
237 	pPMU->GPREG[4] &= ~PMU_GPREG4_WAKEUPHYS;
238 }
239 
240 /**
241  * @brief	Returns Wakeup Pad disable bit
242  * @param	pPMU	: Pointer to PMU register block
243  * @return	TRUE if bit PMU_GPREG4_WAKEPAD_DISABLE is set else returns FALSE
244  * @note	This indicate that whether wakeup hysterisis
245  * is enabled or not.
246  */
Chip_PMU_GetWakePadDisable(LPC_PMU_T * pPMU)247 STATIC INLINE bool Chip_PMU_GetWakePadDisable(LPC_PMU_T *pPMU)
248 {
249 	return (pPMU->GPREG[4] & PMU_GPREG4_WAKEPAD_DISABLE) != 0;
250 }
251 
252 /**
253  * @brief	Sets Wakeup pad disable bit
254  * @param	pPMU	: Pointer to PMU register block
255  * @return	Nothing
256  * @note	Use this function to disable the wakeup pin (P0.17)
257  * in which case RTC wakeup is the only option to wakeup from
258  * deep power down mode.
259  */
Chip_PMU_SetWakePadDisable(LPC_PMU_T * pPMU)260 STATIC INLINE void Chip_PMU_SetWakePadDisable(LPC_PMU_T *pPMU)
261 {
262 	pPMU->GPREG[4] |= PMU_GPREG4_WAKEPAD_DISABLE;
263 }
264 
265 /**
266  * @brief	Clears Wakeup pad disable bit
267  * @param	pPMU	: Pointer to PMU register block
268  * @return	Nothing
269  * @note	Use this function to enable the wakeup pin (P0.17)
270  * to wakeup from deep power down mode.
271  */
Chip_PMU_ClearWakePadDisable(LPC_PMU_T * pPMU)272 STATIC INLINE void Chip_PMU_ClearWakePadDisable(LPC_PMU_T *pPMU)
273 {
274 	pPMU->GPREG[4] &= ~PMU_GPREG4_WAKEPAD_DISABLE;
275 }
276 
277 /**
278  * @}
279  */
280 
281 #ifdef __cplusplus
282 }
283 #endif
284 
285 #endif /* __PMU_15XX_H_ */
286