1 /* 2 * Copyright (c) 2016, Freescale Semiconductor, Inc. 3 * Copyright 2016-2018, NXP 4 * All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 #include "fsl_power.h" 9 /* Component ID definition, used by tools. */ 10 #ifndef FSL_COMPONENT_ID 11 #define FSL_COMPONENT_ID "platform.drivers.power_no_lib" 12 #endif 13 /******************************************************************************* 14 * Definitions 15 ******************************************************************************/ 16 17 /******************************************************************************* 18 * Code 19 ******************************************************************************/ 20 /*! 21 * brief API to enter sleep power mode. 22 * 23 * return none 24 */ POWER_EnterSleep(void)25void POWER_EnterSleep(void) 26 { 27 uint32_t pmsk; 28 29 pmsk = __get_PRIMASK(); 30 __disable_irq(); 31 32 /* sleep mode */ 33 PMU->PCON &= ~PMU_PCON_PM_MASK; 34 /* disable Deepsleep mode in the ARM-CORTEX M0+ SCR register */ 35 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; 36 37 /* Enter powerdown mode */ 38 __WFI(); 39 40 __set_PRIMASK(pmsk); 41 42 } 43 44 /*! 45 * brief API to enter deep sleep power mode. 46 * 47 * param activePart: should be a single or combine value of _power_deep_sleep_active . 48 * return none 49 */ POWER_EnterDeepSleep(uint32_t activePart)50void POWER_EnterDeepSleep(uint32_t activePart) 51 { 52 assert((SYSCON->MAINCLKSEL & SYSCON_MAINCLKSEL_SEL_MASK) == 0U); 53 54 uint32_t pmsk; 55 56 pmsk = __get_PRIMASK(); 57 __disable_irq(); 58 59 PMU->PCON = (PMU->PCON & (~PMU_PCON_PM_MASK)) | PMU_PCON_PM(kPmu_Deep_Sleep); 60 61 /* remain active during power down mode */ 62 SYSCON->PDSLEEPCFG &= ~activePart; 63 64 /* enable Deepsleep mode in the ARM-CORTEX M0+ SCR register */ 65 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 66 67 /* Enter powerdown mode */ 68 __WFI(); 69 70 /* disable Deepsleep mode in the ARM-CORTEX M0+ SCR register */ 71 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; 72 __set_PRIMASK(pmsk); 73 } 74 75 /*! 76 * brief API to enter power down mode. 77 * 78 * param activePart: should be a single or combine value of _power_deep_sleep_active . 79 * return none 80 */ POWER_EnterPowerDown(uint32_t activePart)81void POWER_EnterPowerDown(uint32_t activePart) 82 { 83 assert((SYSCON->MAINCLKSEL & SYSCON_MAINCLKSEL_SEL_MASK) == 0U); 84 85 uint32_t pmsk; 86 87 pmsk = __get_PRIMASK(); 88 __disable_irq(); 89 90 PMU->PCON = (PMU->PCON & (~PMU_PCON_PM_MASK)) | PMU_PCON_PM(kPmu_PowerDown); 91 92 /* remain active during power down mode */ 93 SYSCON->PDSLEEPCFG &= ~activePart; 94 95 /* enable Deepsleep mode in the ARM-CORTEX M0+ SCR register */ 96 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 97 98 /* Enter powerdown mode */ 99 __WFI(); 100 101 /* disable Deepsleep mode in the ARM-CORTEX M0+ SCR register */ 102 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; 103 __set_PRIMASK(pmsk); 104 } 105 106 /*! 107 * brief API to enter deep power down mode. 108 * 109 * return none 110 */ POWER_EnterDeepPowerDownMode(void)111void POWER_EnterDeepPowerDownMode(void) 112 { 113 uint32_t pmsk; 114 115 pmsk = __get_PRIMASK(); 116 __disable_irq(); 117 118 /* make sure NODPD is cleared */ 119 PMU->PCON = (PMU->PCON & (~(PMU_PCON_PM_MASK | PMU_PCON_NODPD_MASK))) | PMU_PCON_PM(kPmu_Deep_PowerDown); 120 121 /* enable Deepsleep mode in the ARM-CORTEX M0+ SCR register */ 122 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; 123 124 /* Enter powerdown mode */ 125 __WFI(); 126 127 /* disable Deepsleep mode in the ARM-CORTEX M0+ SCR register */ 128 SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; 129 __set_PRIMASK(pmsk); 130 } 131 EnableDeepSleepIRQ(IRQn_Type interrupt)132void EnableDeepSleepIRQ(IRQn_Type interrupt) 133 { 134 uint32_t intNumber = (uint32_t)interrupt; 135 136 if(intNumber >= 24u) 137 { 138 /* enable pin interrupt wake up in the STARTERP0 register */ 139 SYSCON->STARTERP0 |= 1UL << (intNumber - 24u); 140 } 141 else 142 { 143 /* enable interrupt wake up in the STARTERP1 register */ 144 SYSCON->STARTERP1 |= 1UL << intNumber; 145 } 146 /* also enable interrupt at NVIC */ 147 (void)EnableIRQ(interrupt); 148 } 149 DisableDeepSleepIRQ(IRQn_Type interrupt)150void DisableDeepSleepIRQ(IRQn_Type interrupt) 151 { 152 uint32_t intNumber = (uint32_t)interrupt; 153 154 /* also disable interrupt at NVIC */ 155 (void)DisableIRQ(interrupt); 156 157 if(intNumber >= 24u) 158 { 159 /* disable pin interrupt wake up in the STARTERP0 register */ 160 SYSCON->STARTERP0 &= ~(1UL << (intNumber - 24u)); 161 } 162 else 163 { 164 /* disable interrupt wake up in the STARTERP1 register */ 165 SYSCON->STARTERP1 &= ~(1UL << intNumber); 166 } 167 } 168