1 /*
2 * Copyright 2020, NXP
3 * All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7 #include <string.h>
8 #include "fsl_common.h"
9 #include "fsl_power.h"
10
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.power"
14 #endif
15
16 /* NOTE: These registers are handled by the SDK. The user should not modify the source code. Changes to the source code
17 * can cause application failure. NXP is not responsible for any change to the code and is not obligated to provide
18 * support. */
19
20 /*******************************************************************************
21 * Variables
22 ******************************************************************************/
23
24 /*******************************************************************************
25 * Definitions
26 ******************************************************************************/
27 /**
28 * @brief LDO_FLASH_NV & LDO_EFUSE_PROG voltage settings
29 */
30 typedef enum _v_ldo_flashnv_ldo_efuse
31 {
32 V_LDO_1P650 = 0, /*!< 1.65 V */
33 V_LDO_1P700 = 1, /*!< 1.7 V */
34 V_LDO_1P750 = 2, /*!< 1.75 V */
35 V_LDO_1P800 = 3, /*!< 1.8 V */
36 V_LDO_1P850 = 4, /*!< 1.85 V */
37 V_LDO_1P900 = 5, /*!< 1.9 V */
38 V_LDO_1P950 = 6, /*!< 1.95 V */
39 V_LDO_2P000 = 7 /*!< 2.0 V */
40 } v_ldo_flashnv_ldo_efuse_t;
41
42 /**
43 * @brief Always On and Memories LDO voltage settings
44 */
45 typedef enum _v_ao
46 {
47 V_AO_0P700 = 1, /*!< 0.7 V */
48 V_AO_0P725 = 2, /*!< 0.725 V */
49 V_AO_0P750 = 3, /*!< 0.75 V */
50 V_AO_0P775 = 4, /*!< 0.775 V */
51 V_AO_0P800 = 5, /*!< 0.8 V */
52 V_AO_0P825 = 6, /*!< 0.825 V */
53 V_AO_0P850 = 7, /*!< 0.85 V */
54 V_AO_0P875 = 8, /*!< 0.875 V */
55 V_AO_0P900 = 9, /*!< 0.9 V */
56 V_AO_0P960 = 10, /*!< 0.96 V */
57 V_AO_0P970 = 11, /*!< 0.97 V */
58 V_AO_0P980 = 12, /*!< 0.98 V */
59 V_AO_0P990 = 13, /*!< 0.99 V */
60 V_AO_1P000 = 14, /*!< 1 V */
61 V_AO_1P010 = 15, /*!< 1.01 V */
62 V_AO_1P020 = 16, /*!< 1.02 V */
63 V_AO_1P030 = 17, /*!< 1.03 V */
64 V_AO_1P040 = 18, /*!< 1.04 V */
65 V_AO_1P050 = 19, /*!< 1.05 V */
66 V_AO_1P060 = 20, /*!< 1.06 V */
67 V_AO_1P070 = 21, /*!< 1.07 V */
68 V_AO_1P080 = 22, /*!< 1.08 V */
69 V_AO_1P090 = 23, /*!< 1.09 V */
70 V_AO_1P100 = 24, /*!< 1.1 V */
71 V_AO_1P110 = 25, /*!< 1.11 V */
72 V_AO_1P120 = 26, /*!< 1.12 V */
73 V_AO_1P130 = 27, /*!< 1.13 V */
74 V_AO_1P140 = 28, /*!< 1.14 V */
75 V_AO_1P150 = 29, /*!< 1.15 V */
76 V_AO_1P160 = 30, /*!< 1.16 V */
77 V_AO_1P220 = 31 /*!< 1.22 V */
78 } v_ao_t;
79
80 /**
81 * @brief DCDC voltage settings
82 */
83 typedef enum _v_dcdc
84 {
85 V_DCDC_0P950 = 0, /*!< 0.95 V */
86 V_DCDC_0P975 = 1, /*!< 0.975 V */
87 V_DCDC_1P000 = 2, /*!< 1 V */
88 V_DCDC_1P025 = 3, /*!< 1.025 V */
89 V_DCDC_1P050 = 4, /*!< 1.050 V */
90 V_DCDC_1P075 = 5, /*!< 1.075 V */
91 V_DCDC_1P100 = 6, /*!< 1.1 V */
92 V_DCDC_1P125 = 7, /*!< 1.125 V */
93 V_DCDC_1P150 = 8, /*!< 1.150 V */
94 V_DCDC_1P175 = 9, /*!< 1.175 V */
95 V_DCDC_1P200 = 10 /*!< 1.2 V */
96 } v_dcdc_t;
97
98 /**
99 * @brief LDO_CORE High Power Mode voltage settings
100 */
101 typedef enum _v_ldocore_hp
102 {
103 V_LDOCORE_HP_1P373 = 0, /*!< 1.373 V */
104 V_LDOCORE_HP_1P365 = 1, /*!< 1.365 V */
105 V_LDOCORE_HP_1P359 = 2, /*!< 1.359 V */
106 V_LDOCORE_HP_1P352 = 3, /*!< 1.352 V */
107 V_LDOCORE_HP_1P345 = 4, /*!< 1.345 V */
108 V_LDOCORE_HP_1P339 = 5, /*!< 1.339 V */
109 V_LDOCORE_HP_1P332 = 6, /*!< 1.332 V */
110 V_LDOCORE_HP_1P325 = 7, /*!< 1.325 V */
111 V_LDOCORE_HP_1P318 = 8, /*!< 1.318 V */
112 V_LDOCORE_HP_1P311 = 9, /*!< 1.311 V */
113 V_LDOCORE_HP_1P305 = 10, /*!< 1.305 V */
114 V_LDOCORE_HP_1P298 = 11, /*!< 1.298 V */
115 V_LDOCORE_HP_1P291 = 12, /*!< 1.291 V */
116 V_LDOCORE_HP_1P285 = 13, /*!< 1.285 V */
117 V_LDOCORE_HP_1P278 = 14, /*!< 1.278 V */
118 V_LDOCORE_HP_1P271 = 15, /*!< 1.271 V */
119 V_LDOCORE_HP_1P264 = 16, /*!< 1.264 V */
120 V_LDOCORE_HP_1P258 = 17, /*!< 1.258 V */
121 V_LDOCORE_HP_1P251 = 18, /*!< 1.251 V */
122 V_LDOCORE_HP_1P244 = 19, /*!< 1.244 V */
123 V_LDOCORE_HP_1P237 = 20, /*!< 1.237 V */
124 V_LDOCORE_HP_1P231 = 21, /*!< 1.231 V */
125 V_LDOCORE_HP_1P224 = 22, /*!< 1.224 V */
126 V_LDOCORE_HP_1P217 = 23, /*!< 1.217 V */
127 V_LDOCORE_HP_1P210 = 24, /*!< 1.21 V */
128 V_LDOCORE_HP_1P204 = 25, /*!< 1.204 V */
129 V_LDOCORE_HP_1P197 = 26, /*!< 1.197 V */
130 V_LDOCORE_HP_1P190 = 27, /*!< 1.19 V */
131 V_LDOCORE_HP_1P183 = 28, /*!< 1.183 V */
132 V_LDOCORE_HP_1P177 = 29, /*!< 1.177 V */
133 V_LDOCORE_HP_1P169 = 30, /*!< 1.169 V */
134 V_LDOCORE_HP_1P163 = 31, /*!< 1.163 V */
135 V_LDOCORE_HP_1P156 = 32, /*!< 1.156 V */
136 V_LDOCORE_HP_1P149 = 33, /*!< 1.149 V */
137 V_LDOCORE_HP_1P143 = 34, /*!< 1.143 V */
138 V_LDOCORE_HP_1P136 = 35, /*!< 1.136 V */
139 V_LDOCORE_HP_1P129 = 36, /*!< 1.129 V */
140 V_LDOCORE_HP_1P122 = 37, /*!< 1.122 V */
141 V_LDOCORE_HP_1P116 = 38, /*!< 1.116 V */
142 V_LDOCORE_HP_1P109 = 39, /*!< 1.109 V */
143 V_LDOCORE_HP_1P102 = 40, /*!< 1.102 V */
144 V_LDOCORE_HP_1P095 = 41, /*!< 1.095 V */
145 V_LDOCORE_HP_1P088 = 42, /*!< 1.088 V */
146 V_LDOCORE_HP_1P082 = 43, /*!< 1.082 V */
147 V_LDOCORE_HP_1P075 = 44, /*!< 1.075 V */
148 V_LDOCORE_HP_1P068 = 45, /*!< 1.068 V */
149 V_LDOCORE_HP_1P062 = 46, /*!< 1.062 V */
150 V_LDOCORE_HP_1P055 = 47, /*!< 1.055 V */
151 V_LDOCORE_HP_1P048 = 48, /*!< 1.048 V */
152 V_LDOCORE_HP_1P041 = 49, /*!< 1.041 V */
153 V_LDOCORE_HP_1P034 = 50, /*!< 1.034 V */
154 V_LDOCORE_HP_1P027 = 51, /*!< 1.027 V */
155 V_LDOCORE_HP_1P021 = 52, /*!< 1.021 V */
156 V_LDOCORE_HP_1P014 = 53, /*!< 1.014 V */
157 V_LDOCORE_HP_1P007 = 54, /*!< 1.007 V */
158 V_LDOCORE_HP_1P001 = 55, /*!< 1.001 V */
159 V_LDOCORE_HP_0P993 = 56, /*!< 0.9937 V */
160 V_LDOCORE_HP_0P987 = 57, /*!< 0.987 V */
161 V_LDOCORE_HP_0P980 = 58, /*!< 0.9802 V */
162 V_LDOCORE_HP_0P973 = 59, /*!< 0.9731 V */
163 V_LDOCORE_HP_0P966 = 60, /*!< 0.9666 V */
164 V_LDOCORE_HP_0P959 = 61, /*!< 0.9598 V */
165 V_LDOCORE_HP_0P953 = 62, /*!< 0.9532 V */
166 V_LDOCORE_HP_0P946 = 63, /*!< 0.946 V */
167 V_LDOCORE_HP_0P939 = 64, /*!< 0.9398 V */
168 V_LDOCORE_HP_0P932 = 65, /*!< 0.9327 V */
169 V_LDOCORE_HP_0P926 = 66, /*!< 0.9262 V */
170 V_LDOCORE_HP_0P919 = 67, /*!< 0.9199 V */
171 V_LDOCORE_HP_0P913 = 68, /*!< 0.9135 V */
172 V_LDOCORE_HP_0P907 = 69, /*!< 0.9071 V */
173 V_LDOCORE_HP_0P901 = 70, /*!< 0.9012 V */
174 V_LDOCORE_HP_0P895 = 71, /*!< 0.8953 V */
175 V_LDOCORE_HP_0P889 = 72, /*!< 0.8895 V */
176 V_LDOCORE_HP_0P883 = 73, /*!< 0.8837 V */
177 V_LDOCORE_HP_0P877 = 74, /*!< 0.8779 V */
178 V_LDOCORE_HP_0P871 = 75, /*!< 0.8719 V */
179 V_LDOCORE_HP_0P865 = 76, /*!< 0.8658 V */
180 V_LDOCORE_HP_0P859 = 77, /*!< 0.8596 V */
181 V_LDOCORE_HP_0P853 = 78, /*!< 0.8537 V */
182 V_LDOCORE_HP_0P847 = 79, /*!< 0.8474 V */
183 V_LDOCORE_HP_0P841 = 80, /*!< 0.8413 V */
184 V_LDOCORE_HP_0P835 = 81, /*!< 0.835 V */
185 V_LDOCORE_HP_0P828 = 82, /*!< 0.8288 V */
186 V_LDOCORE_HP_0P822 = 83, /*!< 0.8221 V */
187 V_LDOCORE_HP_0P815 = 84, /*!< 0.8158 V */
188 V_LDOCORE_HP_0P809 = 85, /*!< 0.8094 V */
189 V_LDOCORE_HP_0P802 = 86, /*!< 0.8026 V */
190 V_LDOCORE_HP_0P795 = 87, /*!< 0.7959 V */
191 V_LDOCORE_HP_0P789 = 88, /*!< 0.7893 V */
192 V_LDOCORE_HP_0P782 = 89, /*!< 0.7823 V */
193 V_LDOCORE_HP_0P775 = 90, /*!< 0.7756 V */
194 V_LDOCORE_HP_0P768 = 91, /*!< 0.7688 V */
195 V_LDOCORE_HP_0P762 = 92, /*!< 0.7623 V */
196 V_LDOCORE_HP_0P755 = 93, /*!< 0.7558 V */
197 V_LDOCORE_HP_0P749 = 94, /*!< 0.749 V */
198 V_LDOCORE_HP_0P742 = 95, /*!< 0.7421 V */
199 V_LDOCORE_HP_0P735 = 96, /*!< 0.7354 V */
200 V_LDOCORE_HP_0P728 = 97, /*!< 0.7284 V */
201 V_LDOCORE_HP_0P722 = 98, /*!< 0.722 V */
202 V_LDOCORE_HP_0P715 = 99 /*!< 0.715 V */
203 } v_ldocore_hp_t;
204
205 /**
206 * @brief LDO_CORE Low Power Mode voltage settings
207 */
208 typedef enum _v_ldocore_lp
209 {
210 V_LDOCORE_LP_0P750 = 3, /*!< 0.75 V */
211 V_LDOCORE_LP_0P800 = 2, /*!< 0.8 V */
212 V_LDOCORE_LP_0P850 = 1, /*!< 0.85 V */
213 V_LDOCORE_LP_0P900 = 0 /*!< 0.9 V */
214 } v_ldocore_lp_t;
215
216 /**
217 * @brief System Power Mode settings
218 */
219 typedef enum _v_system_power_profile
220 {
221 V_SYSTEM_POWER_PROFILE_LOW = 0UL, /*!< For system below or equal to 100 MHz */
222 V_SYSTEM_POWER_PROFILE_MEDIUM = 1UL, /*!< For system frequencies in ]100 MHz - 150 MHz] */
223 V_SYSTEM_POWER_PROFILE_HIGH = 2UL, /*!< For system above 150 MHz */
224 } v_system_power_profile_t;
225
226 /**
227 * @brief Manufacturing Process Corners
228 */
229 typedef enum
230 {
231 PROCESS_CORNER_SSS, /**< Slow Corner Process */
232 PROCESS_CORNER_NNN, /**< Nominal Corner Process */
233 PROCESS_CORNER_FFF, /**< Fast Corner Process */
234 PROCESS_CORNER_OTHERS, /**< SFN, SNF, NFS, Poly Res ... Corner Process */
235 } lowpower_process_corner_enum;
236
237 /** @brief Low Power main structure */
238 typedef struct
239 {
240 __IO uint32_t CFG; /*!< Low Power Mode Configuration, and miscallenous options */
241 __IO uint32_t PDCTRL[2]; /*!< Power Down control : controls power of various modules
242 in the different Low power modes, including ROM */
243 __IO uint32_t SRAMRETCTRL; /*!< Power Down control : controls power SRAM instances
244 in the different Low power modes */
245 __IO uint32_t CPURETCTRL; /*!< CPU0 retention control : controls CPU retention parameters in POWER DOWN modes */
246 __IO uint64_t VOLTAGE; /*!< Voltage control in Low Power Modes */
247 __IO uint32_t WAKEUPSRC[4]; /*!< Wake up sources control for sleepcon */
248 __IO uint32_t WAKEUPINT[4]; /*!< Wake up sources control for ARM */
249 __IO uint32_t HWWAKE; /*!< Interrupt that can postpone power down modes
250 in case an interrupt is pending when the processor request deepsleep */
251 __IO uint32_t WAKEUPIOSRC; /*!< Wake up I/O sources in DEEP POWER-DOWN mode */
252 } LPC_LOWPOWER_T;
253
254 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
255 /**
256 * @brief NMPA related Registers
257 */
258 #define FLASH_NMPA_BOD_LDOCORE (*((volatile unsigned int *)(0x3FC08)))
259 #define FLASH_NMPA_DCDC_POWER_PROFILE_LOW_ARRAY0 (*((volatile unsigned int *)(0x3FC18)))
260 #define FLASH_NMPA_DCDC_POWER_PROFILE_LOW_ARRAY1 (*((volatile unsigned int *)(0x3FC1C)))
261 #define FLASH_NMPA_LDO_AO (*((volatile unsigned int *)(0x3FC24)))
262 #define FLASH_NMPA_LDO_MEM (*((volatile unsigned int *)(0x3FD60)))
263 #define FLASH_NMPA_DCDC_POWER_PROFILE_HIGH_ARRAY0 (*((volatile unsigned int *)(0x3FCB0)))
264 #define FLASH_NMPA_DCDC_POWER_PROFILE_HIGH_ARRAY1 (*((volatile unsigned int *)(0x3FCB4)))
265 #define FLASH_NMPA_DCDC_POWER_PROFILE_MEDIUM_ARRAY0 (*((volatile unsigned int *)(0x3FCB8)))
266 #define FLASH_NMPA_DCDC_POWER_PROFILE_MEDIUM_ARRAY1 (*((volatile unsigned int *)(0x3FCBC)))
267 #define FLASH_NMPA_PVT_MONITOR_0_RINGO (*((volatile unsigned int *)(0x3FCE0)))
268 #define FLASH_NMPA_PVT_MONITOR_1_RINGO (*((volatile unsigned int *)(0x3FCF0)))
269
270 /**
271 * @brief NMPA related masks
272 */
273
274 #define FLASH_NMPA_BOD_LDOCORE_REGREF_1P8V_OFFSET_SHIFT (24U)
275 #define FLASH_NMPA_BOD_LDOCORE_REGREF_1P8V_OFFSET_MASK (0xFF000000U)
276 #define FLASH_NMPA_LDO_AO_VADJ_ACTIVE_SHIFT (0U)
277 #define FLASH_NMPA_LDO_AO_VADJ_ACTIVE_MASK (0xFFU)
278 #endif
279
280 /**
281 * @brief CSS related Registers
282 */
283 #define CSSV2_STATUS_REG (*((volatile unsigned int *)(0x40030000)))
284 #define CSSV2_CTRL_REG (*((volatile unsigned int *)(0x40030004)))
285 #define SYSCON_CSS_CLK_CTRL_REG (*((volatile unsigned int *)(0x400009B0)))
286 #define SYSCON_CSS_CLK_CTRL_SET_REG (*((volatile unsigned int *)(0x400009B4)))
287 #define SYSCON_CSS_CLK_CTRL_CLR_REG (*((volatile unsigned int *)(0x400009B8)))
288
289 /**
290 * @brief Wake-up I/O positions
291 */
292 /*!< wake-up 0 */
293 #define WAKEUPIO_0_PORT (1UL)
294 #define WAKEUPIO_0_PINS (1UL)
295 /*!< wake-up 1 */
296 #define WAKEUPIO_1_PORT (0UL)
297 #define WAKEUPIO_1_PINS (28UL)
298 /*!< wake-up 2 */
299 #define WAKEUPIO_2_PORT (1UL)
300 #define WAKEUPIO_2_PINS (18UL)
301 /*!< wake-up 3 */
302 #define WAKEUPIO_3_PORT (1UL)
303 #define WAKEUPIO_3_PINS (30UL)
304 /*!< wake-up 4 */
305 #define WAKEUPIO_4_PORT (0UL)
306 #define WAKEUPIO_4_PINS (26UL)
307
308 /**
309 * @brief SRAM Low Power Modes
310 */
311 #define LOWPOWER_SRAM_LPMODE_MASK (0xFUL)
312 #define LOWPOWER_SRAM_LPMODE_ACTIVE (0x6UL) /*!< SRAM functional mode */
313 #define LOWPOWER_SRAM_LPMODE_SLEEP (0xFUL) /*!< SRAM Sleep mode (Data retention, fast wake up) */
314 #define LOWPOWER_SRAM_LPMODE_DEEPSLEEP (0x8UL) /*!< SRAM Deep Sleep mode (Data retention, slow wake up) */
315 #define LOWPOWER_SRAM_LPMODE_SHUTDOWN (0x9UL) /*!< SRAM Shut Down mode (no data retention) */
316 #define LOWPOWER_SRAM_LPMODE_POWERUP (0xAUL) /*!< SRAM is powering up */
317
318 /**
319 * @brief SoC Low Power modes
320 */
321 #define LOWPOWER_CFG_LPMODE_INDEX 0
322 #define LOWPOWER_CFG_LPMODE_MASK (0x3UL << LOWPOWER_CFG_LPMODE_INDEX)
323 #define LOWPOWER_CFG_SELCLOCK_INDEX 2
324 #define LOWPOWER_CFG_SELCLOCK_MASK (0x1UL << LOWPOWER_CFG_SELCLOCK_INDEX)
325 #define LOWPOWER_CFG_SELMEMSUPPLY_INDEX 3
326 #define LOWPOWER_CFG_SELMEMSUPPLY_MASK (0x1UL << LOWPOWER_CFG_SELMEMSUPPLY_INDEX)
327 #define LOWPOWER_CFG_MEMLOWPOWERMODE_INDEX 4
328 #define LOWPOWER_CFG_MEMLOWPOWERMODE_MASK (0x1UL << LOWPOWER_CFG_MEMLOWPOWERMODE_INDEX)
329 #define LOWPOWER_CFG_LDODEEPSLEEPREF_INDEX 5
330 #define LOWPOWER_CFG_LDODEEPSLEEPREF_MASK (0x1UL << LOWPOWER_CFG_LDODEEPSLEEPREF_INDEX)
331
332 #define LOWPOWER_CFG_LPMODE_ACTIVE 0 /*!< ACTIVE mode */
333 #define LOWPOWER_CFG_LPMODE_DEEPSLEEP 1 /*!< DEEP-SLEEP mode */
334 #define LOWPOWER_CFG_LPMODE_POWERDOWN 2 /*!< POWER-DOWN mode */
335 #define LOWPOWER_CFG_LPMODE_DEEPPOWERDOWN 3 /*!< DEEP POWER-DOWN mode */
336 #define LOWPOWER_CFG_LPMODE_SLEEP 4 /*!< SLEEP mode */
337
338 #define LOWPOWER_CFG_SELCLOCK_1MHZ 0 /*!< The 1 MHz clock is used during the configuration of the PMC */
339 #define LOWPOWER_CFG_SELCLOCK_12MHZ \
340 1 /*!< The 12 MHz clock is used during the configuration of the PMC (to speed up PMC configuration process)*/
341
342 #define LOWPOWER_CFG_SELMEMSUPPLY_LDOMEM 0 /*!< In DEEP SLEEP power mode, the Memories are supplied by the LDO_MEM */
343 #define LOWPOWER_CFG_SELMEMSUPPLY_LDODEEPSLEEP \
344 1 /*!< In DEEP SLEEP power mode, the Memories are supplied by the LDO_DEEP_SLEEP (or DCDC) */
345
346 #define LOWPOWER_CFG_MEMLOWPOWERMODE_SOURCEBIASING \
347 0 /*!< All SRAM instances use "Source Biasing" as low power mode technic (it is recommended to set LDO_MEM as high \
348 as possible -- 1.1V typical -- during low power mode) */
349 #define LOWPOWER_CFG_MEMLOWPOWERMODE_VOLTAGESCALING \
350 1 /*!< All SRAM instances use "Voltage Scaling" as low power mode technic (it is recommended to set LDO_MEM as low \
351 as possible -- down to 0.7V -- during low power mode) */
352
353 /**
354 * @brief LDO Voltage control in Low Power Modes
355 */
356 #define LOWPOWER_VOLTAGE_LDO_PMU_INDEX 0
357 #define LOWPOWER_VOLTAGE_LDO_PMU_MASK (0x1FULL << LOWPOWER_VOLTAGE_LDO_PMU_INDEX)
358 #define LOWPOWER_VOLTAGE_LDO_MEM_INDEX 5
359 #define LOWPOWER_VOLTAGE_LDO_MEM_MASK (0x1FULL << LOWPOWER_VOLTAGE_LDO_MEM_INDEX)
360 #define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX 10
361 #define LOWPOWER_VOLTAGE_LDO_PMU_BOOST_MASK (0x1FULL << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX)
362 #define LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX 15
363 #define LOWPOWER_VOLTAGE_LDO_MEM_BOOST_MASK (0x1FULL << LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX)
364
365 /* CPU Retention Control*/
366 #define LOWPOWER_CPURETCTRL_ENA_INDEX 0
367 #define LOWPOWER_CPURETCTRL_ENA_MASK (0x1UL << LOWPOWER_CPURETCTRL_ENA_INDEX)
368 #define LOWPOWER_CPURETCTRL_MEMBASE_INDEX 1
369 #define LOWPOWER_CPURETCTRL_MEMBASE_MASK (0x1FFFUL << LOWPOWER_CPURETCTRL_MEMBASE_INDEX)
370 #define LOWPOWER_CPURETCTRL_RETDATALENGTH_INDEX 14
371 #define LOWPOWER_CPURETCTRL_RETDATALENGTH_MASK (0x3FFUL << LOWPOWER_CPURETCTRL_RETDATALENGTH_INDEX)
372
373 /**
374 * @brief SRAM Power Control Registers Code
375 */
376 // LSDEL DSBDEL DSB LS
377 #define SRAM_PWR_MODE_ACT_CODE (0x6UL) // Active | 0 1 1 0
378 #define SRAM_PWR_MODE_LS_CODE (0xFUL) // Light Sleep | 1 1 1 1
379 #define SRAM_PWR_MODE_DS_CODE (0x8UL) // Deep Sleep | 1 0 0 0
380 #define SRAM_PWR_MODE_SD_CODE (0x9UL) // Shut Down | 1 0 0 1
381 #define SRAM_PWR_MODE_MPU_CODE (0xEUL) // Matrix Power Up | 1 1 1 0
382 #define SRAM_PWR_MODE_FPU_CODE (0xAUL) // Full Power Up | 1 0 1 0
383
384 /**
385 * @brief System voltage setting
386 */
387 // All 3 DCDC_POWER_PROFILE_* constants below have been updated after chip characterization on ATE
388 #define DCDC_POWER_PROFILE_LOW_MAX_FREQ_HZ \
389 (100000000UL) /* Maximum System Frequency allowed with DCDC Power Profile LOW */
390 #define DCDC_POWER_PROFILE_MEDIUM_MAX_FREQ_HZ \
391 (135000000UL) /* Maximum System Frequency allowed with DCDC Power Profile MEDIUM */
392 #define DCDC_POWER_PROFILE_HIGH_MAX_FREQ_HZ \
393 (150000000UL) /* Maximum System Frequency allowed with DCDC Power Profile HIGH */
394
395 /**
396 * @brief Manufacturing Process Parameters
397 */
398 // All 3 PROCESS_* constants below have been updated after chip characterization on ATE
399 #define PROCESS_NNN_AVG_HZ (14900000UL) /* Average Ring Oscillator value for Nominal (NNN) Manufacturing Process */
400 #define PROCESS_NNN_STD_HZ \
401 (515000UL) /* Standard Deviation Ring Oscillator value for Nominal (NNN) Manufacturing Process */
402 #define PROCESS_NNN_LIMITS \
403 (2UL) /* Nominal (NNN) Manufacturing Process Ring Oscillator values limit (with respect to the Average value) */
404
405 #define PROCESS_NNN_MIN_HZ \
406 (PROCESS_NNN_AVG_HZ - \
407 (PROCESS_NNN_LIMITS * \
408 PROCESS_NNN_STD_HZ)) /* Minimum Ring Oscillator value for Nominal (NNN) Manufacturing Process */
409
410 #define PROCESS_NNN_MAX_HZ \
411 (PROCESS_NNN_AVG_HZ + \
412 (PROCESS_NNN_LIMITS * \
413 PROCESS_NNN_STD_HZ)) /* Maximum Ring OScillator value for Nominal (NNN) Manufacturing Process */
414
415 // All 9 VOLTAGE_* constants below have been updated after chip characterization on ATE
416 #define VOLTAGE_SSS_LOW_MV (1075UL) /* Voltage Settings for : Process=SSS, DCDC Power Profile=LOW */
417 #define VOLTAGE_SSS_MED_MV (1175UL) /* Voltage Settings for : Process=SSS, DCDC Power Profile=MEDIUM */
418 #define VOLTAGE_SSS_HIG_MV (1200UL) /* Voltage Settings for : Process=SSS, DCDC Power Profile=HIGH */
419
420 #define VOLTAGE_NNN_LOW_MV (1025UL) /* Voltage Settings for : Process=NNN, DCDC Power Profile=LOW */
421 #define VOLTAGE_NNN_MED_MV (1100UL) /* Voltage Settings for : Process=NNN, DCDC Power Profile=MEDIUM */
422 #define VOLTAGE_NNN_HIG_MV (1150UL) /* Voltage Settings for : Process=NNN, DCDC Power Profile=HIGH */
423
424 #define VOLTAGE_FFF_LOW_MV (1025UL) /* Voltage Settings for : Process=FFF, DCDC Power Profile=LOW */
425 #define VOLTAGE_FFF_MED_MV (1100UL) /* Voltage Settings for : Process=FFF, DCDC Power Profile=MEDIUM */
426 #define VOLTAGE_FFF_HIG_MV (1150UL) /* Voltage Settings for : Process=FFF, DCDC Power Profile=HIGH */
427
428 /*******************************************************************************
429 * Codes
430 ******************************************************************************/
431
432 /*******************************************************************************
433 * LOCAL FUNCTIONS PROTOTYPES
434 ******************************************************************************/
435 static void POWER_WaitLDOCoreInit(void);
436 static void POWER_SRAMPowerUpDelay(void);
437 static void POWER_PowerCycleCpu(void);
438 static void POWER_SetLowPowerMode(LPC_LOWPOWER_T *p_lowpower_cfg);
439 static uint32_t POWER_WakeUpIOCtrl(uint32_t p_wakeup_io_ctrl);
440 static uint32_t POWER_SetLdoAoLdoMemVoltage(uint32_t p_lp_mode);
441 static void POWER_SetSystemPowerProfile(v_system_power_profile_t power_profile);
442 static void POWER_SetVoltageForProcess(v_system_power_profile_t power_profile);
443 static lowpower_process_corner_enum POWER_GetPartProcessCorner(void);
444 static void POWER_SetSystemVoltage(uint32_t system_voltage_mv);
445 static void POWER_SetSystemClock12MHZ(void);
446 static void POWER_SRAMSetRegister(power_sram_index_t sram_index, uint32_t power_mode);
447 static void POWER_SRAMActiveToLightSleep(power_sram_index_t sram_index);
448 static void POWER_SRAMActiveToDeepSleep(power_sram_index_t sram_index);
449 static void POWER_SRAMActiveToShutDown(power_sram_index_t sram_index);
450 static void POWER_SRAMLightSleepToActive(power_sram_index_t sram_index);
451 static void POWER_SRAMDeepSleepToActive(power_sram_index_t sram_index);
452 static void POWER_SRAMShutDownToActive(power_sram_index_t sram_index);
453
454 /**
455 * brief SoC Power Management Controller initialization
456 * return power_status_t
457 */
POWER_PowerInit(void)458 power_status_t POWER_PowerInit(void)
459 {
460 // To speed up PMC configuration, change PMC clock from 1 MHz to 12 MHz.
461 // Set Power Mode to "ACTIVE" (required specially when waking up from DEEP POWER-DOWN)
462 PMC->CTRL = (PMC->CTRL | PMC_CTRL_SELCLOCK_MASK) & (~PMC_CTRL_LPMODE_MASK);
463
464 // Check that no time out occured during the hardware wake-up process
465 if (PMC->TIMEOUTEVENTS != 0UL)
466 {
467 // A least 1 time-out error occured.
468 return kPOWER_Status_Fail;
469 }
470
471 // Set up wake-up IO pad control source : IOCON ((WAKEUPIO_ENABLE = 0)
472 PMC->WAKEUPIOCTRL &= ~PMC_WAKEUPIOCTRL_WAKEUPIO_ENABLE_CTRL_MASK;
473
474 // Set LDO_FLASHNV output voltage
475 PMC->LDOFLASHNV = (PMC->LDOFLASHNV & (~PMC_LDOFLASHNV_VADJ_MASK)) | PMC_LDOFLASHNV_VADJ(V_LDO_1P850);
476
477 // Set LDO_EFUSE_PROG output voltage
478 PMC->LDOEFUSEPROG = (PMC->LDOEFUSEPROG & (~PMC_LDOEFUSEPROG_VADJ_MASK)) | PMC_LDOEFUSEPROG_VADJ(V_LDO_1P850);
479
480 // Configure the voltage level of LDO CORE Low Power mode (TODO :: :: Temporarily set to 0.9V; target is 0.8 V)*/
481 PMC->LDOCORE0 = (PMC->LDOCORE0 & (~PMC_LDOCORE0_LPREGREFSEL_MASK)) | PMC_LDOCORE0_LPREGREFSEL(V_LDOCORE_LP_0P900);
482
483 // SRAM uses Voltage Scaling in all Low Power modes
484 PMC->SRAMCTRL = (PMC->SRAMCTRL & (~PMC_SRAMCTRL_SMB_MASK)) | PMC_SRAMCTRL_SMB(3);
485
486 // Enable Analog References fast wake-up in case of wake-up from all low power modes and Hardware Pin reset
487 PMC->REFFASTWKUP = PMC->REFFASTWKUP | PMC_REFFASTWKUP_LPWKUP_MASK | PMC_REFFASTWKUP_HWWKUP_MASK;
488
489 // Enable FRO192MHz shut-off glitch suppression.
490 // TODO :: :: Check the Power Consumption Impact of this setting during DEEP-SLEEP and POWER-DOWN.
491 // (Supposed to be 1 to 2uA in typical conditions). If the impe
492 //
493 ANACTRL->OSC_TESTBUS = 0x1;
494
495 return kPOWER_Status_Success;
496 }
497
498 /**
499 * brief
500 * return power_status_t
501 */
POWER_SetCorePowerSource(power_core_pwr_source_t pwr_source)502 power_status_t POWER_SetCorePowerSource(power_core_pwr_source_t pwr_source)
503 {
504 uint32_t pmc_reg_data;
505
506 switch (pwr_source)
507 {
508 case kPOWER_CoreSrcDCDC:
509 {
510 // Enable DCDC (1st step)
511 PMC->CMD = PMC_CMD_DCDCENABLE_MASK;
512
513 // Wait until DCDC is enabled
514 while ((PMC->STATUSPWR & PMC_STATUSPWR_DCDCPWROK_MASK) == 0UL)
515 {
516 }
517
518 // Disable LDO Core Low Power Mode (2nd step)
519 PMC->CMD = PMC_CMD_LDOCORELOWPWRDISABLE_MASK;
520
521 // Disable LDO Core High Power Mode (3rd step)
522 PMC->CMD = PMC_CMD_LDOCOREHIGHPWRDISABLE_MASK;
523
524 // Check PMC Finite State Machines status
525 pmc_reg_data = PMC->STATUS & (PMC_STATUS_FSMDCDCENABLE_MASK | PMC_STATUS_FSMLDOCOREHPENABLE_MASK |
526 PMC_STATUS_FSMLDOCORELPENABLE_MASK | PMC_STATUS_FSMLDOCOREEXPTMRENABLE_MASK);
527 if (pmc_reg_data != (PMC_STATUS_FSMDCDCENABLE_MASK | PMC_STATUS_FSMLDOCOREEXPTMRENABLE_MASK))
528 {
529 // Error : only DCDC and LDO CORE Exponential Timer must both be enabled.
530 return (kPOWER_Status_Fail);
531 }
532 }
533 break;
534
535 case kPOWER_CoreSrcLDOCoreHP:
536 {
537 // Enable LDO Core High Power Mode (1st step)
538 PMC->CMD = PMC_CMD_LDOCOREHIGHPWRENABLE_MASK;
539
540 // Note: Once LDO_CORE High Power Mode has been enabled,
541 // at least 2us are required before one can reliabily sample
542 // the LDO Low Voltage Detectore Output.
543 POWER_WaitLDOCoreInit();
544
545 // Wait until LDO CORE High Power is enabled
546 while ((PMC->STATUSPWR & PMC_STATUSPWR_LDOCOREPWROK_MASK) == 0UL)
547 {
548 }
549
550 // Disable DCDC (2nd step)
551 PMC->CMD = PMC_CMD_DCDCDISABLE_MASK;
552
553 // Disable LDO Core Low Power Mode (3rd step)
554 PMC->CMD = PMC_CMD_LDOCORELOWPWRDISABLE_MASK;
555
556 // Check PMC Finite State Machines status
557 pmc_reg_data = PMC->STATUS & (PMC_STATUS_FSMDCDCENABLE_MASK | PMC_STATUS_FSMLDOCOREHPENABLE_MASK |
558 PMC_STATUS_FSMLDOCORELPENABLE_MASK | PMC_STATUS_FSMLDOCOREEXPTMRENABLE_MASK);
559 if (pmc_reg_data != PMC_STATUS_FSMLDOCOREHPENABLE_MASK)
560 {
561 // Error : only LDO CORE High Power mode must both be enabled.
562 return (kPOWER_Status_Fail);
563 }
564 }
565 break;
566
567 case kPOWER_CoreSrcLDOCoreLP:
568 {
569 // Enable LDO Core Low Power Mode (1st step)
570 PMC->CMD = PMC_CMD_LDOCORELOWPWRENABLE_MASK;
571
572 // Disable LDO Core High Power Mode (2nd step)
573 PMC->CMD = PMC_CMD_LDOCOREHIGHPWRDISABLE_MASK;
574
575 // Disable DCDC (3rd step)
576 PMC->CMD = PMC_CMD_DCDCDISABLE_MASK;
577
578 // Check PMC Finite State Machines status
579 pmc_reg_data = PMC->STATUS & (PMC_STATUS_FSMDCDCENABLE_MASK | PMC_STATUS_FSMLDOCOREHPENABLE_MASK |
580 PMC_STATUS_FSMLDOCORELPENABLE_MASK | PMC_STATUS_FSMLDOCOREEXPTMRENABLE_MASK);
581 if (pmc_reg_data != (PMC_STATUS_FSMLDOCORELPENABLE_MASK | PMC_STATUS_FSMLDOCOREEXPTMRENABLE_MASK))
582 {
583 // Error : only LDO CORE Low Power mode and LDO CORE Exponential Timer must both be enabled.
584 return (kPOWER_Status_Fail);
585 }
586 }
587 break;
588
589 case kPOWER_CoreSrcExternal:
590 {
591 // Disable LDO Core Low Power Mode (1st step)
592 PMC->CMD = PMC_CMD_LDOCORELOWPWRDISABLE_MASK;
593
594 // Disable LDO Core High Power Mode (2nd step)
595 PMC->CMD = PMC_CMD_LDOCOREHIGHPWRDISABLE_MASK;
596
597 // Disable DCDC (3rd step)
598 PMC->CMD = PMC_CMD_DCDCDISABLE_MASK;
599
600 // Check PMC Finite State Machines status
601 pmc_reg_data = PMC->STATUS & (PMC_STATUS_FSMDCDCENABLE_MASK | PMC_STATUS_FSMLDOCOREHPENABLE_MASK |
602 PMC_STATUS_FSMLDOCORELPENABLE_MASK | PMC_STATUS_FSMLDOCOREEXPTMRENABLE_MASK);
603 if (pmc_reg_data != 0UL)
604 {
605 // Error : All power sources must be disabled.
606 return (kPOWER_Status_Fail);
607 }
608 }
609 break;
610
611 default: // Not supported
612 return (kPOWER_Status_Fail);
613
614 } // End switch (pwr_source)
615
616 return (kPOWER_Status_Success);
617 }
618
619 /**
620 * brief
621 * @param :
622 * return power_core_pwr_source_t
623 */
POWER_GetCorePowerSource(void)624 power_core_pwr_source_t POWER_GetCorePowerSource(void)
625 {
626 uint32_t reg_status, reg_statuspwr;
627
628 reg_status = PMC->STATUS;
629 reg_statuspwr = PMC->STATUSPWR;
630
631 if ((0UL != (reg_statuspwr & PMC_STATUSPWR_DCDCPWROK_MASK)) && (0UL != (reg_status & PMC_STATUS_FSMDCDCENABLE_MASK)))
632 {
633 /* DCDC */
634 return (kPOWER_CoreSrcDCDC);
635 }
636 else
637 {
638 if ((0UL != (reg_statuspwr & PMC_STATUSPWR_LDOCOREPWROK_MASK)) && (0UL != (reg_status & PMC_STATUS_FSMLDOCOREHPENABLE_MASK)))
639 {
640 /* LDO_CORE High Power Mode */
641 return (kPOWER_CoreSrcLDOCoreHP);
642 }
643 else
644 {
645 if (0UL != (reg_status & PMC_STATUS_FSMLDOCORELPENABLE_MASK))
646 {
647 /* LDO_CORE Low Power Mode */
648 return (kPOWER_CoreSrcLDOCoreLP);
649 }
650 else
651 {
652 /* External */
653 return (kPOWER_CoreSrcExternal);
654 }
655 }
656 }
657 }
658
659 /**
660 * brief
661 * return nothing
662 */
POWER_CorePowerSourceControl(power_core_pwr_source_t pwr_source,power_core_pwr_state_t pwr_state)663 power_status_t POWER_CorePowerSourceControl(power_core_pwr_source_t pwr_source, power_core_pwr_state_t pwr_state)
664 {
665 switch (pwr_source)
666 {
667 case kPOWER_CoreSrcDCDC:
668 {
669 if (pwr_state == kPOWER_CorePwrEnable)
670 {
671 // Enable DCDC
672 PMC->CMD = PMC_CMD_DCDCENABLE_MASK;
673
674 // Wait until DCDC is enabled
675 while ((PMC->STATUSPWR & PMC_STATUSPWR_DCDCPWROK_MASK) == 0UL)
676 {
677 }
678
679 // Check PMC Finite State Machines status
680 if ((PMC->STATUS & PMC_STATUS_FSMDCDCENABLE_MASK) == 0UL)
681 {
682 // Error : DCDC not enabled.
683 return (kPOWER_Status_Fail);
684 }
685 }
686 else
687 {
688 // Disable DCDC
689 PMC->CMD = PMC_CMD_DCDCDISABLE_MASK;
690
691 // Check PMC Finite State Machines status
692 if ((PMC->STATUS & PMC_STATUS_FSMDCDCENABLE_MASK) != 0UL)
693 {
694 // Error : DCDC is enabled.
695 return (kPOWER_Status_Fail);
696 }
697 }
698 }
699 break;
700
701 case kPOWER_CoreSrcLDOCoreHP:
702 {
703 if (pwr_state == kPOWER_CorePwrEnable)
704 {
705 // Enable LDO Core High Power Mode
706 PMC->CMD = PMC_CMD_LDOCOREHIGHPWRENABLE_MASK;
707
708 // Note: Once LDO_CORE High Power Mode has been enabled,
709 // at least 2us are required before one can reliabily sample
710 // the LDO Low Voltage Detector Output.
711 POWER_WaitLDOCoreInit();
712
713 // Wait until LDO CORE High Power is enabled
714 while ((PMC->STATUSPWR & PMC_STATUSPWR_LDOCOREPWROK_MASK) == 0UL)
715 {
716 }
717
718 // Check PMC Finite State Machines status
719 if ((PMC->STATUS & PMC_STATUS_FSMLDOCOREHPENABLE_MASK) == 0UL)
720 {
721 // Error : LDO CORE High Power mode is not enabled.
722 return (kPOWER_Status_Fail);
723 }
724 }
725 else
726 {
727 // Disable LDO Core High Power Mode
728 PMC->CMD = PMC_CMD_LDOCOREHIGHPWRDISABLE_MASK;
729
730 // Check PMC Finite State Machines status
731 if ((PMC->STATUS & PMC_STATUS_FSMLDOCOREHPENABLE_MASK) != 0UL)
732 {
733 // Error : LDO CORE High Power mode is enabled.
734 return (kPOWER_Status_Fail);
735 }
736 }
737 }
738 break;
739
740 case kPOWER_CoreSrcLDOCoreLP:
741 {
742 if (pwr_state == kPOWER_CorePwrEnable)
743 {
744 // Enable LDO Core Low Power Mode (1st step)
745 PMC->CMD = PMC_CMD_LDOCORELOWPWRENABLE_MASK;
746
747 // Check PMC Finite State Machines status
748 if ((PMC->STATUS & (PMC_STATUS_FSMLDOCORELPENABLE_MASK | PMC_STATUS_FSMLDOCOREEXPTMRENABLE_MASK)) !=
749 (PMC_STATUS_FSMLDOCORELPENABLE_MASK | PMC_STATUS_FSMLDOCOREEXPTMRENABLE_MASK))
750 {
751 // Error : LDO CORE Low Power mode is not enabled.
752 return (kPOWER_Status_Fail);
753 }
754 }
755 else
756 {
757 // Disable LDO Core Low Power Mode
758 PMC->CMD = PMC_CMD_LDOCORELOWPWRDISABLE_MASK;
759
760 // Check PMC Finite State Machines status
761 if ((PMC->STATUS & (PMC_STATUS_FSMLDOCORELPENABLE_MASK | PMC_STATUS_FSMLDOCOREEXPTMRENABLE_MASK)) != 0UL)
762 {
763 // Error : LDO CORE Low Power mode is enabled.
764 return (kPOWER_Status_Fail);
765 }
766 }
767 }
768 break;
769
770 default: // Not supported
771 return (kPOWER_Status_Fail);
772
773 } // End switch (pwr_source)
774
775 return (kPOWER_Status_Success);
776 }
777
778 /**
779 * brief
780 * return
781 */
POWER_GetSRAMPowerMode(power_sram_index_t sram_index)782 power_sram_pwr_mode_t POWER_GetSRAMPowerMode(power_sram_index_t sram_index)
783 {
784 power_sram_pwr_mode_t pwr_mode;
785 uint32_t state;
786 uint32_t sram_ctrl_0 = PMC->SRAMCTRL0;
787 uint32_t sram_ctrl_1 = PMC->SRAMCTRL1;
788
789 switch (sram_index)
790 {
791 case kPOWER_SRAM_IDX_RAM_X0:
792 {
793 state = (sram_ctrl_0 >> PMC_SRAMCTRL0_RAM_X0_LS_SHIFT) & 0xFUL;
794 break;
795 }
796
797 case kPOWER_SRAM_IDX_RAM_00:
798 {
799 state = (sram_ctrl_0 >> PMC_SRAMCTRL0_RAM_00_LS_SHIFT) & 0xFUL;
800 break;
801 }
802
803 case kPOWER_SRAM_IDX_RAM_01:
804 {
805 state = (sram_ctrl_0 >> PMC_SRAMCTRL0_RAM_01_LS_SHIFT) & 0xFUL;
806 break;
807 }
808
809 case kPOWER_SRAM_IDX_RAM_02:
810 {
811 state = (sram_ctrl_0 >> PMC_SRAMCTRL0_RAM_02_LS_SHIFT) & 0xFUL;
812 break;
813 }
814
815 case kPOWER_SRAM_IDX_RAM_03:
816 {
817 state = (sram_ctrl_0 >> PMC_SRAMCTRL0_RAM_03_LS_SHIFT) & 0xFUL;
818 break;
819 }
820
821 case kPOWER_SRAM_IDX_RAM_10:
822 {
823 state = (sram_ctrl_0 >> PMC_SRAMCTRL0_RAM_10_LS_SHIFT) & 0xFU;
824 break;
825 }
826
827 case kPOWER_SRAM_IDX_RAM_20:
828 {
829 state = (sram_ctrl_0 >> PMC_SRAMCTRL0_RAM_20_LS_SHIFT) & 0xFUL;
830 break;
831 }
832
833 case kPOWER_SRAM_IDX_RAM_30:
834 {
835 state = (sram_ctrl_0 >> PMC_SRAMCTRL0_RAM_30_LS_SHIFT) & 0xFUL;
836 break;
837 }
838
839 case kPOWER_SRAM_IDX_RAM_40:
840 {
841 state = (sram_ctrl_1 >> PMC_SRAMCTRL1_RAM_40_LS_SHIFT) & 0xFUL;
842 break;
843 }
844
845 case kPOWER_SRAM_IDX_RAM_41:
846 {
847 state = (sram_ctrl_1 >> PMC_SRAMCTRL1_RAM_41_LS_SHIFT) & 0xFUL;
848 break;
849 }
850
851 case kPOWER_SRAM_IDX_RAM_42:
852 {
853 state = (sram_ctrl_1 >> PMC_SRAMCTRL1_RAM_42_LS_SHIFT) & 0xFUL;
854 break;
855 }
856
857 case kPOWER_SRAM_IDX_RAM_43:
858 {
859 state = (sram_ctrl_1 >> PMC_SRAMCTRL1_RAM_43_LS_SHIFT) & 0xFUL;
860 break;
861 }
862
863 default:
864 // Error
865 state = 0x6; // Active.
866 break;
867 }
868
869 switch (state)
870 {
871 case 0x6:
872 pwr_mode = kPOWER_SRAMPwrActive;
873 break;
874
875 case 0xF:
876 pwr_mode = kPOWER_SRAMPwrLightSleep;
877 break;
878
879 case 0x8:
880 pwr_mode = kPOWER_SRAMPwrDeepSleep;
881 break;
882
883 case 0x9:
884 pwr_mode = kPOWER_SRAMPwrShutDown;
885 break;
886
887 default:
888 pwr_mode = kPOWER_SRAMPwrActive;
889 break;
890 }
891
892 return (pwr_mode);
893 }
894
895 /**
896 * brief
897 * return
898 */
POWER_SRAMPowerModeControl(power_sram_bit_t sram_inst,power_sram_pwr_mode_t pwr_mode)899 power_status_t POWER_SRAMPowerModeControl(power_sram_bit_t sram_inst, power_sram_pwr_mode_t pwr_mode)
900 {
901 power_sram_pwr_mode_t current_pwr_mode;
902 power_sram_index_t sram_index = kPOWER_SRAM_IDX_RAM_X0;
903
904 sram_inst = (power_sram_bit_t)(uint32_t)(((uint32_t)sram_inst & 0x3FFFUL)); /* Only SRAM from RAM_X0 to RAM_F3 */
905 while ((uint32_t)sram_inst != 0UL)
906 {
907 // There is a least 1 SRAM instance to be processed
908 if (0UL != ((uint32_t)sram_inst & 0x1UL))
909 {
910 // Get current SRAM state
911 current_pwr_mode = POWER_GetSRAMPowerMode(sram_index);
912
913 // The SRAM instance Power state must be updated
914 switch (current_pwr_mode)
915 {
916 case kPOWER_SRAMPwrActive:
917 { // Active
918 switch (pwr_mode)
919 {
920 case kPOWER_SRAMPwrActive:
921 { // Active ---> Active : there is nothing to do.
922 break;
923 }
924
925 case kPOWER_SRAMPwrLightSleep:
926 { // Active ---> Light Sleep
927 POWER_SRAMActiveToLightSleep(sram_index);
928 break;
929 }
930
931 case kPOWER_SRAMPwrDeepSleep:
932 { // Active ---> Deep Sleep
933 POWER_SRAMActiveToDeepSleep(sram_index);
934 break;
935 }
936
937 case kPOWER_SRAMPwrShutDown:
938 { // Active ---> Shut Down
939 POWER_SRAMActiveToShutDown(sram_index);
940 break;
941 }
942
943 default:
944 // Do nothing.
945 break;
946 } // switch( pwr_mode )
947
948 break;
949 }
950
951 case kPOWER_SRAMPwrLightSleep:
952 { // Light Sleep
953 switch (pwr_mode)
954 {
955 case kPOWER_SRAMPwrActive:
956 { // Light Sleep ---> Active
957 POWER_SRAMLightSleepToActive(sram_index);
958 break;
959 }
960
961 case kPOWER_SRAMPwrLightSleep:
962 { // Light Sleep ---> Light Sleep : there is nothing to do.
963 break;
964 }
965
966 default:
967 // Light Sleep ---> Shut Down : FORBIDDEN (error)
968 // Light Sleep ---> Deep Sleep : FORBIDDEN (error)
969 return (kPOWER_Status_Fail);
970 } // switch( pwr_mode )
971
972 break;
973 }
974
975 case kPOWER_SRAMPwrDeepSleep:
976 { // Deep Sleep
977 switch (pwr_mode)
978 {
979 case kPOWER_SRAMPwrActive:
980 { // Deep Sleep ---> Active
981 POWER_SRAMDeepSleepToActive(sram_index);
982 break;
983 }
984
985 case kPOWER_SRAMPwrDeepSleep:
986 { // Deep Sleep ---> Deep Sleep : there is nothing to do.
987 break;
988 }
989
990 default:
991 // Deep Sleep ---> Shut Down : FORBIDDEN (error)
992 // Deep Sleep ---> Light Sleep : FORBIDDEN (error)
993 return (kPOWER_Status_Fail);
994 } // switch( pwr_mode )
995
996 break;
997 }
998
999 case kPOWER_SRAMPwrShutDown:
1000 { // Shutdown
1001 switch (pwr_mode)
1002 {
1003 case kPOWER_SRAMPwrActive:
1004 { // Shutdown ---> Active
1005 POWER_SRAMShutDownToActive(sram_index);
1006 break;
1007 }
1008
1009 case kPOWER_SRAMPwrShutDown:
1010 { // Shutdown ---> Shut Down : there is nothing to do.
1011 break;
1012 }
1013
1014 default:
1015 // Shutdown ---> Deep Sleep : FORBIDDEN (error)
1016 // Shutdown ---> Light Sleep : FORBIDDEN (error)
1017 return (kPOWER_Status_Fail);
1018 } // switch( pwr_mode )
1019
1020 break;
1021 }
1022
1023 default:
1024 // Do nothing
1025 break;
1026 } // switch( current_pwr_mode )
1027 } // if ( (uint32_t)sram_inst & 0x1 )
1028
1029 // Move to next SRAM index
1030 sram_inst = (power_sram_bit_t)((uint32_t)((uint32_t)sram_inst >> 1));
1031 sram_index = (power_sram_index_t)((uint32_t)((uint32_t)sram_index + 1U));
1032 } // while ((uint32_t)sram_inst != 0 )
1033
1034 return (kPOWER_Status_Success);
1035 }
1036
1037 /**
1038 * @brief Configures and enters in SLEEP low power mode
1039 * @return Nothing
1040 */
POWER_EnterSleep(void)1041 void POWER_EnterSleep(void)
1042 {
1043 uint32_t pmsk;
1044 pmsk = __get_PRIMASK(); /* Save CORTEX-M33 interrupt configuration */
1045 __disable_irq(); /* Disable all interrupts */
1046 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; /* CORTEX-M33 uses "Sleep" mode */
1047 __WFI(); /* CORTEX-M33 enters "Sleep" mode */
1048 __set_PRIMASK(pmsk); /* Restore CORTEX-M33 interrupt configuration (after wake up) */
1049 }
1050
1051 /**
1052 * brief PMC Deep Sleep function call
1053 * return nothing
1054 */
POWER_EnterDeepSleep(uint32_t exclude_from_pd[2],uint32_t sram_retention_ctrl,uint32_t wakeup_interrupts[4],uint32_t hardware_wake_ctrl)1055 void POWER_EnterDeepSleep(uint32_t exclude_from_pd[2],
1056 uint32_t sram_retention_ctrl,
1057 uint32_t wakeup_interrupts[4],
1058 uint32_t hardware_wake_ctrl)
1059 {
1060 LPC_LOWPOWER_T lv_low_power_mode_cfg; /* Low Power Mode configuration structure */
1061 uint32_t pmc_reset_ctrl;
1062
1063 /* Clear Low Power Mode configuration variable */
1064 (void)memset(&lv_low_power_mode_cfg, 0x0, sizeof(LPC_LOWPOWER_T));
1065
1066 /* Configure Low Power Mode configuration variable */
1067 lv_low_power_mode_cfg.CFG = (uint32_t)LOWPOWER_CFG_LPMODE_DEEPSLEEP << LOWPOWER_CFG_LPMODE_INDEX; /* DEEPSLEEP mode */
1068
1069 /* Make sure LDO MEM & Analog references will stay powered, Shut down ROM & LDO Flash NV */
1070 lv_low_power_mode_cfg.PDCTRL[0] =
1071 (~exclude_from_pd[0] & ~(uint32_t)kPDRUNCFG_PD_LDOMEM & ~(uint32_t)kPDRUNCFG_PD_BIAS) | (uint32_t)kPDRUNCFG_PD_ROM | (uint32_t)kPDRUNCFG_PD_LDOFLASHNV;
1072 lv_low_power_mode_cfg.PDCTRL[1] = ~exclude_from_pd[1];
1073
1074 // Voltage control in DeepSleep Low Power Modes
1075 lv_low_power_mode_cfg.VOLTAGE = POWER_SetLdoAoLdoMemVoltage(LOWPOWER_CFG_LPMODE_DEEPSLEEP);
1076
1077 // SRAM retention control during DEEP-SLEEP
1078 lv_low_power_mode_cfg.SRAMRETCTRL = sram_retention_ctrl & (uint32_t)kPOWER_SRAM_DSLP_MASK;
1079
1080 /* Interrupts that allow DMA transfers with Flexcomm without waking up the Processor */
1081 if (0UL != (hardware_wake_ctrl & (LOWPOWER_HWWAKE_PERIPHERALS | LOWPOWER_HWWAKE_DMIC | LOWPOWER_HWWAKE_SDMA0 |
1082 LOWPOWER_HWWAKE_SDMA1 | LOWPOWER_HWWAKE_DAC)))
1083 {
1084 lv_low_power_mode_cfg.HWWAKE = (hardware_wake_ctrl & ~LOWPOWER_HWWAKE_FORCED) | LOWPOWER_HWWAKE_ENABLE_FRO192M;
1085 }
1086
1087 // @NOTE Niobe4mini: update with new BOD reset enable management
1088 pmc_reset_ctrl = PMC->RESETCTRL;
1089 if ((pmc_reset_ctrl & (PMC_RESETCTRL_BODCORERESETENA_SECURE_MASK | PMC_RESETCTRL_BODCORERESETENA_SECURE_DP_MASK)) ==
1090 ((0x1UL << PMC_RESETCTRL_BODCORERESETENA_SECURE_SHIFT) | (0x1UL << PMC_RESETCTRL_BODCORERESETENA_SECURE_DP_SHIFT)))
1091 {
1092 /* BoD CORE reset is activated, so make sure BoD Core and Biasing won't be shutdown */
1093 lv_low_power_mode_cfg.PDCTRL[0] &= ~(uint32_t)kPDRUNCFG_PD_BODCORE & ~(uint32_t)kPDRUNCFG_PD_BIAS;
1094 }
1095
1096 if ((pmc_reset_ctrl &
1097 (PMC_RESETCTRL_BODVDDMAINRESETENA_SECURE_MASK | PMC_RESETCTRL_BODVDDMAINRESETENA_SECURE_DP_MASK)) ==
1098 ((0x1UL << PMC_RESETCTRL_BODVDDMAINRESETENA_SECURE_SHIFT) |
1099 (0x1UL << PMC_RESETCTRL_BODVDDMAINRESETENA_SECURE_DP_SHIFT)))
1100 {
1101 /* BoD VDDMAIN reset is activated, so make sure BoD VDDMAIN and Biasing won't be shutdown */
1102 lv_low_power_mode_cfg.PDCTRL[0] &= ~(uint32_t)kPDRUNCFG_PD_BODVDDMAIN & ~(uint32_t)kPDRUNCFG_PD_BIAS;
1103 }
1104
1105 /* CPU Wake up & Interrupt sources control */
1106 lv_low_power_mode_cfg.WAKEUPSRC[0] = lv_low_power_mode_cfg.WAKEUPINT[0] = wakeup_interrupts[0];
1107 lv_low_power_mode_cfg.WAKEUPSRC[1] = lv_low_power_mode_cfg.WAKEUPINT[1] = wakeup_interrupts[1];
1108 lv_low_power_mode_cfg.WAKEUPSRC[2] = lv_low_power_mode_cfg.WAKEUPINT[2] = wakeup_interrupts[2];
1109 lv_low_power_mode_cfg.WAKEUPSRC[3] = lv_low_power_mode_cfg.WAKEUPINT[3] = wakeup_interrupts[3];
1110
1111 /* Enter low power mode */
1112 POWER_SetLowPowerMode(&lv_low_power_mode_cfg);
1113 }
1114
1115 /**
1116 * brief PMC power Down function call
1117 * return nothing
1118 */
POWER_EnterPowerDown(uint32_t exclude_from_pd[1],uint32_t sram_retention_ctrl,uint32_t wakeup_interrupts[4],uint32_t cpu_retention_addr)1119 void POWER_EnterPowerDown(uint32_t exclude_from_pd[1],
1120 uint32_t sram_retention_ctrl,
1121 uint32_t wakeup_interrupts[4],
1122 uint32_t cpu_retention_addr)
1123 {
1124 LPC_LOWPOWER_T lv_low_power_mode_cfg; /* Low Power Mode configuration structure */
1125
1126 // Clear Low Power Mode configuration variable
1127 (void)memset(&lv_low_power_mode_cfg, 0x0, sizeof(LPC_LOWPOWER_T));
1128
1129 // Configure Low Power Mode configuration variable : POWER DOWN mode
1130 lv_low_power_mode_cfg.CFG = (uint32_t)LOWPOWER_CFG_LPMODE_POWERDOWN << LOWPOWER_CFG_LPMODE_INDEX;
1131
1132 // Only FRO32K, XTAL32K, FRO1M, COMP, BIAS and VREF can stay powered during POWERDOWN.
1133 // LDO_MEM is enabled (because at least 1 SRAM instance will be required - for CPU state retention -)
1134 lv_low_power_mode_cfg.PDCTRL[0] = ~(exclude_from_pd[0] | (uint32_t)kPDRUNCFG_PD_LDOMEM);
1135 lv_low_power_mode_cfg.PDCTRL[1] = 0xFFFFFFFFUL;
1136
1137 // Force Bias activation if Analog Comparator is required, otherwise, disable it.
1138 if ((lv_low_power_mode_cfg.PDCTRL[0] & (uint32_t)kPDRUNCFG_PD_COMP) == 0UL)
1139 {
1140 // Analog Comparator is required du ring power-down: Enable Biasing
1141 lv_low_power_mode_cfg.PDCTRL[0] = lv_low_power_mode_cfg.PDCTRL[0] & (~(uint32_t)kPDRUNCFG_PD_BIAS);
1142 }
1143 else
1144 {
1145 // Analog Comparator is not required du ring power-down: Disable Biasing
1146 lv_low_power_mode_cfg.PDCTRL[0] = lv_low_power_mode_cfg.PDCTRL[0] | (uint32_t)kPDRUNCFG_PD_BIAS;
1147 }
1148
1149 // SRAM retention control during POWER-DOWN
1150
1151 // Depending on where the user wants to locate the CPU state retention data,
1152 // the associated SRAM instance will be automatically put in retention mode.
1153 // The boundaries are defined in such a way that the area where the CPU state
1154 // will be retained does not cross any SRAM instance boundary.
1155 // Per hardware design, 1540 bytes are necessary to store the whole CPU state
1156 #define RAM_00_CPU_RET_ADDR_MIN 0x20000000UL // RAM_00 start address
1157 #define RAM_00_CPU_RET_ADDR_MAX 0x200009FCUL // RAM_00 start address + 1540 - 1
1158 #define RAM_01_CPU_RET_ADDR_MIN 0x20001000UL // RAM_01 start address
1159 #define RAM_01_CPU_RET_ADDR_MAX 0x200019FCUL // RAM_01 start address + 1540 - 1
1160 #define RAM_02_CPU_RET_ADDR_MIN 0x20002000UL // RAM_02 start address
1161 #define RAM_02_CPU_RET_ADDR_MAX 0x200029FCUL // RAM_02 start address + 1540 - 1
1162 #define RAM_03_CPU_RET_ADDR_MIN 0x20003000UL // RAM_03 start address
1163 #define RAM_03_CPU_RET_ADDR_MAX 0x200039FCUL // RAM_03 start address + 1540 - 1
1164
1165 if ((cpu_retention_addr >= RAM_00_CPU_RET_ADDR_MIN) && (cpu_retention_addr <= RAM_00_CPU_RET_ADDR_MAX))
1166 {
1167 // Inside RAM_00
1168 sram_retention_ctrl |= (uint32_t)kPOWER_SRAM_RAM_00;
1169 }
1170 else
1171 {
1172 if ((cpu_retention_addr >= RAM_01_CPU_RET_ADDR_MIN) && (cpu_retention_addr <= RAM_01_CPU_RET_ADDR_MAX))
1173 {
1174 // Inside RAM_01
1175 sram_retention_ctrl |= (uint32_t)kPOWER_SRAM_RAM_01;
1176 }
1177 else
1178 {
1179 if ((cpu_retention_addr >= RAM_02_CPU_RET_ADDR_MIN) && (cpu_retention_addr <= RAM_02_CPU_RET_ADDR_MAX))
1180 {
1181 // Inside RAM_02
1182 sram_retention_ctrl |= (uint32_t)kPOWER_SRAM_RAM_02;
1183 }
1184 else
1185 {
1186 if ((cpu_retention_addr >= RAM_03_CPU_RET_ADDR_MIN) && (cpu_retention_addr <= RAM_03_CPU_RET_ADDR_MAX))
1187 {
1188 // Inside RAM_03
1189 sram_retention_ctrl |= (uint32_t)kPOWER_SRAM_RAM_03;
1190 }
1191 else
1192 {
1193 // Error! Therefore, we locate the retention area in RAM_00
1194 cpu_retention_addr = 0x20000000UL;
1195 sram_retention_ctrl |= (uint32_t)kPOWER_SRAM_RAM_00;
1196 }
1197 }
1198 }
1199 }
1200
1201 lv_low_power_mode_cfg.SRAMRETCTRL = sram_retention_ctrl & (uint32_t)kPOWER_SRAM_PDWN_MASK;
1202
1203 // Voltage control in Low Power Modes
1204 // The Memories Voltage settings below are for voltage scaling
1205 lv_low_power_mode_cfg.VOLTAGE = POWER_SetLdoAoLdoMemVoltage(LOWPOWER_CFG_LPMODE_POWERDOWN);
1206
1207 /* CPU0 retention Address */
1208 lv_low_power_mode_cfg.CPURETCTRL = ((cpu_retention_addr >> 1) | LOWPOWER_CPURETCTRL_ENA_MASK) &
1209 (LOWPOWER_CPURETCTRL_MEMBASE_MASK | LOWPOWER_CPURETCTRL_ENA_MASK);
1210
1211 /* CPU Wake up & Interrupt sources control */
1212 lv_low_power_mode_cfg.WAKEUPSRC[0] = lv_low_power_mode_cfg.WAKEUPINT[0] =
1213 wakeup_interrupts[0] & (WAKEUP_GPIO_GLOBALINT0 | WAKEUP_GPIO_GLOBALINT1 | WAKEUP_FLEXCOMM3 | WAKEUP_ACMP |
1214 WAKEUP_RTC_ALARM_WAKEUP | WAKEUP_WAKEUP_MAILBOX);
1215 lv_low_power_mode_cfg.WAKEUPSRC[1] = lv_low_power_mode_cfg.WAKEUPINT[1] =
1216 wakeup_interrupts[1] & WAKEUP_OS_EVENT_TIMER;
1217 lv_low_power_mode_cfg.WAKEUPSRC[2] = lv_low_power_mode_cfg.WAKEUPINT[2] = 0UL;
1218 lv_low_power_mode_cfg.WAKEUPSRC[3] = lv_low_power_mode_cfg.WAKEUPINT[3] = wakeup_interrupts[3] & WAKEUP_ITRC;
1219
1220 /* Enter low power mode */
1221 POWER_SetLowPowerMode(&lv_low_power_mode_cfg);
1222 }
1223
1224 /**
1225 * brief PMC Deep Power-Down function call
1226 * return nothing
1227 */
POWER_EnterDeepPowerDown(uint32_t exclude_from_pd[1],uint32_t sram_retention_ctrl,uint32_t wakeup_interrupts[2],uint32_t wakeup_io_ctrl)1228 void POWER_EnterDeepPowerDown(uint32_t exclude_from_pd[1],
1229 uint32_t sram_retention_ctrl,
1230 uint32_t wakeup_interrupts[2],
1231 uint32_t wakeup_io_ctrl)
1232 {
1233 LPC_LOWPOWER_T lv_low_power_mode_cfg; /* Low Power Mode configuration structure */
1234
1235 // Clear Low Power Mode configuration variable
1236 (void)memset(&lv_low_power_mode_cfg, 0x0, sizeof(LPC_LOWPOWER_T));
1237
1238 // Configure Low Power Mode configuration variable : DEEP POWER-DOWN mode
1239 lv_low_power_mode_cfg.CFG = (uint32_t)LOWPOWER_CFG_LPMODE_DEEPPOWERDOWN << LOWPOWER_CFG_LPMODE_INDEX;
1240
1241 // Note: only FRO32K, XTAL32K, FRO1M and LDO_MEM can stay powered during DEEP POWER-DOWN
1242 lv_low_power_mode_cfg.PDCTRL[0] = ~exclude_from_pd[0];
1243 lv_low_power_mode_cfg.PDCTRL[1] = 0xFFFFFFFFUL;
1244
1245 // SRAM retention control during DEEP POWER-DOWN
1246 // RAM_X0, RAM_02 and RAM_03 excluded: they are used by ROM Boot code
1247 sram_retention_ctrl = sram_retention_ctrl & (uint32_t)kPOWER_SRAM_DPWD_MASK;
1248 lv_low_power_mode_cfg.SRAMRETCTRL = sram_retention_ctrl;
1249
1250 // Sanity check: if retention is required for any SRAM instance other than RAM_00, make sure LDO MEM will stay
1251 // powered */
1252 if ((sram_retention_ctrl & (~(uint32_t)kPOWER_SRAM_RAM_00)) != 0UL)
1253 {
1254 // SRAM retention is required : enable LDO_MEM
1255 lv_low_power_mode_cfg.PDCTRL[0] &= ~(uint32_t)kPDRUNCFG_PD_LDOMEM;
1256 }
1257 else
1258 {
1259 // No SRAM retention required : disable LDO_MEM
1260 lv_low_power_mode_cfg.PDCTRL[0] |= (uint32_t)kPDRUNCFG_PD_LDOMEM;
1261 }
1262
1263 // Voltage control in Low Power Modes
1264 // The Memories Voltage settings below are for voltage scaling
1265 lv_low_power_mode_cfg.VOLTAGE = POWER_SetLdoAoLdoMemVoltage(LOWPOWER_CFG_LPMODE_DEEPPOWERDOWN);
1266
1267 // Wake up sources control
1268 lv_low_power_mode_cfg.WAKEUPSRC[0] = lv_low_power_mode_cfg.WAKEUPINT[0] =
1269 wakeup_interrupts[0] &
1270 WAKEUP_RTC_ALARM_WAKEUP; /* CPU Wake up sources control : only WAKEUP_RTC_LITE_ALARM_WAKEUP */
1271 lv_low_power_mode_cfg.WAKEUPSRC[1] = lv_low_power_mode_cfg.WAKEUPINT[1] =
1272 wakeup_interrupts[1] & WAKEUP_OS_EVENT_TIMER; /* CPU Wake up sources control : only WAKEUP_OS_EVENT_TIMER */
1273 lv_low_power_mode_cfg.WAKEUPSRC[2] = lv_low_power_mode_cfg.WAKEUPINT[2] = 0UL;
1274 lv_low_power_mode_cfg.WAKEUPSRC[3] = lv_low_power_mode_cfg.WAKEUPINT[3] = 0UL;
1275
1276 /* Wake up I/O sources */
1277 lv_low_power_mode_cfg.WAKEUPIOSRC = POWER_WakeUpIOCtrl(wakeup_io_ctrl);
1278
1279 /* Enter low power mode */
1280 POWER_SetLowPowerMode(&lv_low_power_mode_cfg);
1281
1282 /*** We'll reach this point ONLY and ONLY if the DEEPPOWERDOWN has not been taken (for instance because an RTC or
1283 * OSTIMER interrupt is pending) ***/
1284 }
1285
1286 /**
1287 * @brief Configures the 5 wake-up pins to wake up the part in DEEP-SLEEP and POWER-DOWN low power modes.
1288 * @param wakeup_io_cfg_src : for all wake-up pins : indicates if the config is from IOCON or from PMC.
1289 * @param wakeup_io_ctrl: the 5 wake-up pins configurations (see "LOWPOWER_WAKEUPIOSRC_*" definition)
1290
1291 * @return Nothing
1292 *
1293 * !!! IMPORTANT NOTES :
1294 * 1 - To be called just before POWER_EnterDeepSleep() or POWER_EnterPowerDown().
1295 */
1296 /**
1297 * brief PMC Deep Power-Down function call
1298 * return nothing
1299 */
POWER_SetWakeUpPins(uint32_t wakeup_io_cfg_src,uint32_t wakeup_io_ctrl)1300 void POWER_SetWakeUpPins(uint32_t wakeup_io_cfg_src, uint32_t wakeup_io_ctrl)
1301 {
1302 if (wakeup_io_cfg_src == (uint32_t)LOWPOWER_WAKEUPIO_CFG_SRC_IOCON)
1303 {
1304 /* All wake-up pins controls are coming from IOCON */
1305
1306 wakeup_io_ctrl = wakeup_io_ctrl | LOWPOWER_WAKEUPIO_PIO0_DISABLEPULLUPDOWN_MASK |
1307 LOWPOWER_WAKEUPIO_PIO1_DISABLEPULLUPDOWN_MASK | LOWPOWER_WAKEUPIO_PIO2_DISABLEPULLUPDOWN_MASK |
1308 LOWPOWER_WAKEUPIO_PIO3_DISABLEPULLUPDOWN_MASK |
1309 LOWPOWER_WAKEUPIO_PIO4_DISABLEPULLUPDOWN_MASK; /* Make sure IOCON is not modified inside
1310 POWER_WakeUpIOCtrl */
1311
1312 PMC->WAKEUPIOCTRL = POWER_WakeUpIOCtrl(wakeup_io_ctrl) & (~PMC_WAKEUPIOCTRL_WAKEUPIO_ENABLE_CTRL_MASK);
1313 }
1314 else
1315 {
1316 /* All wake-up pins controls are coming from PMC */
1317 PMC->WAKEUPIOCTRL = POWER_WakeUpIOCtrl(wakeup_io_ctrl) | PMC_WAKEUPIOCTRL_WAKEUPIO_ENABLE_CTRL_MASK;
1318 }
1319
1320 /* Release Wake up I/O reset (WAKEUPIO_RSTN = 1)*/
1321 PMC->WAKEUPIOCTRL |= PMC_WAKEUPIOCTRL_WAKEUPIO_RSTN_MASK;
1322 }
1323
POWER_GetWakeUpCause(power_reset_cause_t * reset_cause,power_boot_mode_t * boot_mode,power_wakeup_pin_t * wakeup_pin_cause)1324 void POWER_GetWakeUpCause(power_reset_cause_t *reset_cause,
1325 power_boot_mode_t *boot_mode,
1326 power_wakeup_pin_t *wakeup_pin_cause)
1327 {
1328 uint32_t reset_cause_reg;
1329 uint32_t boot_mode_reg;
1330 uint32_t wakeupio_cause_reg;
1331
1332 boot_mode_reg = (PMC->STATUS & PMC_STATUS_BOOTMODE_MASK) >> PMC_STATUS_BOOTMODE_SHIFT;
1333
1334 switch (boot_mode_reg)
1335 {
1336 case 1:
1337 /* DEEP-SLEEP */
1338 *boot_mode = kBOOT_MODE_LP_DEEP_SLEEP;
1339 break;
1340 case 2:
1341 /* POWER-DOWN */
1342 *boot_mode = kBOOT_MODE_LP_POWER_DOWN;
1343 break;
1344 case 3:
1345 /* DEEP-POWER-DOWN */
1346 *boot_mode = kBOOT_MODE_LP_DEEP_POWER_DOWN;
1347 break;
1348 default:
1349 /* All non Low Power Mode wake-up */
1350 *boot_mode = kBOOT_MODE_POWER_UP;
1351 break;
1352 }
1353
1354 wakeupio_cause_reg = PMC->WAKEIOCAUSE;
1355
1356 if (boot_mode_reg == 0UL)
1357 {
1358 /* POWER-UP: Power On Reset, Pin reset, Brown Out Detectors, Software Reset:
1359 * PMC has been reset, so wake up pin event not expected to have happened. */
1360 *wakeup_pin_cause = kWAKEUP_PIN_NONE;
1361 }
1362 else
1363 {
1364 switch (((wakeupio_cause_reg & PMC_WAKEIOCAUSE_WAKEUPIO_EVENTS_ORDER_MASK) >>
1365 PMC_WAKEIOCAUSE_WAKEUPIO_EVENTS_ORDER_SHIFT))
1366 {
1367 case 0x0:
1368 *wakeup_pin_cause = kWAKEUP_PIN_NONE;
1369 break;
1370 case 0x1:
1371 *wakeup_pin_cause = kWAKEUP_PIN_0;
1372 break;
1373 case 0x2:
1374 *wakeup_pin_cause = kWAKEUP_PIN_1;
1375 break;
1376 case 0x4:
1377 *wakeup_pin_cause = kWAKEUP_PIN_2;
1378 break;
1379 case 0x8:
1380 *wakeup_pin_cause = kWAKEUP_PIN_3;
1381 break;
1382 case 0x10:
1383 *wakeup_pin_cause = kWAKEUP_PIN_4;
1384 break;
1385 default:
1386 /* Mutiple */
1387 *wakeup_pin_cause = kWAKEUP_PIN_MULTIPLE;
1388 break;
1389 }
1390 }
1391
1392 reset_cause_reg = PMC->AOREG1;
1393
1394 /*
1395 * Prioritize interrupts source with respect to how critical they are.
1396 */
1397 if (0U != (reset_cause_reg & PMC_AOREG1_CDOGRESET_MASK))
1398 { /* Code Watchdog Reset */
1399 *reset_cause = kRESET_CAUSE_CDOGRESET;
1400 }
1401 else
1402 {
1403 if (0UL != (reset_cause_reg & PMC_AOREG1_WDTRESET_MASK))
1404 { /* Watchdog Timer Reset */
1405 *reset_cause = kRESET_CAUSE_WDTRESET;
1406 }
1407 else
1408 {
1409 if (0U != (reset_cause_reg & PMC_AOREG1_SYSTEMRESET_MASK))
1410 { /* ARM System Reset */
1411 *reset_cause = kRESET_CAUSE_ARMSYSTEMRESET;
1412 }
1413 else
1414 {
1415 if (boot_mode_reg != 3UL) /* POWER-UP: Power On Reset, Pin reset, Brown Out Detectors, Software Reset,
1416 DEEP-SLEEP and POWER-DOWN */
1417 {
1418 /*
1419 * Prioritise Reset causes, starting from the strongest (Power On Reset)
1420 */
1421 if (0U != (reset_cause_reg & PMC_AOREG1_POR_MASK))
1422 { /* Power On Reset */
1423 *reset_cause = kRESET_CAUSE_POR;
1424 }
1425 else
1426 {
1427 if (0U != (reset_cause_reg & PMC_AOREG1_BODRESET_MASK))
1428 { /* Brown-out Detector reset (either BODVBAT or BODCORE) */
1429 *reset_cause = kRESET_CAUSE_BODRESET;
1430 }
1431 else
1432 {
1433 if (0U != (reset_cause_reg & PMC_AOREG1_PADRESET_MASK))
1434 { /* Hardware Pin Reset */
1435 *reset_cause = kRESET_CAUSE_PADRESET;
1436 }
1437 else
1438 {
1439 if (0U != (reset_cause_reg & PMC_AOREG1_SWRRESET_MASK))
1440 { /* Software triggered Reset */
1441 *reset_cause = kRESET_CAUSE_SWRRESET;
1442 }
1443 else
1444 { /* Unknown Reset Cause (shall never occur) */
1445 *reset_cause = kRESET_CAUSE_NOT_DETERMINISTIC;
1446 }
1447 }
1448 }
1449 }
1450 }
1451 else /* boot_mode_reg == 3 : DEEP-POWER-DOWN */
1452 {
1453 switch (((reset_cause_reg & PMC_AOREG1_DPD_EVENTS_ORDER_MASK) >> PMC_AOREG1_DPD_EVENTS_ORDER_SHIFT))
1454 {
1455 case 1:
1456 *reset_cause = kRESET_CAUSE_DPDRESET_WAKEUPIO;
1457 break;
1458 case 2:
1459 *reset_cause = kRESET_CAUSE_DPDRESET_RTC;
1460 break;
1461 case 3:
1462 *reset_cause = kRESET_CAUSE_DPDRESET_WAKEUPIO_RTC;
1463 break;
1464 case 4:
1465 *reset_cause = kRESET_CAUSE_DPDRESET_OSTIMER;
1466 break;
1467 case 5:
1468 *reset_cause = kRESET_CAUSE_DPDRESET_WAKEUPIO_OSTIMER;
1469 break;
1470 case 6:
1471 *reset_cause = kRESET_CAUSE_DPDRESET_RTC_OSTIMER;
1472 break;
1473 case 7:
1474 *reset_cause = kRESET_CAUSE_DPDRESET_WAKEUPIO_RTC_OSTIMER;
1475 break;
1476 default:
1477 /* Unknown Reset Cause (shall not occur) */
1478 *reset_cause = kRESET_CAUSE_NOT_DETERMINISTIC;
1479 break;
1480 }
1481 } // if ( boot_mode != 3 )
1482
1483 } // if ( reset_cause_reg & PMC_AOREG1_CDOGRESET_MASK )
1484
1485 } // if ( reset_cause_reg & PMC_AOREG1_WDTRESET_MASK )
1486
1487 } // if ( reset_cause_reg & PMC_AOREG1_SYSTEMRESET_MASK )
1488 }
1489
1490 /**
1491 * @brief Described in fsl_common.h
1492 * @param
1493 * @return
1494 */
POWER_SetVoltageForFreq(uint32_t system_freq_hz)1495 void POWER_SetVoltageForFreq(uint32_t system_freq_hz)
1496 {
1497 if (system_freq_hz <= DCDC_POWER_PROFILE_LOW_MAX_FREQ_HZ)
1498 {
1499 /* [0 Hz - DCDC_POWER_PROFILE_LOW_MAX_FREQ_HZ Hz] */
1500 POWER_SetSystemPowerProfile(V_SYSTEM_POWER_PROFILE_LOW);
1501 POWER_SetVoltageForProcess(V_SYSTEM_POWER_PROFILE_LOW);
1502 }
1503 else
1504 {
1505 if (system_freq_hz <= DCDC_POWER_PROFILE_MEDIUM_MAX_FREQ_HZ)
1506 {
1507 /* ]DCDC_POWER_PROFILE_LOW_MAX_FREQ_HZ Hz - DCDC_POWER_PROFILE_MEDIUM_MAX_FREQ_HZ Hz] */
1508 POWER_SetSystemPowerProfile(V_SYSTEM_POWER_PROFILE_MEDIUM);
1509 POWER_SetVoltageForProcess(V_SYSTEM_POWER_PROFILE_MEDIUM);
1510 }
1511 else
1512 {
1513 /* > DCDC_POWER_PROFILE_MEDIUM_MAX_FREQ_HZ Hz */
1514 POWER_SetSystemPowerProfile(V_SYSTEM_POWER_PROFILE_HIGH);
1515 POWER_SetVoltageForProcess(V_SYSTEM_POWER_PROFILE_HIGH);
1516 }
1517 }
1518
1519 /* Update BoD Core */
1520 if (0UL == Chip_GetVersion())
1521 {
1522 /* 0A */
1523 if (system_freq_hz <= 135000000U)
1524 {
1525 PMC->BODCORE = (PMC->BODCORE & ~PMC_BODCORE_HYST_MASK & ~PMC_BODCORE_TRIGLVL_MASK) |
1526 PMC_BODCORE_HYST(kPOWER_BodHystLevel50mv) | PMC_BODCORE_TRIGLVL(kPOWER_BodCoreLevel0A900mv);
1527 }
1528 else
1529 {
1530 PMC->BODCORE = (PMC->BODCORE & ~PMC_BODCORE_HYST_MASK & ~PMC_BODCORE_TRIGLVL_MASK) |
1531 PMC_BODCORE_HYST(kPOWER_BodHystLevel25mv) | PMC_BODCORE_TRIGLVL(kPOWER_BodCoreLevel0A950mv);
1532 }
1533 }
1534 else
1535 {
1536 /* 1B */
1537 if (system_freq_hz < 100000000U)
1538 {
1539 PMC->BODCORE = (PMC->BODCORE & ~PMC_BODCORE_HYST_MASK & ~PMC_BODCORE_TRIGLVL_MASK) |
1540 PMC_BODCORE_HYST(kPOWER_BodHystLevel75mv) | PMC_BODCORE_TRIGLVL(kPOWER_BodCoreLevel1B929mv);
1541 }
1542 else if (system_freq_hz <= 135000000U)
1543 {
1544 PMC->BODCORE = (PMC->BODCORE & ~PMC_BODCORE_HYST_MASK & ~PMC_BODCORE_TRIGLVL_MASK) |
1545 PMC_BODCORE_HYST(kPOWER_BodHystLevel50mv) | PMC_BODCORE_TRIGLVL(kPOWER_BodCoreLevel1B984mv);
1546 }
1547 else
1548 {
1549 PMC->BODCORE = (PMC->BODCORE & ~PMC_BODCORE_HYST_MASK & ~PMC_BODCORE_TRIGLVL_MASK) |
1550 PMC_BODCORE_HYST(kPOWER_BodHystLevel25mv) | PMC_BODCORE_TRIGLVL(kPOWER_BodCoreLevel1B1038mv);
1551 }
1552 }
1553 }
1554
1555 /**
1556 * @brief Wait at least 2us.
1557 * @param None
1558 * @return Nothing
1559 */
1560
POWER_WaitLDOCoreInit(void)1561 static void POWER_WaitLDOCoreInit(void)
1562 {
1563 /*
1564 * Note: Once LDO_CORE High Power Mode has been enabled,
1565 * at least 2us are required before one can reliabily sample
1566 * the LDO Low Voltage Detectore Output.
1567 * The PMC clock being 12 MHz, with at least 5 dummy read
1568 * operations, it is guaranteed by design that, whatever the
1569 * System/CPU clock frequency (up to 200 MHz).
1570 */
1571
1572 volatile uint32_t reg_data;
1573 for (int i = 0; i < 5; i++)
1574 {
1575 reg_data = PMC->STATUSPWR; /* Dummy Read */
1576 }
1577 (void)reg_data;
1578 }
1579
1580 /**
1581 * @brief Wait at least 2us.
1582 * @param None
1583 * @return Nothing
1584 */
1585
POWER_SRAMPowerUpDelay(void)1586 static void POWER_SRAMPowerUpDelay(void)
1587 {
1588 /*
1589 * Note: Wait about 1 us
1590 * The PMC clock being 12 MHz, with at least 3 dummy read
1591 * operations, it is guaranteed by design that when this ,
1592 * function is called, at least 1 us will elapse,
1593 * whatever the System/CPU clock frequency (up to 200 MHz).
1594 */
1595
1596 volatile uint32_t reg_data;
1597 for (int i = 0; i < 3; i++)
1598 {
1599 reg_data = PMC->STATUSPWR; /* Dummy Read */
1600 }
1601 (void)reg_data;
1602 }
1603
1604 /**
1605 * @brief Shut off the Flash and execute the _WFI(), then power up the Flash after wake-up event
1606 * @param None
1607 * @return Nothing
1608 */
1609
POWER_PowerCycleCpu(void)1610 static void POWER_PowerCycleCpu(void)
1611 {
1612 /* Switch System Clock to FRO12Mhz (the configuration before calling this function will not be restored back) */
1613 POWER_SetSystemClock12MHZ();
1614
1615 /* Configure the Cortex-M33 in Deep Sleep mode */
1616 SCB->SCR = SCB->SCR | SCB_SCR_SLEEPDEEP_Msk;
1617
1618 /* Enter in low power mode */
1619 __WFI();
1620
1621 /* Configure the Cortex-M33 in Active mode */
1622 SCB->SCR = SCB->SCR & (~SCB_SCR_SLEEPDEEP_Msk);
1623 };
1624
1625 /**
1626 * @brief Configures and enters in low power mode
1627 * @param : p_lowpower_cfg
1628 * @return Nothing
1629 */
POWER_SetLowPowerMode(LPC_LOWPOWER_T * p_lowpower_cfg)1630 static void POWER_SetLowPowerMode(LPC_LOWPOWER_T *p_lowpower_cfg)
1631 {
1632 uint32_t i, primask, reg_data;
1633 uint32_t cpu0_nmi_enable;
1634 uint32_t cpu0_int_enable[4];
1635 uint32_t analog_ctrl_regs[7]; /* To store Analog Controller Registers */
1636 uint32_t vref_regs[4]; /* To store VREF Registers */
1637 uint32_t fmccr_reg; /* FMC Configuration Register */
1638
1639 /* Save FMC configuration */
1640 fmccr_reg = SYSCON->FMCCR;
1641
1642 cpu0_nmi_enable = SYSCON->NMISRC & SYSCON_NMISRC_NMIENCPU0_MASK; /* Save the configuration of the NMI Register */
1643 SYSCON->NMISRC &= ~SYSCON_NMISRC_NMIENCPU0_MASK; /* Disable NMI of CPU0 */
1644
1645 // Save the configuration of the CPU interrupt enable Registers (because they are overwritten in
1646 // POWER_SetLowPowerMode)
1647 for (i = 0; i < 4U; i++)
1648 {
1649 cpu0_int_enable[i] = NVIC->ISER[i];
1650 }
1651
1652 uint32_t low_power_mode = (p_lowpower_cfg->CFG & LOWPOWER_CFG_LPMODE_MASK) >> LOWPOWER_CFG_LPMODE_INDEX;
1653
1654 /* Set the Low power mode.*/
1655 PMC->CTRL = (PMC->CTRL & (~PMC_CTRL_LPMODE_MASK)) | PMC_CTRL_LPMODE(low_power_mode);
1656
1657 /* SRAM in Retention modes */
1658 PMC->SRAMRETCTRL = p_lowpower_cfg->SRAMRETCTRL;
1659
1660 /* Configure the voltage level of the Always On domain, Memories LDO */
1661 PMC->LDOPMU = (PMC->LDOPMU & (~PMC_LDOPMU_VADJ_PWD_MASK) & (~PMC_LDOPMU_VADJ_BOOST_PWD_MASK)) |
1662 PMC_LDOPMU_VADJ_PWD((p_lowpower_cfg->VOLTAGE & LOWPOWER_VOLTAGE_LDO_PMU_MASK) >>
1663 LOWPOWER_VOLTAGE_LDO_PMU_INDEX) |
1664 PMC_LDOPMU_VADJ_BOOST_PWD((p_lowpower_cfg->VOLTAGE & LOWPOWER_VOLTAGE_LDO_PMU_BOOST_MASK) >>
1665 LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX);
1666
1667 PMC->LDOMEM = (PMC->LDOMEM & (~PMC_LDOMEM_VADJ_PWD_MASK) & (~PMC_LDOMEM_VADJ_BOOST_PWD_MASK)) |
1668 PMC_LDOMEM_VADJ_PWD((p_lowpower_cfg->VOLTAGE & LOWPOWER_VOLTAGE_LDO_MEM_MASK) >>
1669 LOWPOWER_VOLTAGE_LDO_MEM_INDEX) |
1670 PMC_LDOMEM_VADJ_BOOST_PWD((p_lowpower_cfg->VOLTAGE & LOWPOWER_VOLTAGE_LDO_MEM_BOOST_MASK) >>
1671 LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX);
1672
1673 /*
1674 * Enable wake up interrupt.
1675 * Rational : we enable each interrupt (NVIC->ISER) that can wake up the CPU here (before the __disable_irq()
1676 * below): Hence, if an interrupt was pending and not treated before (for any reason), the CPU will jump to that
1677 * interrupt handler before trying to enter the low power mode.
1678 * VERY IMPORTANT : Also, any interrupt set in NVIC->ISER, even though __disable_irq(), will make the CPU
1679 * go out of the Deep Sleep mode.
1680 */
1681 for (i = 0; i < 4U; i++)
1682 {
1683 NVIC->ISER[i] = p_lowpower_cfg->WAKEUPINT[i]; /* Enable wake-up interrupt */
1684 SYSCON->STARTER[i] = p_lowpower_cfg->WAKEUPSRC[i]; /* Enable wake-up sources */
1685 }
1686
1687 /* Save the configuration of the Priority Mask Register */
1688 primask = __get_PRIMASK();
1689
1690 switch (low_power_mode)
1691 {
1692 case LOWPOWER_CFG_LPMODE_DEEPSLEEP:
1693 {
1694 /* DEEP SLEEP power mode */
1695
1696 uint32_t bod_core_trglvl; /* BoD Core trigger level */
1697 uint32_t css_ctrl, syscon_css_clk_ctrl, syscon_css_clk_pclk_hclk;
1698 uint32_t syscon_autoclkgateoverride_reg; /* AUTOCLKGATEOVERRIDE Configuration Register */
1699
1700 /* Analog Modules to be shut off */
1701 PMC->PDSLEEPCFG0 = p_lowpower_cfg->PDCTRL[0];
1702 PMC->PDSLEEPCFG1 = p_lowpower_cfg->PDCTRL[1];
1703
1704 /* Saving AUTOCLKGATEOVERRIDE register*/
1705 syscon_autoclkgateoverride_reg = SYSCON->AUTOCLKGATEOVERRIDE;
1706
1707 /* DMA transactions with Flexcomm during DEEP SLEEP */
1708 SYSCON->HARDWARESLEEP = p_lowpower_cfg->HWWAKE;
1709 /* Enable autoclockgating on SDMA0 and SDMA1 during DeepSleep*/
1710 SYSCON->AUTOCLKGATEOVERRIDE =
1711 0xC0DE0000UL | (syscon_autoclkgateoverride_reg &
1712 (~(SYSCON_AUTOCLKGATEOVERRIDE_SDMA1_MASK | SYSCON_AUTOCLKGATEOVERRIDE_SDMA0_MASK)));
1713
1714 /* Make sure DEEP POWER DOWN reset is disabled */
1715 PMC->RESETCTRL = PMC->RESETCTRL & (~PMC_RESETCTRL_DPDWAKEUPRESETENABLE_MASK);
1716
1717 /* Adjust BoD Core Trip point . Currently set to 700 mV. TODO :: :: Check this value. */
1718 reg_data = PMC->BODCORE;
1719 bod_core_trglvl = (reg_data & PMC_BODCORE_TRIGLVL_MASK) >> PMC_BODCORE_TRIGLVL_SHIFT;
1720 PMC->BODCORE = (reg_data & (~PMC_BODCORE_TRIGLVL_MASK)) | PMC_BODCORE_TRIGLVL(kPOWER_BodCoreLevel0A700mv);
1721
1722 // CSSV2
1723 {
1724 syscon_css_clk_ctrl = SYSCON_CSS_CLK_CTRL_REG & (1U << 1);
1725
1726 css_ctrl = 0U;
1727
1728 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
1729 syscon_css_clk_pclk_hclk = SYSCON->AHBCLKCTRL2 & (0x1UL << 18);
1730 /* Check if CSS is NOT in reset AND is clocked and enable, to avoid deadlock situations or a hardfault
1731 */
1732 if ((0UL != (CSSV2_CTRL_REG & 0x1U)) && ((SYSCON->PRESETCTRL2 & 0x40000U) == 0UL) && (0UL != syscon_css_clk_pclk_hclk))
1733 #else
1734 syscon_css_clk_pclk_hclk = SYSCON->AHBCLKCTRL[2] & (0x1UL<< 18);
1735 /* Check if CSS is NOT in reset AND is clocked and enable, to avoid deadlock situations or a hardfault
1736 */
1737 if (((SYSCON->PRESETCTRL[2] & 0x40000U) == 0) && syscon_css_clk_pclk_hclk && (CSSV2_CTRL_REG & 0x1U))
1738 #endif
1739 {
1740 css_ctrl = CSSV2_CTRL_REG;
1741
1742 /* Wait until CSS is in idle state (CSS_STATUS_BUSY_MASK) */
1743 while (0UL != (CSSV2_STATUS_REG & 0x1UL))
1744 {
1745 }
1746
1747 /* Disable CSS */
1748 CSSV2_CTRL_REG = CSSV2_CTRL_REG & 0xFFFFFFFEU;
1749
1750 /* Swicth off i_css_clk/pclk/hclk */
1751 SYSCON->AHBCLKCTRLCLR[2] = ((uint32_t)1U << 18);
1752 }
1753
1754 /* Switch off DTRNG clocks */
1755 SYSCON_CSS_CLK_CTRL_CLR_REG = (1U << 1);
1756 }
1757
1758 /* Disable all IRQs */
1759 __disable_irq();
1760
1761 /*
1762 * - Switch PMC clock to 1 MHz,
1763 * - Set LDO_MEM as SRAM supply source during DEEP-SLEEP,
1764 * - Set LDO_CORE Low Power mode as Core supply source during DEEP-SLEEP,
1765 * - Select Core Logic supply source when waking up from DEEP-SLEEP.
1766 */
1767 reg_data = PMC->CTRL & (~PMC_CTRL_SELCLOCK_MASK) & (~PMC_CTRL_DEEPSLEEPCORESUPPLY_MASK) &
1768 (~PMC_CTRL_SELMEMSUPPLY_MASK);
1769 if (POWER_GetCorePowerSource() == kPOWER_CoreSrcDCDC)
1770 {
1771 /* Core Logic is supplied by DCDC Converter when waking up from DEEP-SLEEP */
1772 PMC->CTRL = reg_data & (~PMC_CTRL_SELCORESUPPLYWK_MASK);
1773 }
1774 else
1775 {
1776 /* Core Logic is supplied by LDO CORE (configured in High Power mode) when waking up from DEEP-SLEEP */
1777 PMC->CTRL = reg_data | PMC_CTRL_SELCORESUPPLYWK_MASK;
1778 }
1779
1780 /* _WFI() */
1781 POWER_PowerCycleCpu();
1782
1783 /* Switch PMC clock to 12 MHz and Configure the PMC in ACTIVE mode */
1784 PMC->CTRL = (PMC->CTRL & (~PMC_CTRL_LPMODE_MASK)) | PMC_CTRL_SELCLOCK_MASK |
1785 PMC_CTRL_LPMODE(LOWPOWER_CFG_LPMODE_ACTIVE);
1786
1787 /* Restore BoD Core Trip point. */
1788 PMC->BODCORE = (PMC->BODCORE & (~PMC_BODCORE_TRIGLVL_MASK)) | PMC_BODCORE_TRIGLVL(bod_core_trglvl);
1789
1790 // CSSV2
1791 {
1792 /* Restore i_css_clk/pclk/hclk */
1793 SYSCON->AHBCLKCTRLSET[2] = syscon_css_clk_pclk_hclk;
1794
1795 /* Restore DTRNG clocks */
1796 SYSCON_CSS_CLK_CTRL_SET_REG = syscon_css_clk_ctrl;
1797
1798 /* Check if CSS is NOT in reset AND is clocked, to avoid deadlock situations */
1799 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
1800 if (((SYSCON->PRESETCTRL2 & 0x40000U) == 0UL) && (0UL != syscon_css_clk_pclk_hclk) && (0UL != (css_ctrl & 0x1UL)))
1801 #else
1802 if (((SYSCON->PRESETCTRL[2] & 0x40000U) == 0UL) && (0UL != syscon_css_clk_pclk_hclk) && (0UL != (css_ctrl & 0x1UL)))
1803 #endif
1804 {
1805 /* Restore CSS */
1806 CSSV2_CTRL_REG = css_ctrl;
1807
1808 /* Wait until CSS is in idle state */
1809 while (0UL != (CSSV2_STATUS_REG & 0x1UL))
1810 {
1811 }
1812 }
1813 }
1814
1815 /* Restore AUTOCLKGATEOVERRIDE register*/
1816 SYSCON->AUTOCLKGATEOVERRIDE = 0xC0DE0000UL | syscon_autoclkgateoverride_reg;
1817
1818 /* Reset Sleep Postpone configuration */
1819 SYSCON->HARDWARESLEEP = 0;
1820
1821 break;
1822 }
1823
1824 case LOWPOWER_CFG_LPMODE_POWERDOWN:
1825 {
1826 uint32_t lpcac_ctrl_reg;
1827 uint32_t vref_rst_state;
1828 uint32_t vref_clk_state;
1829 uint32_t syscon_ahbclk_reg_0;
1830 uint32_t syscon_css_clk_ctrl, syscon_css_clk_pclk_hclk;
1831
1832 /* POWER DOWN power mode */
1833 power_core_pwr_source_t core_supply_source;
1834
1835 /* Only FRO32K, XTAL32K, FRO1M, COMP, BIAS, LDO_MEM and can VREF stay powered during POWERDOWN */
1836 PMC->PDSLEEPCFG0 =
1837 p_lowpower_cfg->PDCTRL[0] |
1838 (0xFFFFFFFFUL & (~((uint32_t)kPDRUNCFG_PD_FRO1M | (uint32_t)kPDRUNCFG_PD_FRO32K | (uint32_t)kPDRUNCFG_PD_XTAL32K | (uint32_t)kPDRUNCFG_PD_COMP |
1839 (uint32_t)kPDRUNCFG_PD_BIAS | (uint32_t)kPDRUNCFG_PD_LDOMEM | (uint32_t)kPDRUNCFG_PD_VREF)));
1840 PMC->PDSLEEPCFG1 = p_lowpower_cfg->PDCTRL[1];
1841
1842 /* Make sure DEEP POWER DOWN reset is disabled */
1843 PMC->RESETCTRL = PMC->RESETCTRL & (~PMC_RESETCTRL_DPDWAKEUPRESETENABLE_MASK);
1844
1845 /* Enable VREF Module (reset & clock) */
1846 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
1847 vref_rst_state = (SYSCON->PRESETCTRL3) & SYSCON_PRESETCTRL3_VREF_RST_MASK;
1848 vref_clk_state = (SYSCON->AHBCLKCTRL3) & SYSCON_AHBCLKCTRL3_VREF_MASK;
1849 SYSCON->PRESETCTRLCLR[3] = SYSCON_PRESETCTRL3_VREF_RST_MASK;
1850 SYSCON->AHBCLKCTRLSET[3] = SYSCON_AHBCLKCTRL3_VREF_MASK;
1851 #else
1852 vref_rst_state = (*(uint32_t *)(((uint32_t *)SYSCON->RESERVED_5))) & 0x40000UL;
1853 vref_clk_state = (*(uint32_t *)(((uint32_t *)SYSCON->RESERVED_9))) & 0x40000UL;
1854 *(uint32_t *)(((uint32_t *)SYSCON->RESERVED_7)) = 0x40000UL;
1855 *(uint32_t *)(((uint32_t *)SYSCON->RESERVED_10)) = 0x40000UL;
1856 #endif
1857
1858 /* Save VREF Module User Configuration ... */
1859 vref_regs[0] = VREF->CSR;
1860 vref_regs[1] = VREF->UTRIM;
1861 /* Save VREF Module Factory Trimmings ... */
1862 VREF->TEST_UNLOCK = 0x5AA5UL << 1; /* TEST_UNLOCK. Required before writting TRIM0 & TRIM1 */
1863 vref_regs[2] = VREF->TRIM0;
1864 vref_regs[3] = VREF->TRIM1;
1865
1866 /* ... then enable VREF Module isolation */
1867 PMC->MISCCTRL = PMC->MISCCTRL | PMC_MISCCTRL_VREF_ISO_MASK;
1868
1869 // CSSV2
1870 {
1871 syscon_css_clk_ctrl = SYSCON_CSS_CLK_CTRL_REG & (1U << 1);
1872 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
1873 syscon_css_clk_pclk_hclk = SYSCON->AHBCLKCTRL2 & ((uint32_t)1U << 18);
1874 #else
1875 syscon_css_clk_pclk_hclk = SYSCON->AHBCLKCTRL[2] & ((uint32_t)1U << 18);
1876 #endif
1877
1878 /* Switch off DTRNG clocks */
1879 SYSCON_CSS_CLK_CTRL_CLR_REG = (1U << 1);
1880
1881 /* Swicth off i_css_clk/pclk/hclk */
1882 SYSCON->AHBCLKCTRLCLR[2] = ((uint32_t)1U << 18);
1883 }
1884
1885 /* CPU0 Retention */
1886 SYSCON->FUNCRETENTIONCTRL =
1887 (SYSCON->FUNCRETENTIONCTRL & SYSCON_FUNCRETENTIONCTRL_RET_LENTH_MASK) | p_lowpower_cfg->CPURETCTRL;
1888
1889 /* Disable all IRQs */
1890 __disable_irq();
1891
1892 /*
1893 * From here :
1894 * 1 - If an interrupt that is enable occurs, the _WFI instruction will not be executed and we won't enter
1895 * in POWER DOWN. 2 - If an interrupt that is not enable occurs, there is no consequence neither on the
1896 * execution of the low power mode nor on the behaviour of the CPU.
1897 */
1898
1899 /* Switch PMC clock to 1 MHz and select LDO CORE (configured in High Power mode) as Core Logic supply source
1900 * when waking up from POWER-DOWN */
1901 PMC->CTRL = (PMC->CTRL & (~PMC_CTRL_SELCLOCK_MASK)) | PMC_CTRL_SELCORESUPPLYWK_MASK;
1902
1903 /* Save user Core Supply Source configuration */
1904 core_supply_source = POWER_GetCorePowerSource();
1905
1906 /* Store Analog Controller Registers */
1907 analog_ctrl_regs[0] = ANACTRL->FRO192M_CTRL;
1908 analog_ctrl_regs[1] = ANACTRL->ANALOG_CTRL_CFG;
1909 analog_ctrl_regs[2] = ANACTRL->ADC_CTRL;
1910 analog_ctrl_regs[3] = ANACTRL->XO32M_CTRL;
1911 analog_ctrl_regs[4] = ANACTRL->BOD_DCDC_INT_CTRL;
1912 analog_ctrl_regs[5] = ANACTRL->LDO_XO32M;
1913 analog_ctrl_regs[6] = ANACTRL->OSC_TESTBUS;
1914
1915 /* Save Flash Cache settings, then disable and clear it */
1916 lpcac_ctrl_reg = SYSCON->LPCAC_CTRL;
1917 SYSCON->LPCAC_CTRL = 0x3; /* dis_lpcac = '1', clr_lpcac = '1' */
1918
1919 /* Save ROM clock setting, then enable it.
1920 * It is important to have the ROM clock running before entering
1921 * POWER-DOWN for the following two reasons:
1922 * 1 - In case of POWER-DOWN with CPU state retention (which is the only
1923 * option currently offered to the user), some flip-flops that depend
1924 on this clock need to be saved.
1925 * 2 - In case of POWER-DOWN without CPU state retention (which is a
1926 * hardware feature that is NOT offered to the user for the time being)
1927 * CPU reboot cannot occur if ROM clock has been shut down.
1928 */
1929 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
1930 syscon_ahbclk_reg_0 = SYSCON->AHBCLKCTRL0;
1931 SYSCON->AHBCLKCTRLSET[0] = SYSCON_AHBCLKCTRL0_ROM_MASK; /* Enable the clock for ROM */
1932 #else
1933 syscon_ahbclk_reg_0 = SYSCON->AHBCLKCTRL[0];
1934 SYSCON->AHBCLKCTRLSET[0] = SYSCON_AHBCLKCTRL_ROM_MASK; /* Enable the clock for ROM */
1935 #endif
1936
1937 /* _WFI() */
1938 POWER_PowerCycleCpu();
1939
1940 /* Restore ROM clock setting */
1941 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
1942 SYSCON->AHBCLKCTRL0 = syscon_ahbclk_reg_0;
1943 #else
1944 SYSCON->AHBCLKCTRL[0] = syscon_ahbclk_reg_0;
1945 #endif
1946 /* Restore Flash Cache settings */
1947 SYSCON->LPCAC_CTRL = lpcac_ctrl_reg;
1948
1949 /* Switch PMC clock to 12 MHz and Configure the PMC in ACTIVE mode */
1950 PMC->CTRL = (PMC->CTRL & (~PMC_CTRL_LPMODE_MASK)) | PMC_CTRL_SELCLOCK_MASK |
1951 PMC_CTRL_LPMODE(LOWPOWER_CFG_LPMODE_ACTIVE);
1952
1953 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
1954 {
1955 /* Restore i_css_clk/pclk/hclk */
1956 SYSCON->AHBCLKCTRLSET[2] = syscon_css_clk_pclk_hclk;
1957
1958 /* Restore DTRNG clocks */
1959 SYSCON_CSS_CLK_CTRL_SET_REG = syscon_css_clk_ctrl;
1960 }
1961 #endif
1962
1963 /* Restore Analog Controller Registers */
1964 ANACTRL->FRO192M_CTRL = analog_ctrl_regs[0] | ANACTRL_FRO192M_CTRL_WRTRIM_MASK;
1965 ANACTRL->ANALOG_CTRL_CFG = analog_ctrl_regs[1];
1966 ANACTRL->ADC_CTRL = analog_ctrl_regs[2];
1967 ANACTRL->XO32M_CTRL = analog_ctrl_regs[3];
1968 ANACTRL->BOD_DCDC_INT_CTRL = analog_ctrl_regs[4];
1969 ANACTRL->LDO_XO32M = analog_ctrl_regs[5];
1970 ANACTRL->OSC_TESTBUS = analog_ctrl_regs[6];
1971
1972 /* Restore VREF Module Factory Trimmings ... */
1973 VREF->TEST_UNLOCK = 0x5AA5UL << 1; /* TEST_UNLOCK. Required before writting TRIM0 & TRIM1 */
1974 VREF->TRIM0 = vref_regs[2];
1975 VREF->TRIM1 = vref_regs[3];
1976 /* ... then restore VREF Module User Configuration */
1977 VREF->CSR = vref_regs[0];
1978 VREF->UTRIM = vref_regs[1];
1979
1980 /* Restore VREF module reset and clock state */
1981 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
1982 SYSCON->PRESETCTRL3 = (SYSCON->PRESETCTRL3 & (~SYSCON_PRESETCTRL3_VREF_RST_MASK)) | vref_rst_state;
1983 SYSCON->AHBCLKCTRL3 = (SYSCON->AHBCLKCTRL3 & (~SYSCON_AHBCLKCTRL3_VREF_MASK)) | vref_clk_state;
1984 #else
1985 *(uint32_t *)(((uint32_t *)SYSCON->RESERVED_5)) =
1986 ((*(uint32_t *)(((uint32_t *)SYSCON->RESERVED_5))) & (~0x40000UL)) | vref_rst_state;
1987 *(uint32_t *)(((uint32_t *)SYSCON->RESERVED_9)) =
1988 ((*(uint32_t *)(((uint32_t *)SYSCON->RESERVED_9))) & (~0x40000UL)) | vref_clk_state;
1989 #endif
1990
1991 /* Disable VREF Module isolation ... */
1992 PMC->MISCCTRL = PMC->MISCCTRL & (~PMC_MISCCTRL_VREF_ISO_MASK);
1993
1994 /* After wake up from Power-down, the Core supply source is LDO CORE */
1995 /* So restore the user configuration if necessary */
1996 if (core_supply_source == kPOWER_CoreSrcDCDC)
1997 {
1998 /* Restore DCDC Converter as Core Logic supply source */
1999 /* NOTE: PMC must be set in ACTIVE mode first before doing this switching to DCDC */
2000 (void)POWER_SetCorePowerSource(kPOWER_CoreSrcDCDC);
2001 }
2002
2003 break;
2004 }
2005
2006 case LOWPOWER_CFG_LPMODE_DEEPPOWERDOWN:
2007 {
2008 /* DEEP-POWER-DOWN power mode */
2009
2010 /* Configure wake-up by I/O :
2011 * - Set up wake-up IO pad control source : PMC WAKEUPIOCTRL (WAKEUPIO_ENABLE = 1)
2012 * - Reset Wake-up I/O Edge Detectors & Cause (WAKEUPIO_RSTN = 0)
2013 */
2014 PMC->WAKEUPIOCTRL = p_lowpower_cfg->WAKEUPIOSRC | PMC_WAKEUPIOCTRL_WAKEUPIO_ENABLE_CTRL_MASK;
2015
2016 /* Release Wake up I/O reset (WAKEUPIO_RSTN = 1)*/
2017 PMC->WAKEUPIOCTRL |= PMC_WAKEUPIOCTRL_WAKEUPIO_RSTN_MASK;
2018
2019 /* Only FRO1M, FRO32K, XTAL32K and LDOMEM can stay powered during DEEP POWER-DOWN */
2020 PMC->PDSLEEPCFG0 =
2021 p_lowpower_cfg->PDCTRL[0] | (0xFFFFFFFFU & (~((uint32_t)kPDRUNCFG_PD_FRO1M | (uint32_t)kPDRUNCFG_PD_FRO32K |
2022 (uint32_t)kPDRUNCFG_PD_XTAL32K | (uint32_t)kPDRUNCFG_PD_LDOMEM)));
2023 PMC->PDSLEEPCFG1 = p_lowpower_cfg->PDCTRL[1];
2024
2025 /* Disable all IRQs */
2026 __disable_irq();
2027
2028 /*
2029 * From here :
2030 * 1 - If an interrupt that is enabled occurs, the _WFI instruction will not be executed and we won't enter
2031 * in POWER DOWN. 2 - If an interrupt that is not enabled occurs, there is no consequence neither on the
2032 * execution of the low power mode nor on the behaviour of the CPU.
2033 */
2034
2035 /* clear all Reset causes */
2036 PMC->RESETCAUSE = 0xFFFFFFFFUL;
2037
2038 /* Enable DEEP POWER-DOWN reset */
2039 PMC->RESETCTRL |= PMC_RESETCTRL_DPDWAKEUPRESETENABLE_MASK;
2040
2041 /* Switch PMC clock to 1 MHz */
2042 PMC->CTRL = PMC->CTRL & (~PMC_CTRL_SELCLOCK_MASK);
2043
2044 /* _WFI() */
2045 POWER_PowerCycleCpu();
2046
2047 /*** We should never reach this point, unless the Low Power cycle has been cancelled somehow. ***/
2048 /* Switch PMC clock to 12 MHz and Configure the PMC in ACTIVE mode */
2049 PMC->CTRL = (PMC->CTRL & (~PMC_CTRL_LPMODE_MASK)) | PMC_CTRL_SELCLOCK_MASK |
2050 PMC_CTRL_LPMODE(LOWPOWER_CFG_LPMODE_ACTIVE);
2051
2052 break;
2053 }
2054
2055 default:
2056 {
2057 /* Error */
2058 break;
2059 }
2060 } // End switch( low_power_mode )
2061
2062 /* Restore FMC Configuration */
2063 SYSCON->FMCCR = SYSCON->FMCCR | (fmccr_reg & SYSCON_FMCCR_PREFEN_MASK);
2064
2065 /*
2066 * Restore the configuration of the Priority Mask Register.
2067 * Rational : if the interrupts were enable before entering the Low power mode, they will be re-enabled,
2068 * if they were disabled, they will stay disabled.
2069 */
2070 __set_PRIMASK(primask);
2071
2072 /* Restore the configuration of the NMI Register */
2073 SYSCON->NMISRC |= cpu0_nmi_enable;
2074
2075 /* Restore the configuration of the CPU interrupt enable Registers (because they have been overwritten inside the
2076 * low power API */
2077 for (i = 0; i < 4U; i++)
2078 {
2079 NVIC->ISER[i] = cpu0_int_enable[i];
2080 }
2081 }
2082
2083 /**
2084 * @brief Configures and enters in low power mode
2085 * @param : p_lowpower_cfg
2086 * @return Nothing
2087 */
POWER_WakeUpIOCtrl(uint32_t p_wakeup_io_ctrl)2088 static uint32_t POWER_WakeUpIOCtrl(uint32_t p_wakeup_io_ctrl)
2089 {
2090 uint32_t wake_up_type;
2091 uint32_t wakeup_io_ctrl_reg = 0;
2092
2093 // Enable IOCON
2094 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
2095 SYSCON->PRESETCTRLCLR[0] = SYSCON_PRESETCTRL0_IOCON_RST_MASK;
2096 SYSCON->AHBCLKCTRLSET[0] = SYSCON_AHBCLKCTRL0_IOCON_MASK;
2097 #else
2098 SYSCON->PRESETCTRLCLR[0] = SYSCON_PRESETCTRL_IOCON_RST_MASK;
2099 SYSCON->AHBCLKCTRLSET[0] = SYSCON_AHBCLKCTRL_IOCON_MASK;
2100 #endif
2101
2102 /* Configure Pull up & Pull down based on the required wake-up edge */
2103
2104 /* Wake-up I/O 0 */
2105 wake_up_type =
2106 (p_wakeup_io_ctrl & (PMC_WAKEUPIOCTRL_RISINGEDGEWAKEUP0_MASK | PMC_WAKEUPIOCTRL_FALLINGEDGEWAKEUP0_MASK)) >>
2107 LOWPOWER_WAKEUPIOSRC_PIO0_INDEX;
2108 wakeup_io_ctrl_reg |= (wake_up_type << LOWPOWER_WAKEUPIOSRC_PIO0_INDEX);
2109 if ((wake_up_type == LOWPOWER_WAKEUPIOSRC_RISING) || (wake_up_type == LOWPOWER_WAKEUPIOSRC_RISING_FALLING))
2110 {
2111 /* Rising edge and both rising and falling edges */
2112 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO0_DISABLEPULLUPDOWN_MASK) == 0UL)
2113 {
2114 /* Internal pull up / pull down are not disabled by the user, so use them */
2115 IOCON->PIO[WAKEUPIO_0_PORT][WAKEUPIO_0_PINS] = IOCON_PIO_DIGIMODE(1) | IOCON_PIO_MODE(1); /* Pull down */
2116 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN << LOWPOWER_WAKEUPIOSRC_PIO0MODE_INDEX);
2117 }
2118 }
2119 else
2120 {
2121 if (wake_up_type == LOWPOWER_WAKEUPIOSRC_FALLING)
2122 {
2123 /* Falling edge only */
2124 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO0_DISABLEPULLUPDOWN_MASK) == 0U)
2125 {
2126 /* Internal pull up / pull down are not disabled by the user, so use them */
2127 IOCON->PIO[WAKEUPIO_0_PORT][WAKEUPIO_0_PINS] = IOCON_PIO_DIGIMODE(1) | IOCON_PIO_MODE(2); /* Pull up */
2128 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP << LOWPOWER_WAKEUPIOSRC_PIO0MODE_INDEX);
2129 }
2130 }
2131 else
2132 {
2133 /* Wake-up I/O is disabled : set pull-up/pull-down as required by the user */
2134 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO0_DISABLEPULLUPDOWN_MASK) != 0U)
2135 {
2136 /* Wake-up I/O is configured as Plain Input */
2137 p_wakeup_io_ctrl &= ~LOWPOWER_WAKEUPIO_PIO0_PULLUPDOWN_MASK;
2138 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PLAIN << LOWPOWER_WAKEUPIOSRC_PIO0MODE_INDEX);
2139 }
2140 else
2141 {
2142 /* Wake-up I/O is configured as pull-up or pull-down */
2143 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO0_PULLUPDOWN_MASK) != 0U)
2144 {
2145 /* Wake-up I/O is configured as pull-up */
2146 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP << LOWPOWER_WAKEUPIOSRC_PIO0MODE_INDEX);
2147 }
2148 else
2149 {
2150 /* Wake-up I/O is configured as pull-down */
2151 wakeup_io_ctrl_reg |=
2152 ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN << LOWPOWER_WAKEUPIOSRC_PIO0MODE_INDEX);
2153 }
2154 }
2155 }
2156 }
2157
2158 /* Wake-up I/O 1 */
2159 wake_up_type =
2160 (p_wakeup_io_ctrl & (PMC_WAKEUPIOCTRL_RISINGEDGEWAKEUP1_MASK | PMC_WAKEUPIOCTRL_FALLINGEDGEWAKEUP1_MASK)) >>
2161 LOWPOWER_WAKEUPIOSRC_PIO1_INDEX;
2162 wakeup_io_ctrl_reg |= (wake_up_type << LOWPOWER_WAKEUPIOSRC_PIO1_INDEX);
2163 if ((wake_up_type == LOWPOWER_WAKEUPIOSRC_RISING) || (wake_up_type == LOWPOWER_WAKEUPIOSRC_RISING_FALLING))
2164 {
2165 /* Rising edge and both rising and falling edges */
2166 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO1_DISABLEPULLUPDOWN_MASK) == 0U)
2167 {
2168 /* Internal pull up / pull down are not disabled by the user, so use them */
2169 IOCON->PIO[WAKEUPIO_1_PORT][WAKEUPIO_1_PINS] = IOCON_PIO_DIGIMODE(1) | IOCON_PIO_MODE(1); /* Pull down */
2170 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN << LOWPOWER_WAKEUPIOSRC_PIO1MODE_INDEX);
2171 }
2172 }
2173 else
2174 {
2175 if (wake_up_type == LOWPOWER_WAKEUPIOSRC_FALLING)
2176 {
2177 /* Falling edge only */
2178 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO1_DISABLEPULLUPDOWN_MASK) == 0U)
2179 {
2180 /* Internal pull up / pull down are not disabled by the user, so use them */
2181 IOCON->PIO[WAKEUPIO_1_PORT][WAKEUPIO_1_PINS] = IOCON_PIO_DIGIMODE(1) | IOCON_PIO_MODE(2); /* Pull up */
2182 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP << LOWPOWER_WAKEUPIOSRC_PIO1MODE_INDEX);
2183 }
2184 }
2185 else
2186 {
2187 /* Wake-up I/O is disabled : set it as required by the user */
2188 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO1_DISABLEPULLUPDOWN_MASK) != 0U)
2189 {
2190 /* Wake-up I/O is configured as Plain Input */
2191 p_wakeup_io_ctrl &= ~LOWPOWER_WAKEUPIO_PIO1_PULLUPDOWN_MASK;
2192 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PLAIN << LOWPOWER_WAKEUPIOSRC_PIO1MODE_INDEX);
2193 }
2194 else
2195 {
2196 /* Wake-up I/O is configured as pull-up or pull-down */
2197 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO1_PULLUPDOWN_MASK) != 0U)
2198 {
2199 /* Wake-up I/O is configured as pull-up */
2200 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP << LOWPOWER_WAKEUPIOSRC_PIO1MODE_INDEX);
2201 }
2202 else
2203 {
2204 /* Wake-up I/O is configured as pull-down */
2205 wakeup_io_ctrl_reg |=
2206 ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN << LOWPOWER_WAKEUPIOSRC_PIO1MODE_INDEX);
2207 }
2208 }
2209 }
2210 }
2211
2212 /* Wake-up I/O 2 */
2213 wake_up_type =
2214 (p_wakeup_io_ctrl & (PMC_WAKEUPIOCTRL_RISINGEDGEWAKEUP2_MASK | PMC_WAKEUPIOCTRL_FALLINGEDGEWAKEUP2_MASK)) >>
2215 LOWPOWER_WAKEUPIOSRC_PIO2_INDEX;
2216 wakeup_io_ctrl_reg |= (wake_up_type << LOWPOWER_WAKEUPIOSRC_PIO2_INDEX);
2217 if ((wake_up_type == LOWPOWER_WAKEUPIOSRC_RISING) || (wake_up_type == LOWPOWER_WAKEUPIOSRC_RISING_FALLING))
2218 {
2219 /* Rising edge and both rising and falling edges */
2220 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO2_DISABLEPULLUPDOWN_MASK) == 0U)
2221 {
2222 /* Internal pull up / pull down are not disabled by the user, so use them */
2223 IOCON->PIO[WAKEUPIO_2_PORT][WAKEUPIO_2_PINS] = IOCON_PIO_DIGIMODE(1) | IOCON_PIO_MODE(1); /* Pull down */
2224 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN << LOWPOWER_WAKEUPIOSRC_PIO2MODE_INDEX);
2225 }
2226 }
2227 else
2228 {
2229 if (wake_up_type == LOWPOWER_WAKEUPIOSRC_FALLING)
2230 {
2231 /* Falling edge only */
2232 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO2_DISABLEPULLUPDOWN_MASK) == 0U)
2233 {
2234 /* Internal pull up / pull down are not disabled by the user, so use them */
2235 IOCON->PIO[WAKEUPIO_2_PORT][WAKEUPIO_2_PINS] = IOCON_PIO_DIGIMODE(1) | IOCON_PIO_MODE(2); /* Pull up */
2236 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP << LOWPOWER_WAKEUPIOSRC_PIO2MODE_INDEX);
2237 }
2238 }
2239 else
2240 {
2241 /* Wake-up I/O is disabled : set it as required by the user */
2242 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO2_DISABLEPULLUPDOWN_MASK) != 0U)
2243 {
2244 /* Wake-up I/O is configured as Plain Input */
2245 p_wakeup_io_ctrl &= ~LOWPOWER_WAKEUPIO_PIO2_PULLUPDOWN_MASK;
2246 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PLAIN << LOWPOWER_WAKEUPIOSRC_PIO2MODE_INDEX);
2247 }
2248 else
2249 {
2250 /* Wake-up I/O is configured as pull-up or pull-down */
2251 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO2_PULLUPDOWN_MASK) != 0U)
2252 {
2253 /* Wake-up I/O is configured as pull-up */
2254 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP << LOWPOWER_WAKEUPIOSRC_PIO2MODE_INDEX);
2255 }
2256 else
2257 {
2258 /* Wake-up I/O is configured as pull-down */
2259 wakeup_io_ctrl_reg |=
2260 ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN << LOWPOWER_WAKEUPIOSRC_PIO2MODE_INDEX);
2261 }
2262 }
2263 }
2264 }
2265
2266 /* Wake-up I/O 3 */
2267 wake_up_type =
2268 (p_wakeup_io_ctrl & (PMC_WAKEUPIOCTRL_RISINGEDGEWAKEUP3_MASK | PMC_WAKEUPIOCTRL_FALLINGEDGEWAKEUP3_MASK)) >>
2269 LOWPOWER_WAKEUPIOSRC_PIO3_INDEX;
2270 wakeup_io_ctrl_reg |= (wake_up_type << LOWPOWER_WAKEUPIOSRC_PIO3_INDEX);
2271 if ((wake_up_type == LOWPOWER_WAKEUPIOSRC_RISING) || (wake_up_type == LOWPOWER_WAKEUPIOSRC_RISING_FALLING))
2272 {
2273 /* Rising edge and both rising and falling edges */
2274 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO3_DISABLEPULLUPDOWN_MASK) == 0U)
2275 {
2276 /* Internal pull up / pull down are not disabled by the user, so use them */
2277 IOCON->PIO[WAKEUPIO_3_PORT][WAKEUPIO_3_PINS] = IOCON_PIO_DIGIMODE(1) | IOCON_PIO_MODE(1); /* Pull down */
2278 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN << LOWPOWER_WAKEUPIOSRC_PIO3MODE_INDEX);
2279 }
2280 }
2281 else
2282 {
2283 if (wake_up_type == LOWPOWER_WAKEUPIOSRC_FALLING)
2284 {
2285 /* Falling edge only */
2286 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO3_DISABLEPULLUPDOWN_MASK) == 0U)
2287 {
2288 /* Internal pull up / pull down are not disabled by the user, so use them */
2289 IOCON->PIO[WAKEUPIO_3_PORT][WAKEUPIO_3_PINS] = IOCON_PIO_DIGIMODE(1) | IOCON_PIO_MODE(2); /* Pull up */
2290 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP << LOWPOWER_WAKEUPIOSRC_PIO3MODE_INDEX);
2291 }
2292 }
2293 else
2294 {
2295 /* Wake-up I/O is disabled : set it as required by the user */
2296 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO3_DISABLEPULLUPDOWN_MASK) != 0U)
2297 {
2298 /* Wake-up I/O is configured as Plain Input */
2299 p_wakeup_io_ctrl &= ~LOWPOWER_WAKEUPIO_PIO3_PULLUPDOWN_MASK;
2300 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PLAIN << LOWPOWER_WAKEUPIOSRC_PIO3MODE_INDEX);
2301 }
2302 else
2303 {
2304 /* Wake-up I/O is configured as pull-up or pull-down */
2305 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO3_PULLUPDOWN_MASK) != 0U)
2306 {
2307 /* Wake-up I/O is configured as pull-up */
2308 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP << LOWPOWER_WAKEUPIOSRC_PIO3MODE_INDEX);
2309 }
2310 else
2311 {
2312 /* Wake-up I/O is configured as pull-down */
2313 wakeup_io_ctrl_reg |=
2314 ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN << LOWPOWER_WAKEUPIOSRC_PIO3MODE_INDEX);
2315 }
2316 }
2317 }
2318 }
2319
2320 /* Wake-up I/O 4 */
2321 wake_up_type =
2322 (p_wakeup_io_ctrl & (PMC_WAKEUPIOCTRL_RISINGEDGEWAKEUP4_MASK | PMC_WAKEUPIOCTRL_FALLINGEDGEWAKEUP4_MASK)) >>
2323 LOWPOWER_WAKEUPIOSRC_PIO4_INDEX;
2324 wakeup_io_ctrl_reg |= (wake_up_type << LOWPOWER_WAKEUPIOSRC_PIO4_INDEX);
2325 if ((wake_up_type == LOWPOWER_WAKEUPIOSRC_RISING) || (wake_up_type == LOWPOWER_WAKEUPIOSRC_RISING_FALLING))
2326 {
2327 /* Rising edge and both rising and falling edges */
2328 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO4_DISABLEPULLUPDOWN_MASK) == 0UL)
2329 {
2330 /* Internal pull up / pull down are not disabled by the user, so use them */
2331 IOCON->PIO[WAKEUPIO_4_PORT][WAKEUPIO_4_PINS] = IOCON_PIO_DIGIMODE(1) | IOCON_PIO_MODE(1); /* Pull down */
2332 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN << LOWPOWER_WAKEUPIOSRC_PIO4MODE_INDEX);
2333 }
2334 }
2335 else
2336 {
2337 if (wake_up_type == LOWPOWER_WAKEUPIOSRC_FALLING)
2338 {
2339 /* Falling edge only */
2340 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO4_DISABLEPULLUPDOWN_MASK) == 0UL)
2341 {
2342 /* Internal pull up / pull down are not disabled by the user, so use them */
2343 IOCON->PIO[WAKEUPIO_4_PORT][WAKEUPIO_4_PINS] = IOCON_PIO_DIGIMODE(1) | IOCON_PIO_MODE(2); /* Pull up */
2344 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP << LOWPOWER_WAKEUPIOSRC_PIO4MODE_INDEX);
2345 }
2346 }
2347 else
2348 {
2349 /* Wake-up I/O is disabled : set it as required by the user */
2350 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO4_DISABLEPULLUPDOWN_MASK) != 0U)
2351 {
2352 /* Wake-up I/O is configured as Plain Input */
2353 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PLAIN << LOWPOWER_WAKEUPIOSRC_PIO4MODE_INDEX);
2354 }
2355 else
2356 {
2357 /* Wake-up I/O is configured as pull-up or pull-down */
2358 if ((p_wakeup_io_ctrl & LOWPOWER_WAKEUPIO_PIO4_PULLUPDOWN_MASK) != 0U)
2359 {
2360 /* Wake-up I/O is configured as pull-up */
2361 wakeup_io_ctrl_reg |= ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLUP << LOWPOWER_WAKEUPIOSRC_PIO4MODE_INDEX);
2362 }
2363 else
2364 {
2365 /* Wake-up I/O is configured as pull-down */
2366 wakeup_io_ctrl_reg |=
2367 ((uint32_t)LOWPOWER_WAKEUPIOSRC_IO_MODE_PULLDOWN << LOWPOWER_WAKEUPIOSRC_PIO4MODE_INDEX);
2368 }
2369 }
2370 }
2371 }
2372
2373 return (wakeup_io_ctrl_reg);
2374 }
2375
POWER_SetLdoAoLdoMemVoltage(uint32_t p_lp_mode)2376 static uint32_t POWER_SetLdoAoLdoMemVoltage(uint32_t p_lp_mode)
2377 {
2378 uint32_t voltage = 0;
2379 uint32_t ldo_ao_trim = 0;
2380 uint32_t ldo_mem_trim = 0;
2381 uint32_t lv_v_ldo_pmu, lv_v_ldo_pmu_boost;
2382 uint32_t lv_v_ldo_mem, lv_v_ldo_mem_boost;
2383
2384 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
2385 ldo_ao_trim = FLASH_NMPA_LDO_AO;
2386 ldo_mem_trim = FLASH_NMPA_LDO_MEM;
2387 #endif
2388
2389 switch (p_lp_mode)
2390 {
2391 case LOWPOWER_CFG_LPMODE_DEEPSLEEP:
2392 {
2393 if ((ldo_ao_trim & 0x80000000UL) != 0UL)
2394 {
2395 /* Apply settings coming from Flash */
2396 lv_v_ldo_pmu = (ldo_ao_trim >> 8) & 0x1FUL;
2397 lv_v_ldo_pmu_boost = (ldo_ao_trim >> 13) & 0x1FUL;
2398 }
2399 else
2400 {
2401 /* Apply default settings */
2402 lv_v_ldo_pmu = (uint32_t)V_AO_0P900;
2403 lv_v_ldo_pmu_boost = (uint32_t)V_AO_0P850;
2404 }
2405 }
2406 break;
2407
2408 case LOWPOWER_CFG_LPMODE_POWERDOWN:
2409 {
2410 if ((ldo_ao_trim & 0x80000000UL) != 0U)
2411 {
2412 /* Apply settings coming from Flash */
2413 lv_v_ldo_pmu = (ldo_ao_trim >> 18) & 0x1FUL;
2414 lv_v_ldo_pmu_boost = (ldo_ao_trim >> 23) & 0x1FUL;
2415 }
2416 else
2417 {
2418 /* Apply default settings */
2419 lv_v_ldo_pmu = (uint32_t)V_AO_0P800;
2420 lv_v_ldo_pmu_boost = (uint32_t)V_AO_0P750;
2421 }
2422 }
2423 break;
2424
2425 case LOWPOWER_CFG_LPMODE_DEEPPOWERDOWN:
2426 {
2427 if ((ldo_ao_trim & 0x80000000UL) != 0UL)
2428 {
2429 /* Apply settings coming from Flash */
2430 lv_v_ldo_pmu = (ldo_ao_trim >> 18) & 0x1FUL;
2431 lv_v_ldo_pmu_boost = (ldo_ao_trim >> 23) & 0x1FUL;
2432 }
2433 else
2434 {
2435 /* Apply default settings */
2436 lv_v_ldo_pmu = (uint32_t)V_AO_0P800;
2437 lv_v_ldo_pmu_boost = (uint32_t)V_AO_0P750;
2438 }
2439 }
2440 break;
2441
2442 default:
2443 /* We should never reach this point */
2444 lv_v_ldo_pmu = (uint32_t)V_AO_1P100;
2445 lv_v_ldo_pmu_boost = (uint32_t)V_AO_1P050;
2446 break;
2447 }
2448
2449 if ((ldo_mem_trim & 0x80000000U) != 0UL)
2450 {
2451 /* Apply settings coming from Flash */
2452 lv_v_ldo_mem = ldo_mem_trim & 0x1FUL;
2453 lv_v_ldo_mem_boost = (ldo_mem_trim >> 8) & 0x1FUL;
2454 }
2455 else
2456 {
2457 /* Apply default settings */
2458 lv_v_ldo_mem = (uint32_t)V_AO_0P750; /* Set to 0.75V (voltage Scaling) */
2459 lv_v_ldo_mem_boost = (uint32_t)V_AO_0P700; /* Set to 0.7V (voltage Scaling) */
2460 }
2461
2462 /* The Memories Voltage settings below are for voltage scaling */
2463 voltage = (lv_v_ldo_pmu << LOWPOWER_VOLTAGE_LDO_PMU_INDEX) |
2464 (lv_v_ldo_pmu_boost << LOWPOWER_VOLTAGE_LDO_PMU_BOOST_INDEX) |
2465 (lv_v_ldo_mem << LOWPOWER_VOLTAGE_LDO_MEM_INDEX) |
2466 (lv_v_ldo_mem_boost << LOWPOWER_VOLTAGE_LDO_MEM_BOOST_INDEX);
2467
2468 return (voltage);
2469 }
2470
2471 /**
2472 * @brief Configures System Power Profile
2473 * @param power_profile : Low/Medium/High
2474 * @return Nothing
2475 */
POWER_SetSystemPowerProfile(v_system_power_profile_t power_profile)2476 static void POWER_SetSystemPowerProfile(v_system_power_profile_t power_profile)
2477 {
2478 uint32_t dcdcTrimValue0 = 0;
2479 uint32_t dcdcTrimValue1 = 0;
2480
2481 switch (power_profile)
2482 {
2483 case V_SYSTEM_POWER_PROFILE_MEDIUM:
2484 /* Medium */
2485
2486 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
2487 dcdcTrimValue0 = FLASH_NMPA_DCDC_POWER_PROFILE_MEDIUM_ARRAY0;
2488 dcdcTrimValue1 = FLASH_NMPA_DCDC_POWER_PROFILE_MEDIUM_ARRAY1;
2489 #endif
2490
2491 if (0UL != (dcdcTrimValue0 & 0x1UL))
2492 {
2493 /* DCDC Trimmings in Flash are valid */
2494 dcdcTrimValue0 = (uint32_t)dcdcTrimValue0 >> 1;
2495 PMC->DCDC0 = dcdcTrimValue0;
2496 PMC->DCDC1 = dcdcTrimValue1;
2497 }
2498 else
2499 {
2500 /* DCDC Trimmings in Flash are not valid.
2501 * Set a default value */
2502 PMC->DCDC0 = 0x0220ACF1UL >> 1;
2503 PMC->DCDC1 = 0x01D05C78UL;
2504 }
2505
2506 break;
2507
2508 case V_SYSTEM_POWER_PROFILE_HIGH:
2509 /* High */
2510 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
2511 dcdcTrimValue0 = FLASH_NMPA_DCDC_POWER_PROFILE_HIGH_ARRAY0;
2512 dcdcTrimValue1 = FLASH_NMPA_DCDC_POWER_PROFILE_HIGH_ARRAY1;
2513 #endif
2514
2515 if (0UL != (dcdcTrimValue0 & 0x1UL))
2516 {
2517 /* DCDC Trimmings in Flash are valid */
2518 dcdcTrimValue0 = dcdcTrimValue0 >> 1;
2519 PMC->DCDC0 = dcdcTrimValue0;
2520 PMC->DCDC1 = dcdcTrimValue1;
2521 }
2522 else
2523 {
2524 /* DCDC Trimmings in Flash are not valid.
2525 * Set a default value */
2526 PMC->DCDC0 = 0x0228ACF9UL >> 1;
2527 PMC->DCDC1 = 0x01E05C68UL;
2528 }
2529
2530 break;
2531
2532 default:
2533 /* Low */
2534 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
2535 dcdcTrimValue0 = FLASH_NMPA_DCDC_POWER_PROFILE_LOW_ARRAY0;
2536 dcdcTrimValue1 = FLASH_NMPA_DCDC_POWER_PROFILE_LOW_ARRAY1;
2537 #endif
2538
2539 if (0UL != (dcdcTrimValue0 & 0x1UL))
2540 {
2541 /* DCDC Trimmings in Flash are valid */
2542 dcdcTrimValue0 = dcdcTrimValue0 >> 1;
2543 PMC->DCDC0 = dcdcTrimValue0;
2544 PMC->DCDC1 = dcdcTrimValue1;
2545 }
2546 else
2547 {
2548 /* DCDC Trimmings in Flash are not valid.
2549 * Set a default value */
2550 PMC->DCDC0 = 0x0210CCFDUL >> 1;
2551 PMC->DCDC1 = 0x01C05C98UL;
2552 }
2553 break;
2554 }
2555 }
2556
2557 /**
2558 * @brief Configures System Power Profile
2559 * @param power_profile : Low/Medium/High
2560 * @return Nothing
2561 */
POWER_SetVoltageForProcess(v_system_power_profile_t power_profile)2562 static void POWER_SetVoltageForProcess(v_system_power_profile_t power_profile)
2563 {
2564 /* Get Sample Process Corner */
2565 lowpower_process_corner_enum part_process_corner = POWER_GetPartProcessCorner();
2566
2567 switch (part_process_corner)
2568 {
2569 case PROCESS_CORNER_SSS:
2570 /* Slow Corner */
2571 {
2572 switch (power_profile)
2573 {
2574 case V_SYSTEM_POWER_PROFILE_MEDIUM:
2575 /* Medium */
2576 POWER_SetSystemVoltage(VOLTAGE_SSS_MED_MV);
2577 break;
2578
2579 case V_SYSTEM_POWER_PROFILE_HIGH:
2580 /* High */
2581 POWER_SetSystemVoltage(VOLTAGE_SSS_HIG_MV);
2582 break;
2583
2584 default:
2585 /* V_SYSTEM_POWER_PROFILE_LOW */
2586 POWER_SetSystemVoltage(VOLTAGE_SSS_LOW_MV);
2587 break;
2588 } // switch(power_profile)
2589 }
2590 break;
2591
2592 case PROCESS_CORNER_FFF:
2593 /* Fast Corner */
2594 {
2595 switch (power_profile)
2596 {
2597 case V_SYSTEM_POWER_PROFILE_MEDIUM:
2598 /* Medium */
2599 POWER_SetSystemVoltage(VOLTAGE_FFF_MED_MV);
2600 break;
2601
2602 case V_SYSTEM_POWER_PROFILE_HIGH:
2603 /* High */
2604 POWER_SetSystemVoltage(VOLTAGE_FFF_HIG_MV);
2605 break;
2606
2607 default:
2608 /* V_SYSTEM_POWER_PROFILE_LOW */
2609 POWER_SetSystemVoltage(VOLTAGE_FFF_LOW_MV);
2610 break;
2611 } // switch(power_profile)
2612 }
2613 break;
2614
2615 default:
2616 /* Nominal (NNN) and all others Process Corners : assume Nominal Corner */
2617 {
2618 switch (power_profile)
2619 {
2620 case V_SYSTEM_POWER_PROFILE_MEDIUM:
2621 /* Medium */
2622 POWER_SetSystemVoltage(VOLTAGE_NNN_MED_MV);
2623 break;
2624
2625 case V_SYSTEM_POWER_PROFILE_HIGH:
2626 /* High */
2627 POWER_SetSystemVoltage(VOLTAGE_NNN_HIG_MV);
2628 break;
2629
2630 default:
2631 /* V_SYSTEM_POWER_PROFILE_LOW */
2632 POWER_SetSystemVoltage(VOLTAGE_NNN_LOW_MV);
2633 break;
2634 } // switch(power_profile)
2635 }
2636 break;
2637 } // switch(part_process_corner)
2638 }
2639
2640 /**
2641 * @brief
2642 * @param
2643 * @return
2644 */
POWER_GetPartProcessCorner(void)2645 static lowpower_process_corner_enum POWER_GetPartProcessCorner(void)
2646 {
2647 lowpower_process_corner_enum part_process_corner;
2648 uint32_t pvt_ringo_hz;
2649 uint32_t pvt_ringo_0 = 0;
2650 uint32_t pvt_ringo_1 = 0;
2651
2652 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
2653 pvt_ringo_0 = FLASH_NMPA_PVT_MONITOR_0_RINGO;
2654 pvt_ringo_1 = FLASH_NMPA_PVT_MONITOR_1_RINGO;
2655 #endif
2656
2657 /*
2658 * Check that the PVT Monitors Trimmings in flash are valid.
2659 * Note : On Customer Samples, PVT Trimmings in flash will ALWAYS be valid,
2660 * so that in the SDK, the check below could be skipped (but NOT the right shift operation)
2661 */
2662 if (0UL != (pvt_ringo_0 & 0x1UL))
2663 {
2664 /* PVT Trimmings in Flash are valid */
2665 pvt_ringo_0 = pvt_ringo_0 >> 1;
2666 }
2667 else
2668 {
2669 /* PVT Trimmings in Flash are NOT valid (average value assumed) */
2670 pvt_ringo_0 = PROCESS_NNN_AVG_HZ;
2671 }
2672
2673 if (0UL != (pvt_ringo_1 & 0x1UL))
2674 {
2675 /* PVT Trimmings in Flash are valid */
2676 pvt_ringo_1 = pvt_ringo_1 >> 1;
2677 }
2678 else
2679 {
2680 /* PVT Trimmings in Flash are NOT valid (average value assumed) */
2681 pvt_ringo_1 = PROCESS_NNN_AVG_HZ;
2682 }
2683
2684 /*
2685 * There are 2 Ring Oscillators in the System.
2686 * We consider the worst case scenario by choosing
2687 * the minimum of the 2 Ring Oscillators values
2688 * as the final value to determine the Process Corner.
2689 */
2690 if (pvt_ringo_1 <= pvt_ringo_0)
2691 {
2692 pvt_ringo_hz = pvt_ringo_1;
2693 }
2694 else
2695 {
2696 pvt_ringo_hz = pvt_ringo_0;
2697 }
2698
2699 /*
2700 * Determine the process corner based on the value of the Ring Oscillator frequency
2701 */
2702 if (pvt_ringo_hz <= PROCESS_NNN_MIN_HZ)
2703 {
2704 /* SSS Process Corner */
2705 part_process_corner = PROCESS_CORNER_SSS;
2706 }
2707 else
2708 {
2709 if (pvt_ringo_hz <= PROCESS_NNN_MAX_HZ)
2710 {
2711 /* NNN Process Corner */
2712 part_process_corner = PROCESS_CORNER_NNN;
2713 }
2714 else
2715 {
2716 /* FFF Process Corner */
2717 part_process_corner = PROCESS_CORNER_FFF;
2718 }
2719 }
2720
2721 return (part_process_corner);
2722 }
2723
2724 /**
2725 * @brief
2726 * @param
2727 * @return
2728 */
POWER_SetSystemVoltage(uint32_t system_voltage_mv)2729 static void POWER_SetSystemVoltage(uint32_t system_voltage_mv)
2730 {
2731 /*
2732 * Set system voltage
2733 */
2734 uint32_t lv_ldo_ao = (uint32_t)V_AO_1P100; /* <ldo_ao> */
2735 uint32_t lv_ldo_ao_boost = (uint32_t)V_AO_1P150; /* <ldo_ao_boost> */
2736 uint32_t lv_dcdc = (uint32_t)V_DCDC_1P100; /* <dcdc> */
2737 uint32_t lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P102; /* <ldo_core> */
2738
2739 /*
2740 * Because DCDC has less code than LD_AO, we first determine the
2741 * optimum DCDC settings, then we find the closest possible settings
2742 * for LDO_AO, knowing that we want both settings to be as close as possible
2743 * (ideally, they shall be equal).
2744 */
2745
2746 if (system_voltage_mv <= 950UL)
2747 {
2748 lv_dcdc = (uint32_t)V_DCDC_0P950;
2749 lv_ldo_ao = (uint32_t)V_AO_0P960;
2750 lv_ldo_ao_boost = (uint32_t)V_AO_1P010;
2751 lv_ldo_core = (uint32_t)V_LDOCORE_HP_0P953;
2752 }
2753 else if (system_voltage_mv <= 975UL)
2754 {
2755 lv_dcdc = (uint32_t)V_DCDC_0P975;
2756 lv_ldo_ao = (uint32_t)V_AO_0P980;
2757 lv_ldo_ao_boost = (uint32_t)V_AO_1P030;
2758 lv_ldo_core = (uint32_t)V_LDOCORE_HP_0P980;
2759 }
2760 else if (system_voltage_mv <= 1000UL)
2761 {
2762 lv_dcdc = (uint32_t)V_DCDC_1P000;
2763 lv_ldo_ao = (uint32_t)V_AO_1P000;
2764 lv_ldo_ao_boost = (uint32_t)V_AO_1P050;
2765 lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P001;
2766 }
2767 else if (system_voltage_mv <= 1025UL)
2768 {
2769 lv_dcdc = (uint32_t)V_DCDC_1P025;
2770 lv_ldo_ao = (uint32_t)V_AO_1P030;
2771 lv_ldo_ao_boost = (uint32_t)V_AO_1P080;
2772 lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P027;
2773 }
2774 else if (system_voltage_mv <= 1050UL)
2775 {
2776 lv_dcdc = (uint32_t)V_DCDC_1P050;
2777 lv_ldo_ao = (uint32_t)V_AO_1P060;
2778 lv_ldo_ao_boost = (uint32_t)V_AO_1P110;
2779 lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P055;
2780 }
2781 else if (system_voltage_mv <= 1075UL)
2782 {
2783 lv_dcdc = (uint32_t)V_DCDC_1P075;
2784 lv_ldo_ao = (uint32_t)V_AO_1P080;
2785 lv_ldo_ao_boost = (uint32_t)V_AO_1P130;
2786 lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P075;
2787 }
2788 else if (system_voltage_mv <= 1100UL)
2789 {
2790 lv_dcdc = (uint32_t)V_DCDC_1P100;
2791 lv_ldo_ao = (uint32_t)V_AO_1P100;
2792 lv_ldo_ao_boost = (uint32_t)V_AO_1P150;
2793 lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P102;
2794 }
2795 else if (system_voltage_mv <= 1125UL)
2796 {
2797 lv_dcdc = (uint32_t)V_DCDC_1P125;
2798 lv_ldo_ao = (uint32_t)V_AO_1P130;
2799 lv_ldo_ao_boost = (uint32_t)V_AO_1P160;
2800 lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P027;
2801 }
2802 else if (system_voltage_mv <= 1150UL)
2803 {
2804 lv_dcdc = (uint32_t)V_DCDC_1P150;
2805 lv_ldo_ao = (uint32_t)V_AO_1P160;
2806 lv_ldo_ao_boost = (uint32_t)V_AO_1P220;
2807 lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P156;
2808 }
2809 else if (system_voltage_mv <= 1175UL)
2810 {
2811 lv_dcdc = (uint32_t)V_DCDC_1P175;
2812 lv_ldo_ao = (uint32_t)V_AO_1P160;
2813 lv_ldo_ao_boost = (uint32_t)V_AO_1P220;
2814 lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P177;
2815 }
2816 else
2817 {
2818 lv_dcdc = (uint32_t)V_DCDC_1P200;
2819 lv_ldo_ao = (uint32_t)V_AO_1P220;
2820 lv_ldo_ao_boost = (uint32_t)V_AO_1P220;
2821 lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P204;
2822 }
2823
2824 /* Set up LDO Always-On voltages */
2825 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
2826 /* Apply LDO_AO Trimmings */
2827 {
2828 int8_t ldo_ao_offset;
2829 int32_t lv_ldo_ao_signed;
2830
2831 ldo_ao_offset =
2832 (int8_t)(uint32_t)(((FLASH_NMPA_LDO_AO & FLASH_NMPA_LDO_AO_VADJ_ACTIVE_MASK) >> FLASH_NMPA_LDO_AO_VADJ_ACTIVE_SHIFT));
2833 lv_ldo_ao_signed = (int32_t)((int32_t)lv_ldo_ao + (int32_t)ldo_ao_offset);
2834
2835 if (lv_ldo_ao_signed < (int32_t)V_AO_0P960)
2836 {
2837 lv_ldo_ao = (uint32_t)V_AO_0P960;
2838 }
2839 else
2840 {
2841 if (lv_ldo_ao_signed > (int32_t)V_AO_1P220)
2842 {
2843 lv_ldo_ao = (uint32_t)V_AO_1P220;
2844 }
2845 else
2846 {
2847 lv_ldo_ao = (uint32_t)lv_ldo_ao_signed;
2848 }
2849 }
2850 }
2851 // Note: In ACTIVE mode, the LDO BOOST mode is always enabled.
2852 // Therefore, the value of the "lv_ldo_ao_boost" does not really matter.
2853 // For that reason, we do not recompuete it here.
2854 #endif
2855 PMC->LDOPMU = (PMC->LDOPMU & (~PMC_LDOPMU_VADJ_MASK) & (~PMC_LDOPMU_VADJ_BOOST_MASK)) | PMC_LDOPMU_VADJ(lv_ldo_ao) |
2856 PMC_LDOPMU_VADJ_BOOST(lv_ldo_ao_boost);
2857
2858 /* Set up DCDC voltage */
2859 PMC->DCDC0 = (PMC->DCDC0 & (~PMC_DCDC0_VOUT_MASK)) | PMC_DCDC0_VOUT(lv_dcdc);
2860
2861 /* Set up LDO_CORE voltage */
2862 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
2863 /* Apply LDO_CORE Trimmings */
2864 {
2865 int8_t ldo_core_regref_offset;
2866 int32_t lv_ldo_core_signed;
2867
2868 ldo_core_regref_offset = (int8_t)((uint32_t)((FLASH_NMPA_BOD_LDOCORE & FLASH_NMPA_BOD_LDOCORE_REGREF_1P8V_OFFSET_MASK) >>
2869 FLASH_NMPA_BOD_LDOCORE_REGREF_1P8V_OFFSET_SHIFT));
2870 lv_ldo_core_signed = (int32_t)((int32_t)lv_ldo_core + (int32_t)ldo_core_regref_offset);
2871
2872 if (lv_ldo_core_signed < (int32_t)V_LDOCORE_HP_1P204)
2873 {
2874 lv_ldo_core = (uint32_t)V_LDOCORE_HP_1P204;
2875 }
2876 else
2877 {
2878 if (lv_ldo_core_signed > (int32_t)V_LDOCORE_HP_0P953)
2879 {
2880 lv_ldo_core = (uint32_t)V_LDOCORE_HP_0P953;
2881 }
2882 else
2883 {
2884 lv_ldo_core = (uint32_t)lv_ldo_core_signed;
2885 }
2886 }
2887 }
2888 #endif
2889 PMC->LDOCORE0 = (PMC->LDOCORE0 & (~PMC_LDOCORE0_REGREFTRIM_MASK)) | PMC_LDOCORE0_REGREFTRIM(lv_ldo_core);
2890 }
2891
2892 /**
2893 * brief
2894 * return
2895 */
POWER_SRAMSetRegister(power_sram_index_t sram_index,uint32_t power_mode)2896 static void POWER_SRAMSetRegister(power_sram_index_t sram_index, uint32_t power_mode)
2897 {
2898 switch (sram_index)
2899 {
2900 case kPOWER_SRAM_IDX_RAM_X0:
2901 {
2902 PMC->SRAMCTRL0 = (PMC->SRAMCTRL0 & (~(0xFUL << PMC_SRAMCTRL0_RAM_X0_LS_SHIFT))) |
2903 (power_mode << PMC_SRAMCTRL0_RAM_X0_LS_SHIFT);
2904 break;
2905 }
2906
2907 case kPOWER_SRAM_IDX_RAM_00:
2908 {
2909 PMC->SRAMCTRL0 = (PMC->SRAMCTRL0 & (~(0xFUL << PMC_SRAMCTRL0_RAM_00_LS_SHIFT))) |
2910 (power_mode << PMC_SRAMCTRL0_RAM_00_LS_SHIFT);
2911 break;
2912 }
2913
2914 case kPOWER_SRAM_IDX_RAM_01:
2915 {
2916 PMC->SRAMCTRL0 = (PMC->SRAMCTRL0 & (~(0xFUL << PMC_SRAMCTRL0_RAM_01_LS_SHIFT))) |
2917 (power_mode << PMC_SRAMCTRL0_RAM_01_LS_SHIFT);
2918 break;
2919 }
2920
2921 case kPOWER_SRAM_IDX_RAM_02:
2922 {
2923 PMC->SRAMCTRL0 = (PMC->SRAMCTRL0 & (~(0xFUL << PMC_SRAMCTRL0_RAM_02_LS_SHIFT))) |
2924 (power_mode << PMC_SRAMCTRL0_RAM_02_LS_SHIFT);
2925 break;
2926 }
2927
2928 case kPOWER_SRAM_IDX_RAM_03:
2929 {
2930 PMC->SRAMCTRL0 = (PMC->SRAMCTRL0 & (~(0xFUL << PMC_SRAMCTRL0_RAM_03_LS_SHIFT))) |
2931 (power_mode << PMC_SRAMCTRL0_RAM_03_LS_SHIFT);
2932 break;
2933 }
2934
2935 case kPOWER_SRAM_IDX_RAM_10:
2936 {
2937 PMC->SRAMCTRL0 = (PMC->SRAMCTRL0 & (~(0xFUL << PMC_SRAMCTRL0_RAM_10_LS_SHIFT))) |
2938 (power_mode << PMC_SRAMCTRL0_RAM_10_LS_SHIFT);
2939 break;
2940 }
2941
2942 case kPOWER_SRAM_IDX_RAM_20:
2943 {
2944 PMC->SRAMCTRL0 = (PMC->SRAMCTRL0 & (~(0xFUL << PMC_SRAMCTRL0_RAM_20_LS_SHIFT))) |
2945 (power_mode << PMC_SRAMCTRL0_RAM_20_LS_SHIFT);
2946 break;
2947 }
2948
2949 case kPOWER_SRAM_IDX_RAM_30:
2950 {
2951 PMC->SRAMCTRL0 = (PMC->SRAMCTRL0 & (~(0xFUL << PMC_SRAMCTRL0_RAM_30_LS_SHIFT))) |
2952 (power_mode << PMC_SRAMCTRL0_RAM_30_LS_SHIFT);
2953 break;
2954 }
2955
2956 case kPOWER_SRAM_IDX_RAM_40:
2957 {
2958 PMC->SRAMCTRL1 = (PMC->SRAMCTRL1 & (~(0xFUL << PMC_SRAMCTRL1_RAM_40_LS_SHIFT))) |
2959 (power_mode << PMC_SRAMCTRL1_RAM_40_LS_SHIFT);
2960 break;
2961 }
2962
2963 case kPOWER_SRAM_IDX_RAM_41:
2964 {
2965 PMC->SRAMCTRL1 = (PMC->SRAMCTRL1 & (~(0xFUL << PMC_SRAMCTRL1_RAM_41_LS_SHIFT))) |
2966 (power_mode << PMC_SRAMCTRL1_RAM_41_LS_SHIFT);
2967 break;
2968 }
2969
2970 case kPOWER_SRAM_IDX_RAM_42:
2971 {
2972 PMC->SRAMCTRL1 = (PMC->SRAMCTRL1 & (~(0xFUL << PMC_SRAMCTRL1_RAM_42_LS_SHIFT))) |
2973 (power_mode << PMC_SRAMCTRL1_RAM_42_LS_SHIFT);
2974 break;
2975 }
2976
2977 case kPOWER_SRAM_IDX_RAM_43:
2978 {
2979 PMC->SRAMCTRL1 = (PMC->SRAMCTRL1 & (~(0xFUL << PMC_SRAMCTRL1_RAM_43_LS_SHIFT))) |
2980 (power_mode << PMC_SRAMCTRL1_RAM_43_LS_SHIFT);
2981 break;
2982 }
2983
2984 case kPOWER_SRAM_IDX_FLASHCACHE:
2985 {
2986 PMC->SRAMCTRL1 = (PMC->SRAMCTRL1 & (~(0xFUL << PMC_SRAMCTRL1_RAM_FLASHLPCACHE_LS_SHIFT))) |
2987 (power_mode << PMC_SRAMCTRL1_RAM_FLASHLPCACHE_LS_SHIFT);
2988 break;
2989 }
2990
2991 case kPOWER_SRAM_IDX_FLEXSPICACHE:
2992 {
2993 PMC->SRAMCTRL1 = (PMC->SRAMCTRL1 & (~(0xFUL << PMC_SRAMCTRL1_RAM_FLEXSPILPCACHE_LS_SHIFT))) |
2994 (power_mode << PMC_SRAMCTRL1_RAM_FLEXSPILPCACHE_LS_SHIFT);
2995 break;
2996 }
2997
2998 default:
2999 // Error
3000 break;
3001 }
3002 }
3003
3004 /**
3005 * brief
3006 * return
3007 */
POWER_SRAMActiveToLightSleep(power_sram_index_t sram_index)3008 static void POWER_SRAMActiveToLightSleep(power_sram_index_t sram_index)
3009 {
3010 POWER_SRAMSetRegister(sram_index, SRAM_PWR_MODE_LS_CODE);
3011 }
3012
3013 /**
3014 * brief
3015 * return
3016 */
POWER_SRAMActiveToDeepSleep(power_sram_index_t sram_index)3017 static void POWER_SRAMActiveToDeepSleep(power_sram_index_t sram_index)
3018 {
3019 POWER_SRAMSetRegister(sram_index, SRAM_PWR_MODE_DS_CODE);
3020 }
3021
3022 /**
3023 * brief
3024 * return
3025 */
POWER_SRAMActiveToShutDown(power_sram_index_t sram_index)3026 static void POWER_SRAMActiveToShutDown(power_sram_index_t sram_index)
3027 {
3028 POWER_SRAMSetRegister(sram_index, SRAM_PWR_MODE_SD_CODE);
3029 }
3030
3031 /**
3032 * brief
3033 * return
3034 */
POWER_SRAMLightSleepToActive(power_sram_index_t sram_index)3035 static void POWER_SRAMLightSleepToActive(power_sram_index_t sram_index)
3036 {
3037 POWER_SRAMSetRegister(sram_index, SRAM_PWR_MODE_MPU_CODE);
3038 // Wait at least 944.90 ns (worst case, from gf40rfnv_nxp_ehlvsram_008192x032bw4c04_mh_pt_m7)
3039 POWER_SRAMPowerUpDelay(); // wait about 1 us
3040 POWER_SRAMSetRegister(sram_index, SRAM_PWR_MODE_ACT_CODE);
3041 }
3042
3043 /**
3044 * brief
3045 * return
3046 */
POWER_SRAMDeepSleepToActive(power_sram_index_t sram_index)3047 static void POWER_SRAMDeepSleepToActive(power_sram_index_t sram_index)
3048 {
3049 POWER_SRAMSetRegister(sram_index, SRAM_PWR_MODE_FPU_CODE);
3050 // Wait at least 707.30 ns (worst case, from gf40rfnv_nxp_ehlvsram_008192x032bw4c04_mh_pt_m7)
3051 POWER_SRAMPowerUpDelay(); // wait about 1 us
3052 POWER_SRAMSetRegister(sram_index, SRAM_PWR_MODE_ACT_CODE);
3053 }
3054
3055 /**
3056 * brief
3057 * return
3058 */
POWER_SRAMShutDownToActive(power_sram_index_t sram_index)3059 static void POWER_SRAMShutDownToActive(power_sram_index_t sram_index)
3060 {
3061 POWER_SRAMSetRegister(sram_index, SRAM_PWR_MODE_FPU_CODE);
3062 // Wait at least 382.80 ns (worst case, from gf40rfnv_nxp_ehlvsram_008192x032bw4c04_mh_pt_m7)
3063 POWER_SRAMPowerUpDelay(); // wait about 1 us
3064 POWER_SRAMSetRegister(sram_index, SRAM_PWR_MODE_ACT_CODE);
3065 }
3066
3067 /**
3068 * brief
3069 * return
3070 */
POWER_SetSystemClock12MHZ(void)3071 static void POWER_SetSystemClock12MHZ(void)
3072 {
3073 if ((SYSCON->MAINCLKSELA != 0UL) || (SYSCON->MAINCLKSELB != 0UL) ||
3074 ((SYSCON->AHBCLKDIV & SYSCON_AHBCLKDIV_DIV_MASK) != 0UL))
3075 {
3076 /* The System is NOT running at 12 MHz: so switch the system on 12 MHz clock */
3077 /* IMPORTANT NOTE : The assumption here is that before calling any Low Power API
3078 * the system will be running at a frequency higher or equal to 12 MHz.
3079 */
3080 uint32_t flash_int_enable_reg;
3081 uint32_t num_wait_states = 1; /* Default to the maximum number of wait states */
3082
3083 /* Switch main clock to FRO12MHz ( the order of the 5 settings below is critical) */
3084 SYSCON->MAINCLKSELA = SYSCON_MAINCLKSELA_SEL(0); /* Main clock A source select : FRO 12 MHz clock */
3085 SYSCON->MAINCLKSELB = SYSCON_MAINCLKSELB_SEL(0); /* Main clock B source select : Main Clock A */
3086 SYSCON->AHBCLKDIV = SYSCON_AHBCLKDIV_DIV(0); /* Main clock divided by 1 */
3087
3088 /* Adjust FMC waiting time cycles (num_wait_states) and disable PREFETCH
3089 * NOTE : PREFETCH disable MUST BE DONE BEFORE the flash command below.
3090 */
3091 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
3092 SYSCON->FMCCR = (SYSCON->FMCCR & (~SYSCON_FMCCR_FLASHTIM_MASK) & (~SYSCON_FMCCR_PREFEN_MASK)) |
3093 SYSCON_FMCCR_FLASHTIM(num_wait_states);
3094 /* Adjust Flash Controller waiting time */
3095 flash_int_enable_reg = FLASH->INTEN; /* Save INT_ENABLE register. */
3096 FLASH->INTEN_CLR = 0x1F; /* Disable all interrupt */
3097 FLASH->INTSTAT_CLR = 0x1F; /* Clear all status flags */
3098 #else
3099 SYSCON->FMCCR = (SYSCON->FMCCR & (~SYSCON_FMCCR_FMCTIM_MASK) & (~SYSCON_FMCCR_PREFEN_MASK)) |
3100 SYSCON_FMCCR_FMCTIM(num_wait_states);
3101 /* Adjust Flash Controller waiting time */
3102 flash_int_enable_reg = FLASH->INT_ENABLE; /* Save INT_ENABLE register. */
3103 FLASH->INT_CLR_ENABLE = 0x1F; /* Disable all interrupt */
3104 FLASH->INT_CLR_STATUS = 0x1F; /* Clear all status flags */
3105 #endif
3106
3107 FLASH->DATAW[0] = num_wait_states;
3108 FLASH->CMD = 0x2; /* CMD_SET_READ_MODE */
3109
3110 #if (defined(LPC55S36_SERIES) || defined(LPC5536_SERIES) || defined(LPC5534_SERIES))
3111 /* Wait until the cmd is completed (without error) */
3112 while (0UL == (FLASH->INTSTAT & FLASH_INTSTAT_DONE_MASK))
3113 {
3114 }
3115 FLASH->INTSTAT_CLR = 0x1F; /* Clear all status flags, then ... */
3116 FLASH->INTEN_SET = flash_int_enable_reg; /* ... restore INT_ENABLE register. */
3117 #else
3118 /* Wait until the cmd is completed (without error) */
3119 while (!(FLASH->INT_STATUS & FLASH_INT_STATUS_DONE_MASK))
3120 {
3121 }
3122 FLASH->INT_CLR_STATUS = 0x1F; /* Clear all status flags, then ... */
3123 FLASH->INT_SET_ENABLE = flash_int_enable_reg; /* ... restore INT_ENABLE register. */
3124 #endif
3125
3126 POWER_SetSystemPowerProfile(
3127 V_SYSTEM_POWER_PROFILE_LOW); /* Align DCDC/LDO_CORE Power profile with the 12 MHz frequency */
3128 }
3129 else
3130 {
3131 /* The System is already running at 12 MHz: so disable FMC PREFETCH feature only */
3132 SYSCON->FMCCR = SYSCON->FMCCR & (~SYSCON_FMCCR_PREFEN_MASK);
3133 }
3134 }
3135