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)27void MXC_LP_EnterSleepMode(void) 28 { 29 MXC_LP_ClearWakeStatus(); 30 31 // set block detect bit 32 MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_VCORE_DET_BYPASS; 33 34 // Clear SLEEPDEEP bit 35 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; 36 37 // Go into Sleep mode and wait for an interrupt to wake the processor 38 __WFI(); 39 } 40 MXC_LP_EnterDeepSleepMode(void)41void MXC_LP_EnterDeepSleepMode(void) 42 { 43 MXC_LP_ClearWakeStatus(); 44 45 // set block detect bit 46 MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_VCORE_DET_BYPASS; 47 48 // Set SLEEPDEEP bit 49 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 50 51 // Go into Deepsleep mode and wait for an interrupt to wake the processor 52 __WFI(); 53 } 54 MXC_LP_EnterBackupMode(void)55void MXC_LP_EnterBackupMode(void) 56 { 57 MXC_LP_ClearWakeStatus(); 58 59 // set block detect bit 60 MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_VCORE_DET_BYPASS; 61 62 MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE; 63 MXC_GCR->pm |= MXC_S_GCR_PM_MODE_BACKUP; 64 65 while (1) {} 66 // Should never reach this line - device will jump to backup vector on exit from background mode. 67 } 68 MXC_LP_EnterStorageMode(void)69void MXC_LP_EnterStorageMode(void) 70 { 71 MXC_LP_ClearWakeStatus(); 72 /*set block detect bit */ 73 MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_VCORE_DET_BYPASS; 74 75 MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_STORAGE_EN; 76 MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE; 77 MXC_GCR->pm |= MXC_S_GCR_PM_MODE_BACKUP; 78 79 while (1) {} 80 // Should never reach this line - device will jump to backup vector on exit from background mode. 81 } 82 MXC_LP_EnterShutDownMode(void)83void MXC_LP_EnterShutDownMode(void) 84 { 85 MXC_GCR->pm &= ~MXC_F_GCR_PM_MODE; 86 MXC_GCR->pm |= MXC_S_GCR_PM_MODE_SHUTDOWN; 87 88 while (1) {} 89 // Should never reach this line - device will reset on exit from shutdown mode. 90 } 91 MXC_LP_SetOVR(mxc_lp_ovr_t ovr)92void MXC_LP_SetOVR(mxc_lp_ovr_t ovr) 93 { 94 //TODO(all): not supported yet 95 } 96 MXC_LP_RetentionRegEnable(void)97void MXC_LP_RetentionRegEnable(void) 98 { 99 MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_RETREG_EN; 100 } 101 MXC_LP_RetentionRegDisable(void)102void MXC_LP_RetentionRegDisable(void) 103 { 104 MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_RETREG_EN; 105 } 106 MXC_LP_RetentionRegIsEnabled(void)107int MXC_LP_RetentionRegIsEnabled(void) 108 { 109 return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_RETREG_EN); 110 } 111 MXC_LP_BandgapOn(void)112void MXC_LP_BandgapOn(void) 113 { 114 MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_BG_DIS; 115 } 116 MXC_LP_BandgapOff(void)117void MXC_LP_BandgapOff(void) 118 { 119 MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_BG_DIS; 120 } 121 MXC_LP_BandgapIsOn(void)122int MXC_LP_BandgapIsOn(void) 123 { 124 return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_BG_DIS); 125 } 126 MXC_LP_PORVCOREoreMonitorEnable(void)127void MXC_LP_PORVCOREoreMonitorEnable(void) 128 { 129 MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_VCOREPOR_DIS; 130 } 131 MXC_LP_PORVCOREoreMonitorDisable(void)132void MXC_LP_PORVCOREoreMonitorDisable(void) 133 { 134 MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_VCOREPOR_DIS; 135 } 136 MXC_LP_PORVCOREoreMonitorIsEnabled(void)137int MXC_LP_PORVCOREoreMonitorIsEnabled(void) 138 { 139 return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_VCOREPOR_DIS); 140 } 141 MXC_LP_LDOEnable(void)142void MXC_LP_LDOEnable(void) 143 { 144 MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_LDO_DIS; 145 } 146 MXC_LP_LDODisable(void)147void MXC_LP_LDODisable(void) 148 { 149 MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_LDO_DIS; 150 } 151 MXC_LP_LDOIsEnabled(void)152int MXC_LP_LDOIsEnabled(void) 153 { 154 return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_LDO_DIS); 155 } 156 MXC_LP_FastWakeupEnable(void)157void MXC_LP_FastWakeupEnable(void) 158 { 159 MXC_PWRSEQ->lpcn |= MXC_F_PWRSEQ_LPCN_FASTWK_EN; 160 } 161 MXC_LP_FastWakeupDisable(void)162void MXC_LP_FastWakeupDisable(void) 163 { 164 MXC_PWRSEQ->lpcn &= ~MXC_F_PWRSEQ_LPCN_FASTWK_EN; 165 } 166 MXC_LP_FastWakeupIsEnabled(void)167int MXC_LP_FastWakeupIsEnabled(void) 168 { 169 return (MXC_PWRSEQ->lpcn & MXC_F_PWRSEQ_LPCN_FASTWK_EN); 170 } 171 MXC_LP_ClearWakeStatus(void)172void MXC_LP_ClearWakeStatus(void) 173 { 174 // Write 1 to clear 175 MXC_PWRSEQ->lpwkst0 = 0xFFFFFFFF; 176 MXC_PWRSEQ->lpwkst1 = 0xFFFFFFFF; 177 MXC_PWRSEQ->lppwkst |= 0x0001001F; 178 } 179 MXC_LP_EnableGPIOWakeup(mxc_gpio_cfg_t * wu_pins)180void MXC_LP_EnableGPIOWakeup(mxc_gpio_cfg_t *wu_pins) 181 { 182 MXC_GCR->pm |= MXC_F_GCR_PM_GPIO_WE; 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 } 192 } 193 MXC_LP_DisableGPIOWakeup(mxc_gpio_cfg_t * wu_pins)194void MXC_LP_DisableGPIOWakeup(mxc_gpio_cfg_t *wu_pins) 195 { 196 switch (1 << MXC_GPIO_GET_IDX(wu_pins->port)) { 197 case MXC_GPIO_PORT_0: 198 MXC_PWRSEQ->lpwken0 &= ~wu_pins->mask; 199 break; 200 201 case MXC_GPIO_PORT_1: 202 MXC_PWRSEQ->lpwken1 &= ~wu_pins->mask; 203 } 204 205 if (MXC_PWRSEQ->lpwken1 == 0 && MXC_PWRSEQ->lpwken0 == 0) { 206 MXC_GCR->pm &= ~MXC_F_GCR_PM_GPIO_WE; 207 } 208 } 209 MXC_LP_EnableRTCAlarmWakeup(void)210void MXC_LP_EnableRTCAlarmWakeup(void) 211 { 212 MXC_GCR->pm |= MXC_F_GCR_PM_RTC_WE; 213 } 214 MXC_LP_DisableRTCAlarmWakeup(void)215void MXC_LP_DisableRTCAlarmWakeup(void) 216 { 217 MXC_GCR->pm &= ~MXC_F_GCR_PM_RTC_WE; 218 } 219 MXC_LP_EnableTimerWakeup(mxc_tmr_regs_t * tmr)220void MXC_LP_EnableTimerWakeup(mxc_tmr_regs_t *tmr) 221 { 222 MXC_ASSERT(MXC_TMR_GET_IDX(tmr) > 3); 223 224 if (tmr == MXC_TMR4) { 225 MXC_GCR->pm |= MXC_F_GCR_PM_LPTMR0_WE; 226 MXC_PWRSEQ->lppwken |= MXC_F_PWRSEQ_LPPWKEN_LPTMR0; 227 } else { 228 MXC_GCR->pm |= MXC_F_GCR_PM_LPTMR1_WE; 229 MXC_PWRSEQ->lppwken |= MXC_F_PWRSEQ_LPPWKEN_LPTMR1; 230 } 231 } 232 MXC_LP_DisableTimerWakeup(mxc_tmr_regs_t * tmr)233void MXC_LP_DisableTimerWakeup(mxc_tmr_regs_t *tmr) 234 { 235 MXC_ASSERT(MXC_TMR_GET_IDX(tmr) > 3); 236 237 if (tmr == MXC_TMR4) { 238 MXC_GCR->pm &= ~MXC_F_GCR_PM_LPTMR0_WE; 239 MXC_PWRSEQ->lppwken &= ~MXC_F_PWRSEQ_LPPWKEN_LPTMR0; 240 } else { 241 MXC_GCR->pm &= ~MXC_F_GCR_PM_LPTMR1_WE; 242 MXC_PWRSEQ->lppwken &= ~MXC_F_PWRSEQ_LPPWKEN_LPTMR1; 243 } 244 } 245 MXC_LP_EnableComparatorWakeup(mxc_adc_comp_t comp)246void MXC_LP_EnableComparatorWakeup(mxc_adc_comp_t comp) 247 { 248 switch (comp) { 249 case MXC_ADC_COMP_0: 250 MXC_PWRSEQ->lppwkst |= MXC_F_PWRSEQ_LPPWKST_AINCOMP0; 251 MXC_PWRSEQ->lppwken |= MXC_F_PWRSEQ_LPPWKEN_AINCOMP0; 252 break; 253 case MXC_ADC_COMP_1: 254 MXC_PWRSEQ->lppwkst |= MXC_F_PWRSEQ_LPPWKST_AINCOMP1; 255 MXC_PWRSEQ->lppwken |= MXC_F_PWRSEQ_LPPWKEN_AINCOMP1; 256 break; 257 default: 258 return; 259 } 260 MXC_GCR->pm |= MXC_F_GCR_PM_AINCOMP_WE; 261 } 262 MXC_LP_DisableComparatorWakeup(mxc_adc_comp_t comp)263void MXC_LP_DisableComparatorWakeup(mxc_adc_comp_t comp) 264 { 265 switch (comp) { 266 case MXC_ADC_COMP_0: 267 MXC_PWRSEQ->lppwken &= ~MXC_F_PWRSEQ_LPPWKEN_AINCOMP0; 268 break; 269 case MXC_ADC_COMP_1: 270 MXC_PWRSEQ->lppwken &= ~MXC_F_PWRSEQ_LPPWKEN_AINCOMP1; 271 break; 272 default: 273 return; 274 } 275 MXC_GCR->pm &= ~MXC_F_GCR_PM_AINCOMP_WE; 276 } 277 278 // TODO(all): Add MXC_LP_Enable/DisableUARTWakeup functions for LP UARTs. 279 MXC_LP_ConfigDeepSleepClocks(uint32_t mask)280int MXC_LP_ConfigDeepSleepClocks(uint32_t mask) 281 { 282 if (!(mask & (MXC_F_GCR_PM_IBRO_PD | MXC_F_GCR_PM_IPO_PD | MXC_F_GCR_PM_ERFO_PD))) { 283 return E_BAD_PARAM; 284 } 285 286 MXC_GCR->pm |= mask; 287 return E_NO_ERROR; 288 } 289 MXC_LP_SysRam0LightSleepEnable(void)290void MXC_LP_SysRam0LightSleepEnable(void) 291 { 292 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM0LS_EN; 293 } 294 MXC_LP_SysRam1LightSleepEnable(void)295void MXC_LP_SysRam1LightSleepEnable(void) 296 { 297 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM1LS_EN; 298 } 299 MXC_LP_SysRam2LightSleepEnable(void)300void MXC_LP_SysRam2LightSleepEnable(void) 301 { 302 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM2LS_EN; 303 } 304 MXC_LP_SysRam3LightSleepEnable(void)305void MXC_LP_SysRam3LightSleepEnable(void) 306 { 307 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_RAM3LS_EN; 308 } 309 MXC_LP_ICache0LightSleepEnable(void)310void MXC_LP_ICache0LightSleepEnable(void) 311 { 312 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_ICC0LS_EN; 313 } 314 MXC_LP_ROMLightSleepEnable(void)315void MXC_LP_ROMLightSleepEnable(void) 316 { 317 MXC_GCR->memctrl |= MXC_F_GCR_MEMCTRL_ROMLS_EN; 318 } 319 MXC_LP_SysRam0LightSleepDisable(void)320void MXC_LP_SysRam0LightSleepDisable(void) 321 { 322 MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM0LS_EN; 323 } 324 MXC_LP_SysRam1LightSleepDisable(void)325void MXC_LP_SysRam1LightSleepDisable(void) 326 { 327 MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM1LS_EN; 328 } 329 MXC_LP_SysRam2LightSleepDisable(void)330void MXC_LP_SysRam2LightSleepDisable(void) 331 { 332 MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM2LS_EN; 333 } 334 MXC_LP_SysRam3LightSleepDisable(void)335void MXC_LP_SysRam3LightSleepDisable(void) 336 { 337 MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_RAM3LS_EN; 338 } 339 MXC_LP_ICache0LightSleepDisable(void)340void MXC_LP_ICache0LightSleepDisable(void) 341 { 342 MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_ICC0LS_EN; 343 } 344 MXC_LP_ROMLightSleepDisable(void)345void MXC_LP_ROMLightSleepDisable(void) 346 { 347 MXC_GCR->memctrl &= ~MXC_F_GCR_MEMCTRL_ROMLS_EN; 348 } 349 MXC_LP_SysRam0Shutdown(void)350void MXC_LP_SysRam0Shutdown(void) 351 { 352 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM0; 353 } 354 MXC_LP_SysRam0PowerUp(void)355void MXC_LP_SysRam0PowerUp(void) 356 { 357 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM0; 358 } 359 MXC_LP_SysRam1Shutdown(void)360void MXC_LP_SysRam1Shutdown(void) 361 { 362 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM1; 363 } 364 MXC_LP_SysRam1PowerUp(void)365void MXC_LP_SysRam1PowerUp(void) 366 { 367 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM1; 368 } 369 MXC_LP_SysRam2Shutdown(void)370void MXC_LP_SysRam2Shutdown(void) 371 { 372 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM2; 373 } 374 MXC_LP_SysRam2PowerUp(void)375void MXC_LP_SysRam2PowerUp(void) 376 { 377 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM2; 378 } 379 MXC_LP_SysRam3Shutdown(void)380void MXC_LP_SysRam3Shutdown(void) 381 { 382 MXC_PWRSEQ->lpmemsd |= MXC_F_PWRSEQ_LPMEMSD_RAM3; 383 } 384 MXC_LP_SysRam3PowerUp(void)385void MXC_LP_SysRam3PowerUp(void) 386 { 387 MXC_PWRSEQ->lpmemsd &= ~MXC_F_PWRSEQ_LPMEMSD_RAM3; 388 } 389