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