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 "mcr_regs.h" 26 #include "lp.h" 27 MXC_LP_EnterSleepMode(void)28void MXC_LP_EnterSleepMode(void) 29 { 30 MXC_LP_ClearWakeStatus(); 31 32 /* Clear SLEEPDEEP bit */ 33 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; 34 35 /* Go into Sleep mode and wait for an interrupt to wake the processor */ 36 __WFI(); 37 } 38 MXC_LP_EnterDeepSleepMode(void)39void MXC_LP_EnterDeepSleepMode(void) 40 { 41 // Set SLEEPDEEP bit 42 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 43 44 // // Auto-powerdown 96 MHz oscillator when in deep sleep 45 // MXC_GCR->pm |= MXC_F_GCR_PM_HFIOPD; // Not supported on ME12 46 // Go into Deepsleep mode and wait for an interrupt to wake the processor 47 __WFI(); 48 } 49 MXC_LP_EnterBackupMode(void)50void MXC_LP_EnterBackupMode(void) 51 { 52 MXC_LP_ClearWakeStatus(); 53 54 MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE; 55 MXC_GCR->pm |= MXC_S_GCR_PM_MODE_BACKUP; 56 57 while (1) {} 58 // Should never reach this line - device will jump to backup vector on exit from background mode. 59 } 60 MXC_LP_EnterShutDownMode(void)61void MXC_LP_EnterShutDownMode(void) 62 { 63 MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE; 64 MXC_GCR->pm |= MXC_S_GCR_PM_MODE_SHUTDOWN; 65 66 while (1) {} 67 // Should never reach this line - device will reset on exit from shutdown mode. 68 } 69 MXC_LP_EnableSRAM3(void)70void MXC_LP_EnableSRAM3(void) 71 { 72 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM3; 73 } 74 MXC_LP_DisableSRAM3(void)75void MXC_LP_DisableSRAM3(void) 76 { 77 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM3; 78 } 79 MXC_LP_EnableSRAM2(void)80void MXC_LP_EnableSRAM2(void) 81 { 82 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM2; 83 } 84 MXC_LP_DisableSRAM2(void)85void MXC_LP_DisableSRAM2(void) 86 { 87 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM2; 88 } 89 MXC_LP_EnableSRAM1(void)90void MXC_LP_EnableSRAM1(void) 91 { 92 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM1; 93 } 94 MXC_LP_DisableSRAM1(void)95void MXC_LP_DisableSRAM1(void) 96 { 97 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM1; 98 } 99 MXC_LP_EnableSRAM0(void)100void MXC_LP_EnableSRAM0(void) 101 { 102 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM0; 103 } 104 MXC_LP_DisableSRAM0(void)105void MXC_LP_DisableSRAM0(void) 106 { 107 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM0; 108 } 109 MXC_LP_EnableSRAM(int instance)110int MXC_LP_EnableSRAM(int instance) 111 { 112 if (instance == 0) { 113 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM0; 114 } else if (instance == 1) { 115 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM1; 116 } else if (instance == 2) { 117 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM2; 118 } else if (instance == 3) { 119 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM3; 120 } else { 121 return E_BAD_PARAM; 122 } 123 124 return E_SUCCESS; 125 } 126 MXC_LP_DisableSRAM(int instance)127int MXC_LP_DisableSRAM(int instance) 128 { 129 if (instance == 0) { 130 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM0; 131 } else if (instance == 1) { 132 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM1; 133 } else if (instance == 2) { 134 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM2; 135 } else if (instance == 3) { 136 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM3; 137 } else { 138 return E_BAD_PARAM; 139 } 140 141 return E_SUCCESS; 142 } 143 MXC_LP_SetOVR(mxc_lp_ovr_t ovr)144int MXC_LP_SetOVR(mxc_lp_ovr_t ovr) 145 { 146 return E_NOT_SUPPORTED; 147 } 148 MXC_LP_BandgapOn(void)149void MXC_LP_BandgapOn(void) 150 { 151 MXC_PWRSEQ->lpctrl &= ~MXC_F_PWRSEQ_LPCTRL_BG_DIS; // 0 = Bandgap is always ON 152 } 153 MXC_LP_BandgapOff(void)154void MXC_LP_BandgapOff(void) 155 { 156 MXC_PWRSEQ->lpctrl |= MXC_F_PWRSEQ_LPCTRL_BG_DIS; // 1 = Bandgap is always OFF. 157 } 158 MXC_LP_BandgapIsOn(void)159int MXC_LP_BandgapIsOn(void) 160 { 161 return ~(MXC_PWRSEQ->lpctrl & MXC_F_PWRSEQ_LPCTRL_BG_DIS); // Logic on Bandgap bit is inverted 162 } 163 MXC_LP_ClearWakeStatus(void)164void MXC_LP_ClearWakeStatus(void) 165 { 166 /* Write 1 to clear */ 167 MXC_PWRSEQ->lpwkfl0 = 0xFFFFFFFF; 168 MXC_PWRSEQ->lppwkfl = 0xFFFFFFFF; 169 } 170 MXC_LP_EnableGPIOWakeup(const mxc_gpio_cfg_t * wu_pins)171void MXC_LP_EnableGPIOWakeup(const mxc_gpio_cfg_t *wu_pins) 172 { 173 MXC_GCR->pm |= MXC_F_GCR_PM_GPIO_WE; 174 175 switch (1 << MXC_GPIO_GET_IDX(wu_pins->port)) { 176 case MXC_GPIO_PORT_0: 177 MXC_PWRSEQ->lpwken0 |= wu_pins->mask; 178 break; 179 } 180 } 181 MXC_LP_DisableGPIOWakeup(const mxc_gpio_cfg_t * wu_pins)182void MXC_LP_DisableGPIOWakeup(const 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 190 if (MXC_PWRSEQ->lpwken0 == 0) { 191 MXC_GCR->pm &= ~MXC_F_GCR_PM_GPIO_WE; 192 } 193 } 194 MXC_LP_EnableRTCAlarmWakeup(void)195void MXC_LP_EnableRTCAlarmWakeup(void) 196 { 197 MXC_GCR->pm |= MXC_F_GCR_PM_RTC_WE; 198 } 199 MXC_LP_DisableRTCAlarmWakeup(void)200void MXC_LP_DisableRTCAlarmWakeup(void) 201 { 202 MXC_GCR->pm &= ~MXC_F_GCR_PM_RTC_WE; 203 } 204 MXC_LP_EnableTimerWakeup(mxc_tmr_regs_t * tmr)205void MXC_LP_EnableTimerWakeup(mxc_tmr_regs_t *tmr) 206 { 207 if (tmr == MXC_TMR3) { 208 // MXC_TMR3 (LPTIMER0) is the only timer that supports WE 209 MXC_GCR->pm |= MXC_F_GCR_PM_TMR3_WE; 210 } 211 } 212 MXC_LP_DisableTimerWakeup(mxc_tmr_regs_t * tmr)213void MXC_LP_DisableTimerWakeup(mxc_tmr_regs_t *tmr) 214 { 215 if (tmr == MXC_TMR3) { 216 // MXC_TMR3 (LPTIMER0) is the only timer that supports WE 217 MXC_GCR->pm &= ~(MXC_F_GCR_PM_TMR3_WE); 218 } 219 } 220 MXC_LP_EnableICacheLightSleep(void)221void MXC_LP_EnableICacheLightSleep(void) 222 { 223 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_ICC0LS_EN; 224 } 225 MXC_LP_DisableICacheLightSleep(void)226void MXC_LP_DisableICacheLightSleep(void) 227 { 228 MXC_GCR->memctrl &= ~(MXC_F_GCR_MEMCTRL_ICC0LS_EN); 229 } 230 MXC_LP_ROMLightSleepEnable(void)231void MXC_LP_ROMLightSleepEnable(void) 232 { 233 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_ROMLS_EN; 234 } 235 MXC_LP_RomLightSleepDisable(void)236void MXC_LP_RomLightSleepDisable(void) 237 { 238 MXC_GCR->memctrl &= ~(MXC_F_GCR_MEMCTRL_ROMLS_EN); 239 } 240 MXC_LP_EnableSysRAMLightSleep(int instance)241int MXC_LP_EnableSysRAMLightSleep(int instance) 242 { 243 if (instance == 0) { 244 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM0LS_EN; 245 } else if (instance == 1) { 246 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM1LS_EN; 247 } else if (instance == 2) { 248 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM2LS_EN; 249 } else if (instance == 3) { 250 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM3LS_EN; 251 } else { 252 return E_BAD_PARAM; 253 } 254 255 return E_SUCCESS; 256 } 257 MXC_LP_DisableSysRAMLightSleep(int instance)258int MXC_LP_DisableSysRAMLightSleep(int instance) 259 { 260 if (instance == 0) { 261 MXC_GCR->memctrl &= ~(MXC_F_GCR_MEMCTRL_RAM0LS_EN); 262 } else if (instance == 1) { 263 MXC_GCR->memctrl &= ~(MXC_F_GCR_MEMCTRL_RAM1LS_EN); 264 } else if (instance == 2) { 265 MXC_GCR->memctrl &= ~(MXC_F_GCR_MEMCTRL_RAM2LS_EN); 266 } else if (instance == 3) { 267 MXC_GCR->memctrl &= ~(MXC_F_GCR_MEMCTRL_RAM1LS_EN); 268 } else { 269 return E_BAD_PARAM; 270 } 271 272 return E_SUCCESS; 273 } 274