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_VCOREoreMonitorEnable(void)76 void MXC_LP_VCOREoreMonitorEnable(void)
77 {
78     MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_VCOREMON_DIS;
79 }
80 
MXC_LP_VCOREoreMonitorDisable(void)81 void MXC_LP_VCOREoreMonitorDisable(void)
82 {
83     MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_VCOREMON_DIS;
84 }
85 
MXC_LP_VCOREoreMonitorIsEnabled(void)86 int MXC_LP_VCOREoreMonitorIsEnabled(void)
87 {
88     return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_VCOREMON_DIS);
89 }
90 
MXC_LP_LDOEnable(void)91 void MXC_LP_LDOEnable(void)
92 {
93     MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_LDO_DIS;
94 }
95 
MXC_LP_LDODisable(void)96 void MXC_LP_LDODisable(void)
97 {
98     MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_LDO_DIS;
99 }
100 
MXC_LP_LDOIsEnabled(void)101 int MXC_LP_LDOIsEnabled(void)
102 {
103     return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_LDO_DIS);
104 }
105 
MXC_LP_ClearWakeStatus(void)106 void MXC_LP_ClearWakeStatus(void)
107 {
108     // Write 1 to clear
109     MXC_PWRSEQ->lpwkst0 = 0xFFFFFFFF;
110     MXC_PWRSEQ->lpwkst1 = 0xFFFFFFFF;
111     MXC_PWRSEQ->lppwkst = 0xFFFFFFFF;
112 }
113 
MXC_LP_EnableGPIOWakeup(mxc_gpio_cfg_t * wu_pins)114 void MXC_LP_EnableGPIOWakeup(mxc_gpio_cfg_t *wu_pins)
115 {
116     MXC_GCR->pm |= MXC_F_GCR_PM_GPIO_WE;
117 
118     switch (1 << MXC_GPIO_GET_IDX(wu_pins->port)) {
119     case MXC_GPIO_PORT_0:
120         MXC_PWRSEQ->lpwken0 |= wu_pins->mask;
121         break;
122 
123     case MXC_GPIO_PORT_1:
124         MXC_PWRSEQ->lpwken1 |= wu_pins->mask;
125     }
126 }
127 
MXC_LP_DisableGPIOWakeup(mxc_gpio_cfg_t * wu_pins)128 void MXC_LP_DisableGPIOWakeup(mxc_gpio_cfg_t *wu_pins)
129 {
130     switch (1 << MXC_GPIO_GET_IDX(wu_pins->port)) {
131     case MXC_GPIO_PORT_0:
132         MXC_PWRSEQ->lpwken0 &= ~wu_pins->mask;
133         break;
134 
135     case MXC_GPIO_PORT_1:
136         MXC_PWRSEQ->lpwken1 &= ~wu_pins->mask;
137     }
138 
139     if (MXC_PWRSEQ->lpwken1 == 0 && MXC_PWRSEQ->lpwken0 == 0) {
140         MXC_GCR->pm &= ~MXC_F_GCR_PM_GPIO_WE;
141     }
142 }
143 
MXC_LP_ConfigDeepSleepClocks(uint32_t mask)144 int MXC_LP_ConfigDeepSleepClocks(uint32_t mask)
145 {
146     if (!(mask & (MXC_F_GCR_PM_IBRO_PD | MXC_F_GCR_PM_IPO_PD))) {
147         return E_BAD_PARAM;
148     }
149 
150     MXC_GCR->pm |= mask;
151     return E_NO_ERROR;
152 }
153 
MXC_LP_SysRam0LightSleepEnable(void)154 void MXC_LP_SysRam0LightSleepEnable(void)
155 {
156     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM0LS_EN;
157 }
158 
MXC_LP_SysRam1LightSleepEnable(void)159 void MXC_LP_SysRam1LightSleepEnable(void)
160 {
161     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM1LS_EN;
162 }
163 
MXC_LP_SysRam2LightSleepEnable(void)164 void MXC_LP_SysRam2LightSleepEnable(void)
165 {
166     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM2LS_EN;
167 }
168 
MXC_LP_SysRam3LightSleepEnable(void)169 void MXC_LP_SysRam3LightSleepEnable(void)
170 {
171     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM3LS_EN;
172 }
173 
MXC_LP_SysRam4LightSleepEnable(void)174 void MXC_LP_SysRam4LightSleepEnable(void)
175 {
176     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM4LS_EN;
177 }
178 
MXC_LP_ICache0LightSleepEnable(void)179 void MXC_LP_ICache0LightSleepEnable(void)
180 {
181     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_ICC0LS_EN;
182 }
183 
MXC_LP_ROMLightSleepEnable(void)184 void MXC_LP_ROMLightSleepEnable(void)
185 {
186     MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_ROMLS_EN;
187 }
188 
MXC_LP_SysRam0LightSleepDisable(void)189 void MXC_LP_SysRam0LightSleepDisable(void)
190 {
191     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM0LS_EN;
192 }
193 
MXC_LP_SysRam1LightSleepDisable(void)194 void MXC_LP_SysRam1LightSleepDisable(void)
195 {
196     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM1LS_EN;
197 }
198 
MXC_LP_SysRam2LightSleepDisable(void)199 void MXC_LP_SysRam2LightSleepDisable(void)
200 {
201     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM2LS_EN;
202 }
203 
MXC_LP_SysRam3LightSleepDisable(void)204 void MXC_LP_SysRam3LightSleepDisable(void)
205 {
206     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM3LS_EN;
207 }
208 
MXC_LP_SysRam4LightSleepDisable(void)209 void MXC_LP_SysRam4LightSleepDisable(void)
210 {
211     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM4LS_EN;
212 }
213 
MXC_LP_ICache0LightSleepDisable(void)214 void MXC_LP_ICache0LightSleepDisable(void)
215 {
216     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_ICC0LS_EN;
217 }
218 
MXC_LP_ROMLightSleepDisable(void)219 void MXC_LP_ROMLightSleepDisable(void)
220 {
221     MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_ROMLS_EN;
222 }
223 
MXC_LP_ICache0Shutdown(void)224 void MXC_LP_ICache0Shutdown(void)
225 {
226     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_ICACHE;
227 }
228 
MXC_LP_ICache0PowerUp(void)229 void MXC_LP_ICache0PowerUp(void)
230 {
231     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_ICACHE;
232 }
233 
MXC_LP_ROMShutdown(void)234 void MXC_LP_ROMShutdown(void)
235 {
236     MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_ROM;
237 }
238 
MXC_LP_ROMPowerUp(void)239 void MXC_LP_ROMPowerUp(void)
240 {
241     MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_ROM;
242 }
243