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