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 #include "mxc_device.h"
22 #include "mxc_assert.h"
23 #include "mxc_sys.h"
24 #include "gcr_regs.h"
25 #include "lp.h"
26 
MXC_LP_EnterSleepMode(void)27 void MXC_LP_EnterSleepMode(void)
28 {
29     MXC_LP_ClearWakeStatus();
30 
31     // Clear SLEEPDEEP bit
32     SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
33 
34     // Go into Sleep mode and wait for an interrupt to wake the processor
35     __WFI();
36 }
37 
MXC_LP_EnterDeepSleepMode(void)38 void MXC_LP_EnterDeepSleepMode(void)
39 {
40     MXC_LP_ClearWakeStatus();
41 
42     // Set SLEEPDEEP bit
43     MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE;
44     MXC_GCR->pm |= MXC_S_GCR_PM_MODE_DEEPSLEEP;
45     SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
46 
47     // Go into Deepsleep mode and wait for an interrupt to wake the processor
48     __WFI();
49 }
50 
MXC_LP_EnterBackupMode(void)51 void MXC_LP_EnterBackupMode(void)
52 {
53     MXC_LP_ClearWakeStatus();
54 
55     MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE;
56     MXC_GCR->pm |= MXC_S_GCR_PM_MODE_BACKUP;
57 
58     while (1) {}
59     // Should never reach this line - device will jump to backup vector on exit from background mode.
60 }
61 
MXC_LP_EnterShutDownMode(void)62 void MXC_LP_EnterShutDownMode(void)
63 {
64     MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE;
65     MXC_GCR->pm |= MXC_S_GCR_PM_MODE_SHUTDOWN;
66 
67     while (1) {}
68     // Should never reach this line - device will reset on exit from shutdown mode.
69 }
70 
MXC_LP_SetOVR(mxc_lp_ovr_t ovr)71 void MXC_LP_SetOVR(mxc_lp_ovr_t ovr)
72 {
73     //not supported yet
74 }
75 
MXC_LP_RetentionRegEnable(void)76 void MXC_LP_RetentionRegEnable(void)
77 {
78     MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_RETREG_EN;
79 }
80 
MXC_LP_RetentionRegDisable(void)81 void MXC_LP_RetentionRegDisable(void)
82 {
83     MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_RETREG_EN;
84 }
85 
MXC_LP_RetentionRegIsEnabled(void)86 int MXC_LP_RetentionRegIsEnabled(void)
87 {
88     return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_RETREG_EN);
89 }
90 
MXC_LP_BandgapOn(void)91 void MXC_LP_BandgapOn(void)
92 {
93     MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_BG_DIS;
94 }
95 
MXC_LP_BandgapOff(void)96 void MXC_LP_BandgapOff(void)
97 {
98     MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_BG_DIS;
99 }
100 
MXC_LP_BandgapIsOn(void)101 int MXC_LP_BandgapIsOn(void)
102 {
103     return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_BG_DIS);
104 }
105 
MXC_LP_PORVCOREoreMonitorEnable(void)106 void MXC_LP_PORVCOREoreMonitorEnable(void)
107 {
108     MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_VCOREPOR_DIS;
109 }
110 
MXC_LP_PORVCOREoreMonitorDisable(void)111 void MXC_LP_PORVCOREoreMonitorDisable(void)
112 {
113     MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_VCOREPOR_DIS;
114 }
115 
MXC_LP_PORVCOREoreMonitorIsEnabled(void)116 int MXC_LP_PORVCOREoreMonitorIsEnabled(void)
117 {
118     return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_VCOREPOR_DIS);
119 }
120 
MXC_LP_LDOEnable(void)121 void MXC_LP_LDOEnable(void)
122 {
123     MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_LDO_DIS;
124 }
125 
MXC_LP_LDODisable(void)126 void MXC_LP_LDODisable(void)
127 {
128     MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_LDO_DIS;
129 }
130 
MXC_LP_LDOIsEnabled(void)131 int MXC_LP_LDOIsEnabled(void)
132 {
133     return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_LDO_DIS);
134 }
135 
MXC_LP_FastWakeupEnable(void)136 void MXC_LP_FastWakeupEnable(void)
137 {
138     MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_FASTWK_EN;
139 }
140 
MXC_LP_FastWakeupDisable(void)141 void MXC_LP_FastWakeupDisable(void)
142 {
143     MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_FASTWK_EN;
144 }
145 
MXC_LP_FastWakeupIsEnabled(void)146 int MXC_LP_FastWakeupIsEnabled(void)
147 {
148     return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_FASTWK_EN);
149 }
150 
MXC_LP_ClearWakeStatus(void)151 void MXC_LP_ClearWakeStatus(void)
152 {
153     // Write 1 to clear
154     MXC_PWRSEQ->lpwkst0 = 0xFFFFFFFF;
155     MXC_PWRSEQ->lpwkst1 = 0xFFFFFFFF;
156     MXC_PWRSEQ->lpwkst2 = 0xFFFFFFFF;
157     MXC_PWRSEQ->lpwkst3 = 0xFFFFFFFF;
158     MXC_PWRSEQ->lppwkst = 0xFFFFFFFF;
159 }
160 
MXC_LP_EnableGPIOWakeup(mxc_gpio_cfg_t * wu_pins)161 void MXC_LP_EnableGPIOWakeup(mxc_gpio_cfg_t *wu_pins)
162 {
163     MXC_GCR->pm |= MXC_F_GCR_PM_GPIO_WE;
164 
165     switch (1 << MXC_GPIO_GET_IDX(wu_pins->port)) {
166     case MXC_GPIO_PORT_0:
167         MXC_PWRSEQ->lpwken0 |= wu_pins->mask;
168         break;
169 
170     case MXC_GPIO_PORT_1:
171         MXC_PWRSEQ->lpwken1 |= wu_pins->mask;
172         break;
173     case MXC_GPIO_PORT_2:
174         MXC_PWRSEQ->lpwken2 |= wu_pins->mask;
175         break;
176     case MXC_GPIO_PORT_3:
177         MXC_PWRSEQ->lpwken3 |= wu_pins->mask;
178         break;
179     }
180 }
181 
MXC_LP_DisableGPIOWakeup(mxc_gpio_cfg_t * wu_pins)182 void MXC_LP_DisableGPIOWakeup(mxc_gpio_cfg_t *wu_pins)
183 {
184     switch (1 << MXC_GPIO_GET_IDX(wu_pins->port)) {
185     case MXC_GPIO_PORT_0:
186         MXC_PWRSEQ->lpwken0 &= ~wu_pins->mask;
187         break;
188 
189     case MXC_GPIO_PORT_1:
190         MXC_PWRSEQ->lpwken1 &= ~wu_pins->mask;
191         break;
192     case MXC_GPIO_PORT_2:
193         MXC_PWRSEQ->lpwken2 &= ~wu_pins->mask;
194         break;
195     case MXC_GPIO_PORT_3:
196         MXC_PWRSEQ->lpwken3 &= ~wu_pins->mask;
197         break;
198     }
199 
200     if (MXC_PWRSEQ->lpwken3 == 0 && MXC_PWRSEQ->lpwken2 == 0 && MXC_PWRSEQ->lpwken1 == 0 &&
201         MXC_PWRSEQ->lpwken0 == 0) {
202         MXC_GCR->pm &= ~MXC_F_GCR_PM_GPIO_WE;
203     }
204 }
205 
MXC_LP_EnableRTCAlarmWakeup(void)206 void MXC_LP_EnableRTCAlarmWakeup(void)
207 {
208     MXC_GCR->pm |= MXC_F_GCR_PM_RTC_WE;
209 }
210 
MXC_LP_DisableRTCAlarmWakeup(void)211 void MXC_LP_DisableRTCAlarmWakeup(void)
212 {
213     MXC_GCR->pm &= ~MXC_F_GCR_PM_RTC_WE;
214 }
215 
MXC_LP_EnableUSBWakeup(void)216 void MXC_LP_EnableUSBWakeup(void)
217 {
218     MXC_GCR->pm |= MXC_F_GCR_PM_USB_WE;
219 }
220 
MXC_LP_DisableUSBWakeup(void)221 void MXC_LP_DisableUSBWakeup(void)
222 {
223     MXC_GCR->pm &= ~MXC_F_GCR_PM_USB_WE;
224 }
225 
MXC_LP_EnableHA0Wakeup(void)226 void MXC_LP_EnableHA0Wakeup(void)
227 {
228     MXC_GCR->pm |= MXC_F_GCR_PM_HA0_WE;
229 }
230 
MXC_LP_DisablHAA0Wakeup(void)231 void MXC_LP_DisablHAA0Wakeup(void)
232 {
233     MXC_GCR->pm &= ~MXC_F_GCR_PM_HA0_WE;
234 }
235 
MXC_LP_EnableHA1Wakeup(void)236 void MXC_LP_EnableHA1Wakeup(void)
237 {
238     MXC_GCR->pm |= MXC_F_GCR_PM_HA1_WE;
239 }
240 
MXC_LP_DisableHA1Wakeup(void)241 void MXC_LP_DisableHA1Wakeup(void)
242 {
243     MXC_GCR->pm &= ~MXC_F_GCR_PM_HA1_WE;
244 }
245 
MXC_LP_ConfigDeepSleepClocks(uint32_t mask)246 int MXC_LP_ConfigDeepSleepClocks(uint32_t mask)
247 {
248     if (!(mask & (MXC_F_GCR_PM_NFC_PD | MXC_F_GCR_PM_IBRO_PD | MXC_F_GCR_PM_IPO_PD |
249                   MXC_F_GCR_PM_ISO_PD | MXC_F_GCR_PM_ERFO_PD))) {
250         return E_BAD_PARAM;
251     }
252 
253     MXC_GCR->pm |= mask;
254     return E_NO_ERROR;
255 }
256 
MXC_LP_NFCOscBypassEnable(void)257 void MXC_LP_NFCOscBypassEnable(void)
258 {
259     MXC_GCR->pm |= MXC_F_GCR_PM_XTALBP;
260 }
261 
MXC_LP_NFCOscBypassDisable(void)262 void MXC_LP_NFCOscBypassDisable(void)
263 {
264     MXC_GCR->pm &= ~MXC_F_GCR_PM_XTALBP;
265 }
266 
MXC_LP_NFCOscBypassIsEnabled(void)267 int MXC_LP_NFCOscBypassIsEnabled(void)
268 {
269     return (MXC_GCR->pm & MXC_F_GCR_PM_XTALBP);
270 }
271 
MXC_LP_SysRam0LightSleepEnable(void)272 void MXC_LP_SysRam0LightSleepEnable(void)
273 {
274     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM0LS_EN;
275 }
276 
MXC_LP_SysRam1LightSleepEnable(void)277 void MXC_LP_SysRam1LightSleepEnable(void)
278 {
279     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM1LS_EN;
280 }
281 
MXC_LP_SysRam2LightSleepEnable(void)282 void MXC_LP_SysRam2LightSleepEnable(void)
283 {
284     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM2LS_EN;
285 }
286 
MXC_LP_SysRam3LightSleepEnable(void)287 void MXC_LP_SysRam3LightSleepEnable(void)
288 {
289     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM3LS_EN;
290 }
291 
MXC_LP_SysRam4LightSleepEnable(void)292 void MXC_LP_SysRam4LightSleepEnable(void)
293 {
294     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM4LS_EN;
295 }
296 
MXC_LP_SysRam5LightSleepEnable(void)297 void MXC_LP_SysRam5LightSleepEnable(void)
298 {
299     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM5LS_EN;
300 }
301 
MXC_LP_ICache0LightSleepEnable(void)302 void MXC_LP_ICache0LightSleepEnable(void)
303 {
304     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_ICC0LS_EN;
305 }
306 
MXC_LP_ICacheXIPLightSleepEnable(void)307 void MXC_LP_ICacheXIPLightSleepEnable(void)
308 {
309     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_ICCXIPLS_EN;
310 }
311 
MXC_LP_SRCCLightSleepEnable(void)312 void MXC_LP_SRCCLightSleepEnable(void)
313 {
314     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_SRCCLS_EN;
315 }
316 
MXC_LP_CryptoLightSleepEnable(void)317 void MXC_LP_CryptoLightSleepEnable(void)
318 {
319     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_CRYPTOLS_EN;
320 }
321 
MXC_LP_USBFIFOLightSleepEnable(void)322 void MXC_LP_USBFIFOLightSleepEnable(void)
323 {
324     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_USBLS_EN;
325 }
326 
MXC_LP_ROMLightSleepEnable(void)327 void MXC_LP_ROMLightSleepEnable(void)
328 {
329     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_ROMLS_EN;
330 }
331 
MXC_LP_SysRam0LightSleepDisable(void)332 void MXC_LP_SysRam0LightSleepDisable(void)
333 {
334     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM0LS_EN;
335 }
336 
MXC_LP_SysRam1LightSleepDisable(void)337 void MXC_LP_SysRam1LightSleepDisable(void)
338 {
339     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM1LS_EN;
340 }
341 
MXC_LP_SysRam2LightSleepDisable(void)342 void MXC_LP_SysRam2LightSleepDisable(void)
343 {
344     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM2LS_EN;
345 }
346 
MXC_LP_SysRam3LightSleepDisable(void)347 void MXC_LP_SysRam3LightSleepDisable(void)
348 {
349     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM3LS_EN;
350 }
351 
MXC_LP_SysRam4LightSleepDisable(void)352 void MXC_LP_SysRam4LightSleepDisable(void)
353 {
354     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM4LS_EN;
355 }
356 
MXC_LP_SysRam5LightSleepDisable(void)357 void MXC_LP_SysRam5LightSleepDisable(void)
358 {
359     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM5LS_EN;
360 }
361 
MXC_LP_ICache0LightSleepDisable(void)362 void MXC_LP_ICache0LightSleepDisable(void)
363 {
364     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_ICC0LS_EN;
365 }
366 
MXC_LP_ICacheXIPLightSleepDisable(void)367 void MXC_LP_ICacheXIPLightSleepDisable(void)
368 {
369     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_ICCXIPLS_EN;
370 }
371 
MXC_LP_SRCCLightSleepDisable(void)372 void MXC_LP_SRCCLightSleepDisable(void)
373 {
374     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_SRCCLS_EN;
375 }
376 
MXC_LP_CryptoLightSleepDisable(void)377 void MXC_LP_CryptoLightSleepDisable(void)
378 {
379     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_CRYPTOLS_EN;
380 }
381 
MXC_LP_USBFIFOLightSleepDisable(void)382 void MXC_LP_USBFIFOLightSleepDisable(void)
383 {
384     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_USBLS_EN;
385 }
386 
MXC_LP_ROMLightSleepDisable(void)387 void MXC_LP_ROMLightSleepDisable(void)
388 {
389     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_ROMLS_EN;
390 }
391 
MXC_LP_SysRam0Shutdown(void)392 void MXC_LP_SysRam0Shutdown(void)
393 {
394     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM0;
395 }
396 
MXC_LP_SysRam0PowerUp(void)397 void MXC_LP_SysRam0PowerUp(void)
398 {
399     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM0;
400 }
401 
MXC_LP_SysRam1Shutdown(void)402 void MXC_LP_SysRam1Shutdown(void)
403 {
404     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM1;
405 }
406 
MXC_LP_SysRam1PowerUp(void)407 void MXC_LP_SysRam1PowerUp(void)
408 {
409     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM1;
410 }
411 
MXC_LP_SysRam2Shutdown(void)412 void MXC_LP_SysRam2Shutdown(void)
413 {
414     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM2;
415 }
416 
MXC_LP_SysRam2PowerUp(void)417 void MXC_LP_SysRam2PowerUp(void)
418 {
419     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM2;
420 }
421 
MXC_LP_SysRam3Shutdown(void)422 void MXC_LP_SysRam3Shutdown(void)
423 {
424     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM3;
425 }
426 
MXC_LP_SysRam3PowerUp(void)427 void MXC_LP_SysRam3PowerUp(void)
428 {
429     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM3;
430 }
431 
MXC_LP_SysRam4Shutdown(void)432 void MXC_LP_SysRam4Shutdown(void)
433 {
434     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM4;
435 }
436 
MXC_LP_SysRam4PowerUp(void)437 void MXC_LP_SysRam4PowerUp(void)
438 {
439     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM4;
440 }
441 
MXC_LP_SysRam5Shutdown(void)442 void MXC_LP_SysRam5Shutdown(void)
443 {
444     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM5;
445 }
446 
MXC_LP_SysRam5PowerUp(void)447 void MXC_LP_SysRam5PowerUp(void)
448 {
449     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM5;
450 }
451 
MXC_LP_ICache0Shutdown(void)452 void MXC_LP_ICache0Shutdown(void)
453 {
454     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_ICACHE;
455 }
456 
MXC_LP_ICache0PowerUp(void)457 void MXC_LP_ICache0PowerUp(void)
458 {
459     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_ICACHE;
460 }
461 
MXC_LP_ICacheXIPShutdown(void)462 void MXC_LP_ICacheXIPShutdown(void)
463 {
464     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_ICACHEXIP;
465 }
466 
MXC_LP_ICacheXIPPowerUp(void)467 void MXC_LP_ICacheXIPPowerUp(void)
468 {
469     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_ICACHEXIP;
470 }
471 
MXC_LP_SRCCShutdown(void)472 void MXC_LP_SRCCShutdown(void)
473 {
474     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_SRCC;
475 }
476 
MXC_LP_SRCCPowerUp(void)477 void MXC_LP_SRCCPowerUp(void)
478 {
479     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_SRCC;
480 }
481 
MXC_LP_USBFIFOShutdown(void)482 void MXC_LP_USBFIFOShutdown(void)
483 {
484     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_USBFIFO;
485 }
486 
MXC_LP_USBFIFOPowerUp(void)487 void MXC_LP_USBFIFOPowerUp(void)
488 {
489     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_USBFIFO;
490 }
491 
MXC_LP_ROMShutdown(void)492 void MXC_LP_ROMShutdown(void)
493 {
494     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_ROM;
495 }
496 
MXC_LP_ROMPowerUp(void)497 void MXC_LP_ROMPowerUp(void)
498 {
499     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_ROM;
500 }
501