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