1 /******************************************************************************
2  *
3  * Copyright (C) 2022-2023 Maxim Integrated Products, Inc. (now owned by
4  * Analog Devices, Inc.),
5  * Copyright (C) 2023-2024 Analog Devices, Inc.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  ******************************************************************************/
20 
21 /* **** Includes **** */
22 #include "lp.h"
23 #include "pwrseq_regs.h"
24 #include "mxc_errors.h"
25 #include "gcr_regs.h"
26 #include "usbhs_regs.h"
27 #include "mxc_sys.h"
28 
29 /* **** Variable Declaration **** */
MXC_LP_ClearWakeStatus(void)30 void MXC_LP_ClearWakeStatus(void)
31 {
32     /* Write 1 to clear */
33     MXC_PWRSEQ->gpio0_wk_fl = 0xFFFFFFFF;
34     MXC_PWRSEQ->gpio1_wk_fl = 0xFFFFFFFF;
35     MXC_PWRSEQ->gpio2_wk_fl = 0xFFFFFFFF;
36     MXC_PWRSEQ->gpio3_wk_fl = 0xFFFFFFFF;
37     MXC_PWRSEQ->usb_wk_fl = 0xFFFFFFFF;
38 }
39 
40 /* ************************************************************************** */
MXC_LP_EnableROM(void)41 void MXC_LP_EnableROM(void)
42 {
43     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_ROMSD;
44 }
45 
46 /* ************************************************************************** */
MXC_LP_DisableROM(void)47 void MXC_LP_DisableROM(void)
48 {
49     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_ROMSD;
50 }
51 
52 /* ************************************************************************** */
MXC_LP_EnableUSBFIFO(void)53 void MXC_LP_EnableUSBFIFO(void)
54 {
55     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_USBFIFOSD;
56 }
57 
58 /* ************************************************************************** */
MXC_LP_DisableUSBFIFO(void)59 void MXC_LP_DisableUSBFIFO(void)
60 {
61     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_USBFIFOSD;
62 }
63 
64 /* ************************************************************************** */
MXC_LP_EnableCryptoRAM(void)65 void MXC_LP_EnableCryptoRAM(void)
66 {
67     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_CRYPTOSD;
68 }
69 
70 /* ************************************************************************** */
MXC_LP_DisableCryptoRAM(void)71 void MXC_LP_DisableCryptoRAM(void)
72 {
73     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_CRYPTOSD;
74 }
75 
76 /* ************************************************************************** */
MXC_LP_EnableSCache(void)77 void MXC_LP_EnableSCache(void)
78 {
79     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_SCACHESD;
80 }
81 
82 /* ************************************************************************** */
MXC_LP_DisableSCache(void)83 void MXC_LP_DisableSCache(void)
84 {
85     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_SCACHESD;
86 }
87 
88 /* ************************************************************************** */
MXC_LP_EnableICacheXIP(void)89 void MXC_LP_EnableICacheXIP(void)
90 {
91     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_ICACHEXIPSD;
92 }
93 
94 /* ************************************************************************** */
MXC_LP_DisableICacheXIP(void)95 void MXC_LP_DisableICacheXIP(void)
96 {
97     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_ICACHEXIPSD;
98 }
99 
100 /* ************************************************************************** */
MXC_LP_EnableICache(void)101 void MXC_LP_EnableICache(void)
102 {
103     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_ICACHESD;
104 }
105 
106 /* ************************************************************************** */
MXC_LP_DisableICache(void)107 void MXC_LP_DisableICache(void)
108 {
109     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_ICACHESD;
110 }
111 
112 /* ************************************************************************** */
MXC_LP_EnableSRAM6(void)113 void MXC_LP_EnableSRAM6(void)
114 {
115     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_SRAM6SD;
116 }
117 
118 /* ************************************************************************** */
MXC_LP_DisableSRAM6(void)119 void MXC_LP_DisableSRAM6(void)
120 {
121     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_SRAM6SD;
122 }
123 
124 /* ************************************************************************** */
MXC_LP_EnableSRAM5(void)125 void MXC_LP_EnableSRAM5(void)
126 {
127     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_SRAM5SD;
128 }
129 
130 /* ************************************************************************** */
MXC_LP_DisableSRAM5(void)131 void MXC_LP_DisableSRAM5(void)
132 {
133     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_SRAM5SD;
134 }
135 
136 /* ************************************************************************** */
MXC_LP_EnableSRAM4(void)137 void MXC_LP_EnableSRAM4(void)
138 {
139     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_SRAM4SD;
140 }
141 
142 /* ************************************************************************** */
MXC_LP_DisableSRAM4(void)143 void MXC_LP_DisableSRAM4(void)
144 {
145     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_SRAM4SD;
146 }
147 
148 /* ************************************************************************** */
MXC_LP_EnableSRAM3(void)149 void MXC_LP_EnableSRAM3(void)
150 {
151     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_SRAM3SD;
152 }
153 
154 /* ************************************************************************** */
MXC_LP_DisableSRAM3(void)155 void MXC_LP_DisableSRAM3(void)
156 {
157     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_SRAM3SD;
158 }
159 
160 /* ************************************************************************** */
MXC_LP_EnableSRAM2(void)161 void MXC_LP_EnableSRAM2(void)
162 {
163     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_SRAM2SD;
164 }
165 
166 /* ************************************************************************** */
MXC_LP_DisableSRAM2(void)167 void MXC_LP_DisableSRAM2(void)
168 {
169     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_SRAM2SD;
170 }
171 
172 /* ************************************************************************** */
MXC_LP_EnableSRAM1(void)173 void MXC_LP_EnableSRAM1(void)
174 {
175     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_SRAM1SD;
176 }
177 
178 /* ************************************************************************** */
MXC_LP_DisableSRAM1(void)179 void MXC_LP_DisableSRAM1(void)
180 {
181     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_SRAM1SD;
182 }
183 
184 /* ************************************************************************** */
MXC_LP_EnableSRAM0(void)185 void MXC_LP_EnableSRAM0(void)
186 {
187     MXC_PWRSEQ->mem_pwr &= ~MXC_F_PWRSEQ_MEM_PWR_SRAM0SD;
188 }
189 
190 /* ************************************************************************** */
MXC_LP_DisableSRAM0(void)191 void MXC_LP_DisableSRAM0(void)
192 {
193     MXC_PWRSEQ->mem_pwr |= MXC_F_PWRSEQ_MEM_PWR_SRAM0SD;
194 }
195 
196 /* ************************************************************************** */
MXC_LP_EnableROMLightSleep(void)197 void MXC_LP_EnableROMLightSleep(void)
198 {
199     if (ChipRevision > 0xA1) {
200         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_ROMLS_LIGHT_SLEEP;
201     } else {
202         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_ROMLS_LIGHT_SLEEP >> 3);
203         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
204     }
205 }
206 
207 /* ************************************************************************** */
MXC_LP_DisableROMLightSleep(void)208 void MXC_LP_DisableROMLightSleep(void)
209 {
210     if (ChipRevision > 0xA1) {
211         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_ROMLS_LIGHT_SLEEP);
212     } else {
213         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_ROMLS_LIGHT_SLEEP >> 3);
214         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
215     }
216 }
217 
218 /* ************************************************************************** */
MXC_LP_EnableUSBFIFOLightSleep(void)219 void MXC_LP_EnableUSBFIFOLightSleep(void)
220 {
221     if (ChipRevision > 0xA1) {
222         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_USBLS_LIGHT_SLEEP;
223     } else {
224         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_USBLS_LIGHT_SLEEP >> 3);
225         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
226     }
227 }
228 
229 /* ************************************************************************** */
MXC_LP_DisableUSBFIFOLightSleep(void)230 void MXC_LP_DisableUSBFIFOLightSleep(void)
231 {
232     if (ChipRevision > 0xA1) {
233         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_USBLS_LIGHT_SLEEP);
234     } else {
235         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_USBLS_LIGHT_SLEEP >> 3);
236         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
237     }
238 }
239 
240 /* ************************************************************************** */
MXC_LP_EnableCryptoRAMLightSleep(void)241 void MXC_LP_EnableCryptoRAMLightSleep(void)
242 {
243     if (ChipRevision > 0xA1) {
244         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_CRYPTOLS_LIGHT_SLEEP;
245     } else {
246         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_CRYPTOLS_LIGHT_SLEEP >> 3);
247         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
248     }
249 }
250 
MXC_LP_DisableCryptoRAMLightSleep(void)251 void MXC_LP_DisableCryptoRAMLightSleep(void)
252 {
253     if (ChipRevision > 0xA1) {
254         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_CRYPTOLS_LIGHT_SLEEP);
255     } else {
256         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_CRYPTOLS_LIGHT_SLEEP >> 3);
257         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
258     }
259 }
260 
261 /* ************************************************************************** */
MXC_LP_EnableSCacheLightSleep(void)262 void MXC_LP_EnableSCacheLightSleep(void)
263 {
264     if (ChipRevision > 0xA1) {
265         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_SCACHELS_LIGHT_SLEEP);
266     } else {
267         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_SCACHELS_LIGHT_SLEEP >> 3);
268         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
269     }
270 }
271 
272 /* ************************************************************************** */
MXC_LP_DisableSCacheLightSleep(void)273 void MXC_LP_DisableSCacheLightSleep(void)
274 {
275     if (ChipRevision > 0xA1) {
276         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SCACHELS_LIGHT_SLEEP);
277     } else {
278         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SCACHELS_LIGHT_SLEEP >> 3);
279         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
280     }
281 }
282 
283 /* ************************************************************************** */
MXC_LP_EnableICacheXIPLightSleep(void)284 void MXC_LP_EnableICacheXIPLightSleep(void)
285 {
286     if (ChipRevision > 0xA1) {
287         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_ICACHEXIPLS_LIGHT_SLEEP;
288     } else {
289         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_ICACHEXIPLS_LIGHT_SLEEP >> 3);
290         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
291     }
292 }
293 
294 /* ************************************************************************** */
MXC_LP_DisableICacheXIPLightSleep(void)295 void MXC_LP_DisableICacheXIPLightSleep(void)
296 {
297     if (ChipRevision > 0xA1) {
298         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_ICACHEXIPLS_LIGHT_SLEEP);
299     } else {
300         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_ICACHEXIPLS_LIGHT_SLEEP >> 3);
301         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
302     }
303 }
304 
305 /* ************************************************************************** */
MXC_LP_EnableICacheLightSleep(void)306 void MXC_LP_EnableICacheLightSleep(void)
307 {
308     if (ChipRevision > 0xA1) {
309         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_ICACHELS_LIGHT_SLEEP;
310     } else {
311         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_ICACHELS_LIGHT_SLEEP >> 3);
312         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
313     }
314 }
315 
316 /* ************************************************************************** */
MXC_LP_DisableICacheLightSleep(void)317 void MXC_LP_DisableICacheLightSleep(void)
318 {
319     if (ChipRevision > 0xA1) {
320         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_ICACHELS_LIGHT_SLEEP);
321     } else {
322         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_ICACHELS_LIGHT_SLEEP >> 3);
323         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
324     }
325 }
326 
327 /* ************************************************************************** */
MXC_LP_EnableSysRAM6LightSleep(void)328 void MXC_LP_EnableSysRAM6LightSleep(void)
329 {
330     if (ChipRevision > 0xA1) {
331         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_SYSRAM6LS_LIGHT_SLEEP;
332     } else {
333         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_SYSRAM6LS_LIGHT_SLEEP >> 3);
334         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
335     }
336 }
337 
338 /* ************************************************************************** */
MXC_LP_DisableSysRAM6LightSleep(void)339 void MXC_LP_DisableSysRAM6LightSleep(void)
340 {
341     if (ChipRevision > 0xA1) {
342         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM6LS_LIGHT_SLEEP);
343     } else {
344         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM6LS_LIGHT_SLEEP >> 3);
345         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
346     }
347 }
348 
349 /* ************************************************************************** */
MXC_LP_EnableSysRAM5LightSleep(void)350 void MXC_LP_EnableSysRAM5LightSleep(void)
351 {
352     if (ChipRevision > 0xA1) {
353         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_SYSRAM5LS_LIGHT_SLEEP;
354     } else {
355         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_SYSRAM5LS_LIGHT_SLEEP >> 3);
356         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
357     }
358 }
359 
360 /* ************************************************************************** */
MXC_LP_DisableSysRAM5LightSleep(void)361 void MXC_LP_DisableSysRAM5LightSleep(void)
362 {
363     if (ChipRevision > 0xA1) {
364         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM5LS_LIGHT_SLEEP);
365     } else {
366         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM5LS_LIGHT_SLEEP >> 3);
367         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
368     }
369 }
370 
371 /* ************************************************************************** */
MXC_LP_EnableSysRAM4LightSleep(void)372 void MXC_LP_EnableSysRAM4LightSleep(void)
373 {
374     if (ChipRevision > 0xA1) {
375         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_SYSRAM4LS_LIGHT_SLEEP;
376 
377     } else {
378         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_SYSRAM4LS_LIGHT_SLEEP >> 3);
379         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
380     }
381 }
382 
383 /* ************************************************************************** */
MXC_LP_DisableSysRAM4LightSleep(void)384 void MXC_LP_DisableSysRAM4LightSleep(void)
385 {
386     if (ChipRevision > 0xA1) {
387         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM4LS_LIGHT_SLEEP);
388     } else {
389         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM4LS_LIGHT_SLEEP >> 3);
390         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
391     }
392 }
393 
394 /* ************************************************************************** */
MXC_LP_EnableSysRAM3LightSleep(void)395 void MXC_LP_EnableSysRAM3LightSleep(void)
396 {
397     if (ChipRevision > 0xA1) {
398         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_SYSRAM3LS_LIGHT_SLEEP;
399     } else {
400         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_SYSRAM3LS_LIGHT_SLEEP >> 3);
401         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
402     }
403 }
404 
405 /* ************************************************************************** */
MXC_LP_DisableSysRAM3LightSleep(void)406 void MXC_LP_DisableSysRAM3LightSleep(void)
407 {
408     if (ChipRevision > 0xA1) {
409         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM3LS_LIGHT_SLEEP);
410     } else {
411         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM3LS_LIGHT_SLEEP >> 3);
412         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
413     }
414 }
415 
416 /* ************************************************************************** */
MXC_LP_EnableSysRAM2LightSleep(void)417 void MXC_LP_EnableSysRAM2LightSleep(void)
418 {
419     if (ChipRevision > 0xA1) {
420         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_SYSRAM2LS_LIGHT_SLEEP;
421     } else {
422         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_SYSRAM2LS_LIGHT_SLEEP >> 3);
423         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
424     }
425 }
426 
427 /* ************************************************************************** */
MXC_LP_DisableSysRAM2LightSleep(void)428 void MXC_LP_DisableSysRAM2LightSleep(void)
429 {
430     if (ChipRevision > 0xA1) {
431         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM2LS_LIGHT_SLEEP);
432     } else {
433         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM2LS_LIGHT_SLEEP >> 3);
434         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
435     }
436 }
437 
438 /* ************************************************************************** */
MXC_LP_EnableSysRAM1LightSleep(void)439 void MXC_LP_EnableSysRAM1LightSleep(void)
440 {
441     if (ChipRevision > 0xA1) {
442         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_SYSRAM1LS_LIGHT_SLEEP;
443     } else {
444         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_SYSRAM1LS_LIGHT_SLEEP >> 3);
445         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
446     }
447 }
448 
449 /* ************************************************************************** */
MXC_LP_DisableSysRAM1LightSleep(void)450 void MXC_LP_DisableSysRAM1LightSleep(void)
451 {
452     if (ChipRevision > 0xA1) {
453     } else {
454         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM1LS_LIGHT_SLEEP >> 3);
455         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
456     }
457 }
458 
459 /* ************************************************************************** */
MXC_LP_EnableSysRAM0LightSleep(void)460 void MXC_LP_EnableSysRAM0LightSleep(void)
461 {
462     if (ChipRevision > 0xA1) {
463         MXC_GCR->mem_clk |= MXC_S_GCR_MEM_CLK_SYSRAM0LS_LIGHT_SLEEP;
464     } else {
465         MXC_GCR->mem_clk |= (MXC_S_GCR_MEM_CLK_SYSRAM0LS_LIGHT_SLEEP >> 3);
466         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
467     }
468 }
469 
470 /* ************************************************************************** */
MXC_LP_DisableSysRAM0LightSleep(void)471 void MXC_LP_DisableSysRAM0LightSleep(void)
472 {
473     if (ChipRevision > 0xA1) {
474         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM0LS_LIGHT_SLEEP);
475     } else {
476         MXC_GCR->mem_clk &= ~(MXC_S_GCR_MEM_CLK_SYSRAM0LS_LIGHT_SLEEP >> 3);
477         /* Writes to the register have a flaw in HW logic.  All writes to this register must be offset by 3 bits. */
478     }
479 }
480 
481 /* ************************************************************************** */
MXC_LP_EnableUSBWakeup(mxc_lp_usb_event_t wu_evt)482 void MXC_LP_EnableUSBWakeup(mxc_lp_usb_event_t wu_evt)
483 {
484     MXC_GCR->pmr |= MXC_F_GCR_PMR_USBWKEN;
485     MXC_PWRSEQ->usb_wk_en |= wu_evt;
486 }
487 
488 /* ************************************************************************** */
MXC_LP_DisableUSBWakeup(mxc_lp_usb_event_t wu_evt)489 void MXC_LP_DisableUSBWakeup(mxc_lp_usb_event_t wu_evt)
490 {
491     MXC_PWRSEQ->usb_wk_en &= ~wu_evt;
492     if ((MXC_PWRSEQ->usb_wk_en &
493          (MXC_F_PWRSEQ_USB_WK_EN_USBLSWKEN | MXC_F_PWRSEQ_USB_WK_EN_USBVBUSWKEN)) == 0) {
494         MXC_GCR->pmr &= ~MXC_F_GCR_PMR_USBWKEN;
495     }
496 }
497 
498 /* ************************************************************************** */
MXC_LP_EnableRTCAlarmWakeup(void)499 void MXC_LP_EnableRTCAlarmWakeup(void)
500 {
501     MXC_GCR->pmr |= MXC_F_GCR_PMR_RTCWKEN;
502 }
503 
504 /* ************************************************************************** */
MXC_LP_DisableRTCAlarmWakeup(void)505 void MXC_LP_DisableRTCAlarmWakeup(void)
506 {
507     MXC_GCR->pmr &= ~MXC_F_GCR_PMR_RTCWKEN;
508 }
509 
510 /* ************************************************************************** */
MXC_LP_EnableGPIOWakeup(mxc_gpio_cfg_t * wu_pins)511 void MXC_LP_EnableGPIOWakeup(mxc_gpio_cfg_t *wu_pins)
512 {
513     MXC_GCR->pmr |= MXC_F_GCR_PMR_GPIOWKEN;
514     switch (MXC_GPIO_GET_IDX(wu_pins->port)) {
515     case 0:
516         MXC_PWRSEQ->gpio0_wk_en |= wu_pins->mask;
517         break;
518     case 1:
519         MXC_PWRSEQ->gpio1_wk_en |= wu_pins->mask;
520         break;
521     case 2:
522         MXC_PWRSEQ->gpio2_wk_en |= wu_pins->mask;
523         break;
524     case 3:
525         MXC_PWRSEQ->gpio3_wk_en |= wu_pins->mask;
526         break;
527     }
528 }
529 
530 /* ************************************************************************** */
MXC_LP_DisableGPIOWakeup(mxc_gpio_cfg_t * wu_pins)531 void MXC_LP_DisableGPIOWakeup(mxc_gpio_cfg_t *wu_pins)
532 {
533     switch (MXC_GPIO_GET_IDX(wu_pins->port)) {
534     case 0:
535         MXC_PWRSEQ->gpio0_wk_en &= ~wu_pins->mask;
536         break;
537     case 1:
538         MXC_PWRSEQ->gpio1_wk_en &= ~wu_pins->mask;
539         break;
540     case 2:
541         MXC_PWRSEQ->gpio2_wk_en &= ~wu_pins->mask;
542         break;
543     case 3:
544         MXC_PWRSEQ->gpio3_wk_en &= ~wu_pins->mask;
545         break;
546     }
547 
548     if ((MXC_PWRSEQ->gpio0_wk_en == 0) && (MXC_PWRSEQ->gpio1_wk_en == 0) &&
549         (MXC_PWRSEQ->gpio2_wk_en == 0) && (MXC_PWRSEQ->gpio3_wk_en == 0)) {
550         MXC_GCR->pmr &= ~MXC_F_GCR_PMR_GPIOWKEN;
551     }
552 }
553 
554 /* ************************************************************************** */
MXC_LP_EnterSleepMode(void)555 void MXC_LP_EnterSleepMode(void)
556 {
557     MXC_LP_ClearWakeStatus();
558 
559     /* Clear SLEEPDEEP bit */
560     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
561 
562     /* Go into Sleep mode and wait for an interrupt to wake the processor */
563     __WFI();
564 }
565 
566 /* ************************************************************************** */
MXC_LP_EnterBackgroundMode(void)567 void MXC_LP_EnterBackgroundMode(void)
568 {
569     int restoreSysClock = 0;
570     int restoreHBClock = 0;
571     int restoreSCacheClock = 0;
572     int restoreSPIXClock = 0;
573     uint32_t lpcn = 0;
574     MXC_LP_ClearWakeStatus();
575 
576     //make sure power monitors are in reset mode.
577     lpcn = MXC_PWRSEQ->ctrl &
578            ~(MXC_F_PWRSEQ_CTRL_VDDIOHMD | MXC_F_PWRSEQ_CTRL_VCOREMD | MXC_F_PWRSEQ_CTRL_PORVDDIOMD |
579              MXC_F_PWRSEQ_CTRL_VDDBMD | MXC_F_PWRSEQ_CTRL_VRTCMD | MXC_F_PWRSEQ_CTRL_PORVDDIOHMD |
580              MXC_F_PWRSEQ_CTRL_VDDAMD | MXC_F_PWRSEQ_CTRL_VDDIOMD);
581 
582     /* Set background mode enable. */
583     lpcn |= MXC_F_PWRSEQ_CTRL_BKGRND;
584     MXC_PWRSEQ->ctrl = lpcn;
585 
586     /* Set SLEEPDEEP bit */
587     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
588 
589     /* Cannot enter BACKGROUND mode with a system clock faster than 2x of crypto clock. */
590     /* Divide down if necessary. */
591     if ((MXC_GCR->clk_ctrl & MXC_F_GCR_CLK_CTRL_SYSOSC_SEL) ==
592         MXC_S_GCR_CLK_CTRL_SYSOSC_SEL_HIRC96) {
593         if ((MXC_GCR->clk_ctrl & MXC_F_GCR_CLK_CTRL_SYSCLK_PRESCALE) ==
594             MXC_S_GCR_CLK_CTRL_SYSCLK_PRESCALE_DIV1) {
595             restoreSysClock = 1;
596             MXC_SETFIELD(MXC_GCR->clk_ctrl, MXC_F_GCR_CLK_CTRL_SYSCLK_PRESCALE,
597                          MXC_S_GCR_CLK_CTRL_SYSCLK_PRESCALE_DIV2);
598         }
599     }
600     /* These clocks need to be on during BACKGROUND mode. */
601     if (!MXC_SYS_IsClockEnabled(MXC_SYS_PERIPH_CLOCK_HBC)) {
602         restoreHBClock = 1;
603         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_HBC);
604     }
605     if (!MXC_SYS_IsClockEnabled(MXC_SYS_PERIPH_CLOCK_SCACHE)) {
606         restoreSCacheClock = 1;
607         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SCACHE);
608     }
609     if (!MXC_SYS_IsClockEnabled(MXC_SYS_PERIPH_CLOCK_SPIXIPR)) {
610         restoreSPIXClock = 1;
611         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPIXIPR);
612     }
613 
614     /* Go into Sleep mode and wait for an interrupt to wake the processor */
615     __WFI();
616 
617     /* Restore to the original clock settings. */
618     if (restoreSysClock) {
619         MXC_SETFIELD(MXC_GCR->clk_ctrl, MXC_F_GCR_CLK_CTRL_SYSCLK_PRESCALE,
620                      MXC_S_GCR_CLK_CTRL_SYSCLK_PRESCALE_DIV1);
621     }
622     if (restoreHBClock) {
623         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_HBC);
624     }
625     if (restoreSCacheClock) {
626         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SCACHE);
627     }
628     if (restoreSPIXClock) {
629         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPIXIPR);
630     }
631 }
632 
633 /* ************************************************************************** */
MXC_LP_EnterDeepSleepMode(void)634 void MXC_LP_EnterDeepSleepMode(void)
635 {
636     int restoreHIRC = 0;
637     int restoreHBClock = 0;
638     int restoreSCacheClock = 0;
639     int restoreSPIXClock = 0;
640     uint32_t lpcn = 0;
641 
642     MXC_LP_ClearWakeStatus();
643 
644     //make sure power monitors are in reset mode.
645     lpcn = MXC_PWRSEQ->ctrl &
646            ~(MXC_F_PWRSEQ_CTRL_VDDIOHMD | MXC_F_PWRSEQ_CTRL_VCOREMD | MXC_F_PWRSEQ_CTRL_PORVDDIOMD |
647              MXC_F_PWRSEQ_CTRL_VDDBMD | MXC_F_PWRSEQ_CTRL_VRTCMD | MXC_F_PWRSEQ_CTRL_PORVDDIOHMD |
648              MXC_F_PWRSEQ_CTRL_VDDAMD | MXC_F_PWRSEQ_CTRL_VDDIOMD);
649 
650     /* Clear background mode enable, enable power failure monitor, Bandgap is always on. */
651     lpcn &= ~(MXC_F_PWRSEQ_CTRL_BKGRND | MXC_F_PWRSEQ_CTRL_BGOFF | MXC_F_PWRSEQ_CTRL_PORVCOREMD);
652     MXC_PWRSEQ->ctrl = lpcn;
653 
654     /* Set SLEEPDEEP bit */
655     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
656 
657     /* Enable the clocks that must be turned on during DEEPSLEEP */
658     if ((MXC_GCR->clk_ctrl & MXC_F_GCR_CLK_CTRL_CRYPTO_EN) == 0) {
659         restoreHIRC = 1;
660         MXC_GCR->clk_ctrl |= MXC_F_GCR_CLK_CTRL_CRYPTO_EN;
661     }
662     if (!MXC_SYS_IsClockEnabled(MXC_SYS_PERIPH_CLOCK_HBC)) {
663         restoreHBClock = 1;
664         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_HBC);
665     }
666     if (!MXC_SYS_IsClockEnabled(MXC_SYS_PERIPH_CLOCK_SCACHE)) {
667         restoreSCacheClock = 1;
668         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SCACHE);
669     }
670     if (!MXC_SYS_IsClockEnabled(MXC_SYS_PERIPH_CLOCK_SPIXIPR)) {
671         restoreSPIXClock = 1;
672         MXC_SYS_ClockEnable(MXC_SYS_PERIPH_CLOCK_SPIXIPR);
673     }
674 
675     /* Go into Deepsleep mode and wait for an interrupt to wake the processor */
676     __WFI();
677 
678     /* Disable the clocks that were disabled prior to calling this function. */
679     if (restoreHIRC) {
680         MXC_GCR->clk_ctrl &= ~MXC_F_GCR_CLK_CTRL_CRYPTO_EN;
681     }
682     if (restoreHBClock) {
683         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_HBC);
684     }
685     if (restoreSCacheClock) {
686         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SCACHE);
687     }
688     if (restoreSPIXClock) {
689         MXC_SYS_ClockDisable(MXC_SYS_PERIPH_CLOCK_SPIXIPR);
690     }
691 }
692 
693 /* ************************************************************************** */
MXC_LP_EnterBackupMode(void)694 void MXC_LP_EnterBackupMode(void)
695 {
696     MXC_LP_ClearWakeStatus();
697 
698     MXC_GCR->pmr &= ~MXC_F_GCR_PMR_MODE;
699     MXC_GCR->pmr |= MXC_S_GCR_PMR_MODE_BACKUP;
700     while (1) {}
701 }
702 
703 /* ************************************************************************** */
MXC_LP_USBClearPONRST(void)704 void MXC_LP_USBClearPONRST(void)
705 {
706     // This register is used during the power-on stage or used as a global reset
707     // for the USB block. For this case, the PONRST is used as a global reset
708     // and setting this register to 0 will force the USB block to its initial
709     // state - where the operating current is at its minimum.
710     MXC_USBHS->m31_phy_ponrst = 0;
711 }
712 
713 /* ************************************************************************** */
MXC_LP_USBSetPONRST(void)714 void MXC_LP_USBSetPONRST(void)
715 {
716     // Re-enables the clock generator and the USB block if PONRST was used as
717     // a global reset for operating in low power modes.
718     MXC_USBHS->m31_phy_ponrst = 1;
719 }
720