Mbed library to manage low-power modes on STM32 devices
STM32_LowPower.cpp@0:f37bc13b9bbf, 2019-04-12 (annotated)
- Committer:
- biagiomkr
- Date:
- Fri Apr 12 17:36:38 2019 +0000
- Revision:
- 0:f37bc13b9bbf
First release of STM32_LowPower Mbed library.; Added source code:; - STM32_LowPower.cpp; - STM32_LowPower.h
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
biagiomkr | 0:f37bc13b9bbf | 1 | /** |
biagiomkr | 0:f37bc13b9bbf | 2 | ****************************************************************************** |
biagiomkr | 0:f37bc13b9bbf | 3 | * @file STM32_LowPower.cpp |
biagiomkr | 0:f37bc13b9bbf | 4 | * @author Biagio Montaruli, STM32duino team (STMicroelectronics) |
biagiomkr | 0:f37bc13b9bbf | 5 | * @version V1.0.0 |
biagiomkr | 0:f37bc13b9bbf | 6 | * @date 12-April-2019 |
biagiomkr | 0:f37bc13b9bbf | 7 | * @brief Mbed Library to manage Low Power modes on STM32 boards |
biagiomkr | 0:f37bc13b9bbf | 8 | * |
biagiomkr | 0:f37bc13b9bbf | 9 | ****************************************************************************** |
biagiomkr | 0:f37bc13b9bbf | 10 | * @attention |
biagiomkr | 0:f37bc13b9bbf | 11 | * |
biagiomkr | 0:f37bc13b9bbf | 12 | * <h2><center>© COPYRIGHT(c) 2019 STMicroelectronics</center></h2> |
biagiomkr | 0:f37bc13b9bbf | 13 | * <h2><center>© COPYRIGHT(c) 2019 Biagio Montaruli</center></h2> |
biagiomkr | 0:f37bc13b9bbf | 14 | * |
biagiomkr | 0:f37bc13b9bbf | 15 | * Redistribution and use in source and binary forms, with or without modification, |
biagiomkr | 0:f37bc13b9bbf | 16 | * are permitted provided that the following conditions are met: |
biagiomkr | 0:f37bc13b9bbf | 17 | * 1. Redistributions of source code must retain the above copyright notice, |
biagiomkr | 0:f37bc13b9bbf | 18 | * this list of conditions and the following disclaimer. |
biagiomkr | 0:f37bc13b9bbf | 19 | * 2. Redistributions in binary form must reproduce the above copyright notice, |
biagiomkr | 0:f37bc13b9bbf | 20 | * this list of conditions and the following disclaimer in the documentation |
biagiomkr | 0:f37bc13b9bbf | 21 | * and/or other materials provided with the distribution. |
biagiomkr | 0:f37bc13b9bbf | 22 | * 3. Neither the name of STMicroelectronics nor the names of its contributors |
biagiomkr | 0:f37bc13b9bbf | 23 | * may be used to endorse or promote products derived from this software |
biagiomkr | 0:f37bc13b9bbf | 24 | * without specific prior written permission. |
biagiomkr | 0:f37bc13b9bbf | 25 | * |
biagiomkr | 0:f37bc13b9bbf | 26 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
biagiomkr | 0:f37bc13b9bbf | 27 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
biagiomkr | 0:f37bc13b9bbf | 28 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
biagiomkr | 0:f37bc13b9bbf | 29 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
biagiomkr | 0:f37bc13b9bbf | 30 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
biagiomkr | 0:f37bc13b9bbf | 31 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
biagiomkr | 0:f37bc13b9bbf | 32 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
biagiomkr | 0:f37bc13b9bbf | 33 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
biagiomkr | 0:f37bc13b9bbf | 34 | * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
biagiomkr | 0:f37bc13b9bbf | 35 | * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
biagiomkr | 0:f37bc13b9bbf | 36 | * |
biagiomkr | 0:f37bc13b9bbf | 37 | ****************************************************************************** |
biagiomkr | 0:f37bc13b9bbf | 38 | */ |
biagiomkr | 0:f37bc13b9bbf | 39 | |
biagiomkr | 0:f37bc13b9bbf | 40 | #include "STM32_LowPower.h" |
biagiomkr | 0:f37bc13b9bbf | 41 | #include "rtc_api_hal.h" |
biagiomkr | 0:f37bc13b9bbf | 42 | |
biagiomkr | 0:f37bc13b9bbf | 43 | STM32_LowPower LowPower; |
biagiomkr | 0:f37bc13b9bbf | 44 | |
biagiomkr | 0:f37bc13b9bbf | 45 | static RTC_HandleTypeDef RtcHandle; |
biagiomkr | 0:f37bc13b9bbf | 46 | static voidFuncPtr RTCUserCallback = NULL; |
biagiomkr | 0:f37bc13b9bbf | 47 | static void *callbackUserData = NULL; |
biagiomkr | 0:f37bc13b9bbf | 48 | |
biagiomkr | 0:f37bc13b9bbf | 49 | void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) |
biagiomkr | 0:f37bc13b9bbf | 50 | { |
biagiomkr | 0:f37bc13b9bbf | 51 | UNUSED(hrtc); |
biagiomkr | 0:f37bc13b9bbf | 52 | |
biagiomkr | 0:f37bc13b9bbf | 53 | if (RTCUserCallback != NULL) { |
biagiomkr | 0:f37bc13b9bbf | 54 | RTCUserCallback(callbackUserData); |
biagiomkr | 0:f37bc13b9bbf | 55 | } |
biagiomkr | 0:f37bc13b9bbf | 56 | } |
biagiomkr | 0:f37bc13b9bbf | 57 | |
biagiomkr | 0:f37bc13b9bbf | 58 | void RTC_IRQHandler(void) |
biagiomkr | 0:f37bc13b9bbf | 59 | { |
biagiomkr | 0:f37bc13b9bbf | 60 | HAL_RTCEx_WakeUpTimerIRQHandler(&RtcHandle); |
biagiomkr | 0:f37bc13b9bbf | 61 | } |
biagiomkr | 0:f37bc13b9bbf | 62 | |
biagiomkr | 0:f37bc13b9bbf | 63 | #ifdef STM32G0xx |
biagiomkr | 0:f37bc13b9bbf | 64 | #define PWR_FLAG_WU PWR_FLAG_WUF |
biagiomkr | 0:f37bc13b9bbf | 65 | #endif |
biagiomkr | 0:f37bc13b9bbf | 66 | |
biagiomkr | 0:f37bc13b9bbf | 67 | STM32_LowPower::STM32_LowPower() |
biagiomkr | 0:f37bc13b9bbf | 68 | { |
biagiomkr | 0:f37bc13b9bbf | 69 | _configured = false; |
biagiomkr | 0:f37bc13b9bbf | 70 | _rtc_wakeup = false; |
biagiomkr | 0:f37bc13b9bbf | 71 | _timer = 0; |
biagiomkr | 0:f37bc13b9bbf | 72 | } |
biagiomkr | 0:f37bc13b9bbf | 73 | |
biagiomkr | 0:f37bc13b9bbf | 74 | /** |
biagiomkr | 0:f37bc13b9bbf | 75 | * @brief Initializes the low power mode |
biagiomkr | 0:f37bc13b9bbf | 76 | * @param None |
biagiomkr | 0:f37bc13b9bbf | 77 | * @retval None |
biagiomkr | 0:f37bc13b9bbf | 78 | */ |
biagiomkr | 0:f37bc13b9bbf | 79 | void STM32_LowPower::init(void) |
biagiomkr | 0:f37bc13b9bbf | 80 | { |
biagiomkr | 0:f37bc13b9bbf | 81 | debug(DEBUG, "Starting STM32_LowPower::init()\n"); |
biagiomkr | 0:f37bc13b9bbf | 82 | /* Initialize Low Power mode using STM32 HAL */ |
biagiomkr | 0:f37bc13b9bbf | 83 | #if !defined(STM32H7xx) && !defined(STM32WBxx) |
biagiomkr | 0:f37bc13b9bbf | 84 | /* Enable Power Clock */ |
biagiomkr | 0:f37bc13b9bbf | 85 | __HAL_RCC_PWR_CLK_ENABLE(); |
biagiomkr | 0:f37bc13b9bbf | 86 | debug(DEBUG, "STM32_LowPower::init() -> __HAL_RCC_PWR_CLK_ENABLE()\n"); |
biagiomkr | 0:f37bc13b9bbf | 87 | #endif |
biagiomkr | 0:f37bc13b9bbf | 88 | /* Allow access to Backup domain */ |
biagiomkr | 0:f37bc13b9bbf | 89 | HAL_PWR_EnableBkUpAccess(); |
biagiomkr | 0:f37bc13b9bbf | 90 | debug(DEBUG, "STM32_LowPower::init() -> HAL_PWR_EnableBkUpAccess()\n"); |
biagiomkr | 0:f37bc13b9bbf | 91 | |
biagiomkr | 0:f37bc13b9bbf | 92 | #ifdef __HAL_RCC_WAKEUPSTOP_CLK_CONFIG |
biagiomkr | 0:f37bc13b9bbf | 93 | /* Ensure that HSI is wake-up system clock */ |
biagiomkr | 0:f37bc13b9bbf | 94 | __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI); |
biagiomkr | 0:f37bc13b9bbf | 95 | debug(DEBUG, "STM32_LowPower::init() -> __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI)\n"); |
biagiomkr | 0:f37bc13b9bbf | 96 | #endif |
biagiomkr | 0:f37bc13b9bbf | 97 | /* Check if the system was resumed from StandBy mode */ |
biagiomkr | 0:f37bc13b9bbf | 98 | if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET) { |
biagiomkr | 0:f37bc13b9bbf | 99 | /* Clear Standby flag */ |
biagiomkr | 0:f37bc13b9bbf | 100 | __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB); |
biagiomkr | 0:f37bc13b9bbf | 101 | debug(DEBUG, "STM32_LowPower::init() -> __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB)\n"); |
biagiomkr | 0:f37bc13b9bbf | 102 | } |
biagiomkr | 0:f37bc13b9bbf | 103 | |
biagiomkr | 0:f37bc13b9bbf | 104 | /* Clear all related wakeup flags */ |
biagiomkr | 0:f37bc13b9bbf | 105 | __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); |
biagiomkr | 0:f37bc13b9bbf | 106 | debug(DEBUG, "STM32_LowPower::init() -> __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU)\n"); |
biagiomkr | 0:f37bc13b9bbf | 107 | |
biagiomkr | 0:f37bc13b9bbf | 108 | /* start RTC */ |
biagiomkr | 0:f37bc13b9bbf | 109 | set_time(0); |
biagiomkr | 0:f37bc13b9bbf | 110 | |
biagiomkr | 0:f37bc13b9bbf | 111 | _configured = true; |
biagiomkr | 0:f37bc13b9bbf | 112 | debug(DEBUG, "Exiting STM32_LowPower::init()...\n"); |
biagiomkr | 0:f37bc13b9bbf | 113 | } |
biagiomkr | 0:f37bc13b9bbf | 114 | |
biagiomkr | 0:f37bc13b9bbf | 115 | /** |
biagiomkr | 0:f37bc13b9bbf | 116 | * @brief Enable the STM32 sleep mode. |
biagiomkr | 0:f37bc13b9bbf | 117 | * Exit this mode on interrupt using the attachInterruptWakeup() method |
biagiomkr | 0:f37bc13b9bbf | 118 | * or in timer_s seconds. |
biagiomkr | 0:f37bc13b9bbf | 119 | * @param reg: type of power regulator. |
biagiomkr | 0:f37bc13b9bbf | 120 | * @param timer_s: optional delay before leaving the sleep mode (default: 0). |
biagiomkr | 0:f37bc13b9bbf | 121 | * @retval None |
biagiomkr | 0:f37bc13b9bbf | 122 | */ |
biagiomkr | 0:f37bc13b9bbf | 123 | void STM32_LowPower::sleep(STM32_RegulatorType reg, uint32_t timer_s) |
biagiomkr | 0:f37bc13b9bbf | 124 | { |
biagiomkr | 0:f37bc13b9bbf | 125 | debug(DEBUG, "Starting STM32_LowPower::sleep()...\n"); |
biagiomkr | 0:f37bc13b9bbf | 126 | |
biagiomkr | 0:f37bc13b9bbf | 127 | uint32_t regulator; |
biagiomkr | 0:f37bc13b9bbf | 128 | |
biagiomkr | 0:f37bc13b9bbf | 129 | /* Enable STM32 Sleep Mode: regulator in main mode */ |
biagiomkr | 0:f37bc13b9bbf | 130 | if (reg == STM32_MAIN_REGULATOR) { |
biagiomkr | 0:f37bc13b9bbf | 131 | regulator = PWR_MAINREGULATOR_ON; |
biagiomkr | 0:f37bc13b9bbf | 132 | debug(DEBUG, "STM32_LowPower::sleep() -> regulator: PWR_MAINREGULATOR_ON\n"); |
biagiomkr | 0:f37bc13b9bbf | 133 | } |
biagiomkr | 0:f37bc13b9bbf | 134 | /* Enable STM32 Low-power Sleep Mode: regulator in low-power mode */ |
biagiomkr | 0:f37bc13b9bbf | 135 | else if (reg == STM32_LOWPOWER_REGULATOR) { |
biagiomkr | 0:f37bc13b9bbf | 136 | regulator = PWR_LOWPOWERREGULATOR_ON; |
biagiomkr | 0:f37bc13b9bbf | 137 | debug(DEBUG, "STM32_LowPower::sleep() -> regulator: PWR_LOWPOWERREGULATOR_ON\n"); |
biagiomkr | 0:f37bc13b9bbf | 138 | } else { |
biagiomkr | 0:f37bc13b9bbf | 139 | regulator = PWR_MAINREGULATOR_ON; |
biagiomkr | 0:f37bc13b9bbf | 140 | } |
biagiomkr | 0:f37bc13b9bbf | 141 | |
biagiomkr | 0:f37bc13b9bbf | 142 | if (timer_s > 0) { |
biagiomkr | 0:f37bc13b9bbf | 143 | programRtcWakeUp(timer_s); |
biagiomkr | 0:f37bc13b9bbf | 144 | debug(DEBUG, "STM32_LowPower::sleep() -> programRtcWakeUp(timer_s)\n"); |
biagiomkr | 0:f37bc13b9bbf | 145 | } |
biagiomkr | 0:f37bc13b9bbf | 146 | else if (_rtc_wakeup && (_timer > 0)) { |
biagiomkr | 0:f37bc13b9bbf | 147 | programRtcWakeUp(_timer); |
biagiomkr | 0:f37bc13b9bbf | 148 | debug(DEBUG, "STM32_LowPower::sleep() -> programRtcWakeUp(_timer)\n"); |
biagiomkr | 0:f37bc13b9bbf | 149 | } |
biagiomkr | 0:f37bc13b9bbf | 150 | |
biagiomkr | 0:f37bc13b9bbf | 151 | /* |
biagiomkr | 0:f37bc13b9bbf | 152 | * Suspend Tick increment to prevent wakeup by Systick interrupt. |
biagiomkr | 0:f37bc13b9bbf | 153 | * Otherwise the Systick interrupt will wake up the device within |
biagiomkr | 0:f37bc13b9bbf | 154 | * 1ms (HAL time base) |
biagiomkr | 0:f37bc13b9bbf | 155 | */ |
biagiomkr | 0:f37bc13b9bbf | 156 | HAL_SuspendTick(); |
biagiomkr | 0:f37bc13b9bbf | 157 | debug(DEBUG, "STM32_LowPower::sleep() -> HAL_SuspendTick()\n"); |
biagiomkr | 0:f37bc13b9bbf | 158 | |
biagiomkr | 0:f37bc13b9bbf | 159 | /* Enter Sleep Mode */ |
biagiomkr | 0:f37bc13b9bbf | 160 | debug(DEBUG, "STM32_LowPower::sleep() -> HAL_PWR_EnterSLEEPMode()\n"); |
biagiomkr | 0:f37bc13b9bbf | 161 | HAL_PWR_EnterSLEEPMode(regulator, PWR_SLEEPENTRY_WFI); |
biagiomkr | 0:f37bc13b9bbf | 162 | |
biagiomkr | 0:f37bc13b9bbf | 163 | /* Resume Tick interrupt if disabled before switching into Sleep mode */ |
biagiomkr | 0:f37bc13b9bbf | 164 | HAL_ResumeTick(); |
biagiomkr | 0:f37bc13b9bbf | 165 | debug(DEBUG, "STM32_LowPower::sleep() -> HAL_ResumeTick()\n"); |
biagiomkr | 0:f37bc13b9bbf | 166 | |
biagiomkr | 0:f37bc13b9bbf | 167 | if ((timer_s > 0) || _rtc_wakeup) { |
biagiomkr | 0:f37bc13b9bbf | 168 | rtc_deactivate_wake_up_timer(); |
biagiomkr | 0:f37bc13b9bbf | 169 | } |
biagiomkr | 0:f37bc13b9bbf | 170 | |
biagiomkr | 0:f37bc13b9bbf | 171 | debug(DEBUG, "Exiting STM32_LowPower::sleep()...\n"); |
biagiomkr | 0:f37bc13b9bbf | 172 | } |
biagiomkr | 0:f37bc13b9bbf | 173 | |
biagiomkr | 0:f37bc13b9bbf | 174 | /** |
biagiomkr | 0:f37bc13b9bbf | 175 | * @brief Enable the STM32 stop mode. |
biagiomkr | 0:f37bc13b9bbf | 176 | * Exit this mode on interrupt using the attachInterruptWakeup() method |
biagiomkr | 0:f37bc13b9bbf | 177 | * or in timer_s seconds. |
biagiomkr | 0:f37bc13b9bbf | 178 | * @param reg: type of power regulator. |
biagiomkr | 0:f37bc13b9bbf | 179 | * @param timer_s: optional delay before leaving the stop mode (default: 0). |
biagiomkr | 0:f37bc13b9bbf | 180 | * @retval None |
biagiomkr | 0:f37bc13b9bbf | 181 | */ |
biagiomkr | 0:f37bc13b9bbf | 182 | void STM32_LowPower::stop(STM32_RegulatorType reg, uint32_t timer_s) |
biagiomkr | 0:f37bc13b9bbf | 183 | { |
biagiomkr | 0:f37bc13b9bbf | 184 | debug(DEBUG, "Starting STM32_LowPower::stop()\n"); |
biagiomkr | 0:f37bc13b9bbf | 185 | |
biagiomkr | 0:f37bc13b9bbf | 186 | __disable_irq(); |
biagiomkr | 0:f37bc13b9bbf | 187 | debug(DEBUG, "STM32_LowPower::stop() -> __disable_irq()\n"); |
biagiomkr | 0:f37bc13b9bbf | 188 | |
biagiomkr | 0:f37bc13b9bbf | 189 | uint32_t regulator; |
biagiomkr | 0:f37bc13b9bbf | 190 | /* Use regulator in main mode */ |
biagiomkr | 0:f37bc13b9bbf | 191 | if (reg == STM32_MAIN_REGULATOR) { |
biagiomkr | 0:f37bc13b9bbf | 192 | regulator = PWR_MAINREGULATOR_ON; |
biagiomkr | 0:f37bc13b9bbf | 193 | debug(DEBUG, "STM32_LowPower::stop() -> regulator: PWR_MAINREGULATOR_ON\n"); |
biagiomkr | 0:f37bc13b9bbf | 194 | } |
biagiomkr | 0:f37bc13b9bbf | 195 | /* Use regulator in low-power mode */ |
biagiomkr | 0:f37bc13b9bbf | 196 | else if (reg == STM32_LOWPOWER_REGULATOR) { |
biagiomkr | 0:f37bc13b9bbf | 197 | regulator = PWR_LOWPOWERREGULATOR_ON; |
biagiomkr | 0:f37bc13b9bbf | 198 | debug(DEBUG, "STM32_LowPower::stop() -> regulator: PWR_LOWPOWERREGULATOR_ON\n"); |
biagiomkr | 0:f37bc13b9bbf | 199 | } else { |
biagiomkr | 0:f37bc13b9bbf | 200 | regulator = PWR_LOWPOWERREGULATOR_ON; |
biagiomkr | 0:f37bc13b9bbf | 201 | } |
biagiomkr | 0:f37bc13b9bbf | 202 | |
biagiomkr | 0:f37bc13b9bbf | 203 | if (timer_s > 0) { |
biagiomkr | 0:f37bc13b9bbf | 204 | programRtcWakeUp(timer_s); |
biagiomkr | 0:f37bc13b9bbf | 205 | debug(DEBUG, "STM32_LowPower::stop() -> programRtcWakeUp(timer_s)\n"); |
biagiomkr | 0:f37bc13b9bbf | 206 | } |
biagiomkr | 0:f37bc13b9bbf | 207 | else if (_rtc_wakeup && (_timer > 0)) { |
biagiomkr | 0:f37bc13b9bbf | 208 | programRtcWakeUp(_timer); |
biagiomkr | 0:f37bc13b9bbf | 209 | debug(DEBUG, "STM32_LowPower::stop() -> programRtcWakeUp(_timer)\n"); |
biagiomkr | 0:f37bc13b9bbf | 210 | } |
biagiomkr | 0:f37bc13b9bbf | 211 | |
biagiomkr | 0:f37bc13b9bbf | 212 | #if defined(STM32L0xx) || defined(STM32L1xx) |
biagiomkr | 0:f37bc13b9bbf | 213 | /* Enable Ultra low power mode */ |
biagiomkr | 0:f37bc13b9bbf | 214 | HAL_PWREx_EnableUltraLowPower(); |
biagiomkr | 0:f37bc13b9bbf | 215 | debug(DEBUG, "STM32_LowPower::stop() -> HAL_PWREx_EnableUltraLowPower()\n"); |
biagiomkr | 0:f37bc13b9bbf | 216 | |
biagiomkr | 0:f37bc13b9bbf | 217 | /* Enable the fast wake up from Ultra low power mode */ |
biagiomkr | 0:f37bc13b9bbf | 218 | HAL_PWREx_EnableFastWakeUp(); |
biagiomkr | 0:f37bc13b9bbf | 219 | debug(DEBUG, "STM32_LowPower::stop() -> HAL_PWREx_EnableFastWakeUp()\n"); |
biagiomkr | 0:f37bc13b9bbf | 220 | #endif |
biagiomkr | 0:f37bc13b9bbf | 221 | #ifdef __HAL_RCC_WAKEUPSTOP_CLK_CONFIG |
biagiomkr | 0:f37bc13b9bbf | 222 | /* Select HSI as system clock source after Wake Up from Stop mode */ |
biagiomkr | 0:f37bc13b9bbf | 223 | __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI); |
biagiomkr | 0:f37bc13b9bbf | 224 | debug(DEBUG, "STM32_LowPower::stop() -> __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI)\n"); |
biagiomkr | 0:f37bc13b9bbf | 225 | #endif |
biagiomkr | 0:f37bc13b9bbf | 226 | |
biagiomkr | 0:f37bc13b9bbf | 227 | /* Enter Stop mode */ |
biagiomkr | 0:f37bc13b9bbf | 228 | debug(DEBUG, "STM32_LowPower::stop() -> HAL_PWR_EnterSTOPMode()\n"); |
biagiomkr | 0:f37bc13b9bbf | 229 | HAL_Delay(20); |
biagiomkr | 0:f37bc13b9bbf | 230 | HAL_PWR_EnterSTOPMode(regulator, PWR_STOPENTRY_WFI); |
biagiomkr | 0:f37bc13b9bbf | 231 | |
biagiomkr | 0:f37bc13b9bbf | 232 | /* Exit Stop mode reset clocks */ |
biagiomkr | 0:f37bc13b9bbf | 233 | SetSysClock(); |
biagiomkr | 0:f37bc13b9bbf | 234 | |
biagiomkr | 0:f37bc13b9bbf | 235 | __enable_irq(); |
biagiomkr | 0:f37bc13b9bbf | 236 | debug(DEBUG, "STM32_LowPower::stop() -> __enable_irq()\n"); |
biagiomkr | 0:f37bc13b9bbf | 237 | |
biagiomkr | 0:f37bc13b9bbf | 238 | HAL_Delay(100); |
biagiomkr | 0:f37bc13b9bbf | 239 | debug(DEBUG, "STM32_LowPower::stop() -> SetSysClock()\n"); |
biagiomkr | 0:f37bc13b9bbf | 240 | |
biagiomkr | 0:f37bc13b9bbf | 241 | if ((timer_s > 0) || _rtc_wakeup) { |
biagiomkr | 0:f37bc13b9bbf | 242 | rtc_deactivate_wake_up_timer(); |
biagiomkr | 0:f37bc13b9bbf | 243 | } |
biagiomkr | 0:f37bc13b9bbf | 244 | |
biagiomkr | 0:f37bc13b9bbf | 245 | debug(DEBUG, "Exiting STM32_LowPower::stop()...\n"); |
biagiomkr | 0:f37bc13b9bbf | 246 | } |
biagiomkr | 0:f37bc13b9bbf | 247 | |
biagiomkr | 0:f37bc13b9bbf | 248 | /** |
biagiomkr | 0:f37bc13b9bbf | 249 | * @brief Enable the STM32 shutdown or standby mode. |
biagiomkr | 0:f37bc13b9bbf | 250 | * Exit this mode on interrupt using the attachInterruptWakeup() method |
biagiomkr | 0:f37bc13b9bbf | 251 | * or in timer_s seconds. |
biagiomkr | 0:f37bc13b9bbf | 252 | * @param timer_s: optional delay before leaving the standby mode (default: 0). |
biagiomkr | 0:f37bc13b9bbf | 253 | * @retval None |
biagiomkr | 0:f37bc13b9bbf | 254 | */ |
biagiomkr | 0:f37bc13b9bbf | 255 | void STM32_LowPower::standby(uint32_t timer_s) |
biagiomkr | 0:f37bc13b9bbf | 256 | { |
biagiomkr | 0:f37bc13b9bbf | 257 | __disable_irq(); |
biagiomkr | 0:f37bc13b9bbf | 258 | debug(DEBUG, "STM32_LowPower::standby() -> __disable_irq()\n"); |
biagiomkr | 0:f37bc13b9bbf | 259 | |
biagiomkr | 0:f37bc13b9bbf | 260 | debug(DEBUG, "Starting STM32_LowPower::standby()...\n"); |
biagiomkr | 0:f37bc13b9bbf | 261 | if (timer_s > 0) { |
biagiomkr | 0:f37bc13b9bbf | 262 | programRtcWakeUp(timer_s); |
biagiomkr | 0:f37bc13b9bbf | 263 | debug(DEBUG, "STM32_LowPower::standby() -> programRtcWakeUp(timer_s)\n"); |
biagiomkr | 0:f37bc13b9bbf | 264 | } |
biagiomkr | 0:f37bc13b9bbf | 265 | else if (_rtc_wakeup && (_timer > 0)) { |
biagiomkr | 0:f37bc13b9bbf | 266 | programRtcWakeUp(_timer); |
biagiomkr | 0:f37bc13b9bbf | 267 | debug(DEBUG, "STM32_LowPower::standby() -> programRtcWakeUp(_timer)\n"); |
biagiomkr | 0:f37bc13b9bbf | 268 | } |
biagiomkr | 0:f37bc13b9bbf | 269 | |
biagiomkr | 0:f37bc13b9bbf | 270 | #if defined(STM32L0xx) || defined(STM32L1xx) |
biagiomkr | 0:f37bc13b9bbf | 271 | /* Enable Ultra low power mode */ |
biagiomkr | 0:f37bc13b9bbf | 272 | HAL_PWREx_EnableUltraLowPower(); |
biagiomkr | 0:f37bc13b9bbf | 273 | debug(DEBUG, "STM32_LowPower::standby() -> HAL_PWREx_EnableUltraLowPower()\n"); |
biagiomkr | 0:f37bc13b9bbf | 274 | |
biagiomkr | 0:f37bc13b9bbf | 275 | /* Enable the fast wake up from Ultra low power mode */ |
biagiomkr | 0:f37bc13b9bbf | 276 | HAL_PWREx_EnableFastWakeUp(); |
biagiomkr | 0:f37bc13b9bbf | 277 | debug(DEBUG, "STM32_LowPower::standby() -> HAL_PWREx_EnableFastWakeUp()\n"); |
biagiomkr | 0:f37bc13b9bbf | 278 | #endif |
biagiomkr | 0:f37bc13b9bbf | 279 | debug(DEBUG, "STM32_LowPower::standby() -> HAL_PWR_EnterSTANDBYMode()\n"); |
biagiomkr | 0:f37bc13b9bbf | 280 | HAL_PWR_EnterSTANDBYMode(); |
biagiomkr | 0:f37bc13b9bbf | 281 | } |
biagiomkr | 0:f37bc13b9bbf | 282 | |
biagiomkr | 0:f37bc13b9bbf | 283 | /** |
biagiomkr | 0:f37bc13b9bbf | 284 | * @brief Enable GPIO pin in interrupt mode. If the pin is a wakeup pin, it is |
biagiomkr | 0:f37bc13b9bbf | 285 | * configured as wakeup source. |
biagiomkr | 0:f37bc13b9bbf | 286 | * @param pin: pin name (PX_Y, where X = GPIO port and Y = GPIO number) |
biagiomkr | 0:f37bc13b9bbf | 287 | * @param callback: pointer to callback function. |
biagiomkr | 0:f37bc13b9bbf | 288 | * @param mode: interrupt mode (IT_MODE_RISING, IT_MODE_FALLING, IT_MODE_RISING_FALLING) |
biagiomkr | 0:f37bc13b9bbf | 289 | * @retval None |
biagiomkr | 0:f37bc13b9bbf | 290 | */ |
biagiomkr | 0:f37bc13b9bbf | 291 | void STM32_LowPower::attachInterruptWakeup(PinName pin, voidFuncPtrVoid callback, |
biagiomkr | 0:f37bc13b9bbf | 292 | Interrupt_Mode mode) |
biagiomkr | 0:f37bc13b9bbf | 293 | { |
biagiomkr | 0:f37bc13b9bbf | 294 | debug(DEBUG, "Starting STM32_LowPower::attachInterruptWakeup()...\n"); |
biagiomkr | 0:f37bc13b9bbf | 295 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> pin: %u\n", pin); |
biagiomkr | 0:f37bc13b9bbf | 296 | _wakeupPin = new InterruptIn(pin); |
biagiomkr | 0:f37bc13b9bbf | 297 | |
biagiomkr | 0:f37bc13b9bbf | 298 | switch (mode) { |
biagiomkr | 0:f37bc13b9bbf | 299 | case IT_MODE_RISING : |
biagiomkr | 0:f37bc13b9bbf | 300 | _wakeupPin->rise(callback); |
biagiomkr | 0:f37bc13b9bbf | 301 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wakeupPin->rise(callback)\n"); |
biagiomkr | 0:f37bc13b9bbf | 302 | break; |
biagiomkr | 0:f37bc13b9bbf | 303 | case IT_MODE_FALLING : |
biagiomkr | 0:f37bc13b9bbf | 304 | _wakeupPin->fall(callback); |
biagiomkr | 0:f37bc13b9bbf | 305 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wakeupPin->fall(callback)\n"); |
biagiomkr | 0:f37bc13b9bbf | 306 | break; |
biagiomkr | 0:f37bc13b9bbf | 307 | case IT_MODE_RISING_FALLING : |
biagiomkr | 0:f37bc13b9bbf | 308 | default: |
biagiomkr | 0:f37bc13b9bbf | 309 | _wakeupPin->rise(callback); |
biagiomkr | 0:f37bc13b9bbf | 310 | _wakeupPin->fall(callback); |
biagiomkr | 0:f37bc13b9bbf | 311 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wakeupPin->rise & fall\n"); |
biagiomkr | 0:f37bc13b9bbf | 312 | break; |
biagiomkr | 0:f37bc13b9bbf | 313 | } |
biagiomkr | 0:f37bc13b9bbf | 314 | |
biagiomkr | 0:f37bc13b9bbf | 315 | /* If Gpio is a Wake up pin activate it in order to wake up the STM32 MCU */ |
biagiomkr | 0:f37bc13b9bbf | 316 | #if !defined(PWR_WAKEUP_PIN1_HIGH) |
biagiomkr | 0:f37bc13b9bbf | 317 | UNUSED(mode); |
biagiomkr | 0:f37bc13b9bbf | 318 | #endif |
biagiomkr | 0:f37bc13b9bbf | 319 | uint32_t wkup_pin; |
biagiomkr | 0:f37bc13b9bbf | 320 | if (pin != NC) { |
biagiomkr | 0:f37bc13b9bbf | 321 | switch (pin) { |
biagiomkr | 0:f37bc13b9bbf | 322 | #ifdef PWR_WAKEUP_PIN1 |
biagiomkr | 0:f37bc13b9bbf | 323 | |
biagiomkr | 0:f37bc13b9bbf | 324 | #if defined(TARGET_DISCO_F100RB) || defined(TARGET_DISCO_F407VG) || \ |
biagiomkr | 0:f37bc13b9bbf | 325 | defined(TARGET_DISCO_F401VC) || defined(TARGET_DISCO_F429ZI) || \ |
biagiomkr | 0:f37bc13b9bbf | 326 | defined(TARGET_NUCLEO_F103RB) || defined(TARGET_NUCLEO_F207ZG) || \ |
biagiomkr | 0:f37bc13b9bbf | 327 | defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || \ |
biagiomkr | 0:f37bc13b9bbf | 328 | defined(TARGET_NUCLEO_F429ZI) || defined(TARGET_NUCLEO_F439ZI) || \ |
biagiomkr | 0:f37bc13b9bbf | 329 | defined(TARGET_NUCLEO_F469NI) || defined(TARGET_MTB_STM_S2LP) |
biagiomkr | 0:f37bc13b9bbf | 330 | case SYS_WKUP : |
biagiomkr | 0:f37bc13b9bbf | 331 | #else |
biagiomkr | 0:f37bc13b9bbf | 332 | case SYS_WKUP1 : |
biagiomkr | 0:f37bc13b9bbf | 333 | #endif |
biagiomkr | 0:f37bc13b9bbf | 334 | wkup_pin = PWR_WAKEUP_PIN1; |
biagiomkr | 0:f37bc13b9bbf | 335 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN1.\n"); |
biagiomkr | 0:f37bc13b9bbf | 336 | #ifdef PWR_WAKEUP_PIN1_HIGH |
biagiomkr | 0:f37bc13b9bbf | 337 | if (mode != IT_MODE_RISING) { |
biagiomkr | 0:f37bc13b9bbf | 338 | wkup_pin = PWR_WAKEUP_PIN1_LOW; |
biagiomkr | 0:f37bc13b9bbf | 339 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN1_LOW.\n"); |
biagiomkr | 0:f37bc13b9bbf | 340 | } |
biagiomkr | 0:f37bc13b9bbf | 341 | #endif |
biagiomkr | 0:f37bc13b9bbf | 342 | break; |
biagiomkr | 0:f37bc13b9bbf | 343 | #endif /* PWR_WAKEUP_PIN1 */ |
biagiomkr | 0:f37bc13b9bbf | 344 | #ifdef PWR_WAKEUP_PIN2 |
biagiomkr | 0:f37bc13b9bbf | 345 | case SYS_WKUP2 : |
biagiomkr | 0:f37bc13b9bbf | 346 | wkup_pin = PWR_WAKEUP_PIN2; |
biagiomkr | 0:f37bc13b9bbf | 347 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN2.\n"); |
biagiomkr | 0:f37bc13b9bbf | 348 | #ifdef PWR_WAKEUP_PIN2_HIGH |
biagiomkr | 0:f37bc13b9bbf | 349 | if (mode != IT_MODE_RISING) { |
biagiomkr | 0:f37bc13b9bbf | 350 | wkup_pin = PWR_WAKEUP_PIN2_LOW; |
biagiomkr | 0:f37bc13b9bbf | 351 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN2_LOW\n"); |
biagiomkr | 0:f37bc13b9bbf | 352 | } |
biagiomkr | 0:f37bc13b9bbf | 353 | #endif |
biagiomkr | 0:f37bc13b9bbf | 354 | break; |
biagiomkr | 0:f37bc13b9bbf | 355 | #endif /* PWR_WAKEUP_PIN2 */ |
biagiomkr | 0:f37bc13b9bbf | 356 | #ifdef PWR_WAKEUP_PIN3 |
biagiomkr | 0:f37bc13b9bbf | 357 | case SYS_WKUP3 : |
biagiomkr | 0:f37bc13b9bbf | 358 | wkup_pin = PWR_WAKEUP_PIN3; |
biagiomkr | 0:f37bc13b9bbf | 359 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN3\n"); |
biagiomkr | 0:f37bc13b9bbf | 360 | #ifdef PWR_WAKEUP_PIN3_HIGH |
biagiomkr | 0:f37bc13b9bbf | 361 | if (mode != IT_MODE_RISING) { |
biagiomkr | 0:f37bc13b9bbf | 362 | wkup_pin = PWR_WAKEUP_PIN3_LOW; |
biagiomkr | 0:f37bc13b9bbf | 363 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN3_LOW\n"); |
biagiomkr | 0:f37bc13b9bbf | 364 | } |
biagiomkr | 0:f37bc13b9bbf | 365 | #endif |
biagiomkr | 0:f37bc13b9bbf | 366 | break; |
biagiomkr | 0:f37bc13b9bbf | 367 | #endif /* PWR_WAKEUP_PIN3 */ |
biagiomkr | 0:f37bc13b9bbf | 368 | #ifdef PWR_WAKEUP_PIN4 |
biagiomkr | 0:f37bc13b9bbf | 369 | case SYS_WKUP4 : |
biagiomkr | 0:f37bc13b9bbf | 370 | wkup_pin = PWR_WAKEUP_PIN4; |
biagiomkr | 0:f37bc13b9bbf | 371 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN4\n"); |
biagiomkr | 0:f37bc13b9bbf | 372 | #ifdef PWR_WAKEUP_PIN4_HIGH |
biagiomkr | 0:f37bc13b9bbf | 373 | if (mode != IT_MODE_RISING) { |
biagiomkr | 0:f37bc13b9bbf | 374 | wkup_pin = PWR_WAKEUP_PIN4_LOW; |
biagiomkr | 0:f37bc13b9bbf | 375 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN4_LOW\n"); |
biagiomkr | 0:f37bc13b9bbf | 376 | } |
biagiomkr | 0:f37bc13b9bbf | 377 | #endif |
biagiomkr | 0:f37bc13b9bbf | 378 | break; |
biagiomkr | 0:f37bc13b9bbf | 379 | #endif /* PWR_WAKEUP_PIN4 */ |
biagiomkr | 0:f37bc13b9bbf | 380 | #ifdef PWR_WAKEUP_PIN5 |
biagiomkr | 0:f37bc13b9bbf | 381 | case SYS_WKUP5 : |
biagiomkr | 0:f37bc13b9bbf | 382 | wkup_pin = PWR_WAKEUP_PIN5; |
biagiomkr | 0:f37bc13b9bbf | 383 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN5\n"); |
biagiomkr | 0:f37bc13b9bbf | 384 | #ifdef PWR_WAKEUP_PIN5_HIGH |
biagiomkr | 0:f37bc13b9bbf | 385 | if (mode != IT_MODE_RISING) { |
biagiomkr | 0:f37bc13b9bbf | 386 | wkup_pin = PWR_WAKEUP_PIN5_LOW; |
biagiomkr | 0:f37bc13b9bbf | 387 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN5_LOW\n"); |
biagiomkr | 0:f37bc13b9bbf | 388 | } |
biagiomkr | 0:f37bc13b9bbf | 389 | #endif |
biagiomkr | 0:f37bc13b9bbf | 390 | break; |
biagiomkr | 0:f37bc13b9bbf | 391 | #endif /* PWR_WAKEUP_PIN5 */ |
biagiomkr | 0:f37bc13b9bbf | 392 | #ifdef PWR_WAKEUP_PIN6 |
biagiomkr | 0:f37bc13b9bbf | 393 | case SYS_WKUP6 : |
biagiomkr | 0:f37bc13b9bbf | 394 | wkup_pin = PWR_WAKEUP_PIN6; |
biagiomkr | 0:f37bc13b9bbf | 395 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN6\n"); |
biagiomkr | 0:f37bc13b9bbf | 396 | #ifdef PWR_WAKEUP_PIN6_HIGH |
biagiomkr | 0:f37bc13b9bbf | 397 | if (mode != IT_MODE_RISING) { |
biagiomkr | 0:f37bc13b9bbf | 398 | wkup_pin = PWR_WAKEUP_PIN6_LOW; |
biagiomkr | 0:f37bc13b9bbf | 399 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN6_LOW\n"); |
biagiomkr | 0:f37bc13b9bbf | 400 | } |
biagiomkr | 0:f37bc13b9bbf | 401 | #endif |
biagiomkr | 0:f37bc13b9bbf | 402 | break; |
biagiomkr | 0:f37bc13b9bbf | 403 | #endif /* PWR_WAKEUP_PIN6 */ |
biagiomkr | 0:f37bc13b9bbf | 404 | #ifdef PWR_WAKEUP_PIN7 |
biagiomkr | 0:f37bc13b9bbf | 405 | case SYS_WKUP7 : |
biagiomkr | 0:f37bc13b9bbf | 406 | wkup_pin = PWR_WAKEUP_PIN7; |
biagiomkr | 0:f37bc13b9bbf | 407 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN7\n"); |
biagiomkr | 0:f37bc13b9bbf | 408 | break; |
biagiomkr | 0:f37bc13b9bbf | 409 | #endif /* PWR_WAKEUP_PIN7 */ |
biagiomkr | 0:f37bc13b9bbf | 410 | #ifdef PWR_WAKEUP_PIN8 |
biagiomkr | 0:f37bc13b9bbf | 411 | case SYS_WKUP8 : |
biagiomkr | 0:f37bc13b9bbf | 412 | wkup_pin = PWR_WAKEUP_PIN8; |
biagiomkr | 0:f37bc13b9bbf | 413 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN7\n"); |
biagiomkr | 0:f37bc13b9bbf | 414 | break; |
biagiomkr | 0:f37bc13b9bbf | 415 | #endif /* PWR_WAKEUP_PIN8 */ |
biagiomkr | 0:f37bc13b9bbf | 416 | default : |
biagiomkr | 0:f37bc13b9bbf | 417 | wkup_pin = PWR_WAKEUP_PIN1; |
biagiomkr | 0:f37bc13b9bbf | 418 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN1 (default case)\n"); |
biagiomkr | 0:f37bc13b9bbf | 419 | #ifdef PWR_WAKEUP_PIN1_HIGH |
biagiomkr | 0:f37bc13b9bbf | 420 | if (mode != IT_MODE_RISING) { |
biagiomkr | 0:f37bc13b9bbf | 421 | wkup_pin = PWR_WAKEUP_PIN1_LOW; |
biagiomkr | 0:f37bc13b9bbf | 422 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN1_LOW (default case)\n"); |
biagiomkr | 0:f37bc13b9bbf | 423 | } |
biagiomkr | 0:f37bc13b9bbf | 424 | #endif |
biagiomkr | 0:f37bc13b9bbf | 425 | break; |
biagiomkr | 0:f37bc13b9bbf | 426 | } |
biagiomkr | 0:f37bc13b9bbf | 427 | |
biagiomkr | 0:f37bc13b9bbf | 428 | HAL_PWR_EnableWakeUpPin(wkup_pin); |
biagiomkr | 0:f37bc13b9bbf | 429 | debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> HAL_PWR_EnableWakeUpPin()\n"); |
biagiomkr | 0:f37bc13b9bbf | 430 | debug(DEBUG, "Exiting STM32_LowPower::attachInterruptWakeup()...\n"); |
biagiomkr | 0:f37bc13b9bbf | 431 | } |
biagiomkr | 0:f37bc13b9bbf | 432 | } |
biagiomkr | 0:f37bc13b9bbf | 433 | |
biagiomkr | 0:f37bc13b9bbf | 434 | /** |
biagiomkr | 0:f37bc13b9bbf | 435 | * @brief Configure the RTC WakeUp Interrupt. |
biagiomkr | 0:f37bc13b9bbf | 436 | * @param millis: time (in seconds) to generate a RTC WakeUp event. |
biagiomkr | 0:f37bc13b9bbf | 437 | * @retval None |
biagiomkr | 0:f37bc13b9bbf | 438 | */ |
biagiomkr | 0:f37bc13b9bbf | 439 | void STM32_LowPower::programRtcWakeUp(uint32_t timer_s) |
biagiomkr | 0:f37bc13b9bbf | 440 | { |
biagiomkr | 0:f37bc13b9bbf | 441 | uint32_t rtc_clock; |
biagiomkr | 0:f37bc13b9bbf | 442 | |
biagiomkr | 0:f37bc13b9bbf | 443 | core_util_critical_section_enter(); |
biagiomkr | 0:f37bc13b9bbf | 444 | debug(DEBUG, "STM32_LowPower::programRtcWakeUp() -> core_util_critical_section_enter()\n"); |
biagiomkr | 0:f37bc13b9bbf | 445 | |
biagiomkr | 0:f37bc13b9bbf | 446 | rtc_clock = RTC_WAKEUPCLOCK_CK_SPRE_16BITS; |
biagiomkr | 0:f37bc13b9bbf | 447 | |
biagiomkr | 0:f37bc13b9bbf | 448 | /* Clear wakeup flag, just in case. */ |
biagiomkr | 0:f37bc13b9bbf | 449 | SET_BIT(PWR->CR, PWR_CR_CWUF); |
biagiomkr | 0:f37bc13b9bbf | 450 | |
biagiomkr | 0:f37bc13b9bbf | 451 | /* HAL_RTCEx_SetWakeUpTimer_IT will assert that timer_s is 0xFFFF at max */ |
biagiomkr | 0:f37bc13b9bbf | 452 | if (timer_s > 0xFFFF) { |
biagiomkr | 0:f37bc13b9bbf | 453 | timer_s -= 0x10000; |
biagiomkr | 0:f37bc13b9bbf | 454 | rtc_clock = RTC_WAKEUPCLOCK_CK_SPRE_17BITS; |
biagiomkr | 0:f37bc13b9bbf | 455 | } |
biagiomkr | 0:f37bc13b9bbf | 456 | |
biagiomkr | 0:f37bc13b9bbf | 457 | RtcHandle.Instance = RTC; |
biagiomkr | 0:f37bc13b9bbf | 458 | |
biagiomkr | 0:f37bc13b9bbf | 459 | HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, timer_s, rtc_clock); |
biagiomkr | 0:f37bc13b9bbf | 460 | debug(DEBUG, "STM32_LowPower::programRtcWakeUp() -> HAL_RTCEx_SetWakeUpTimer_IT()\n"); |
biagiomkr | 0:f37bc13b9bbf | 461 | |
biagiomkr | 0:f37bc13b9bbf | 462 | NVIC_SetVector(RTC_WKUP_IRQn, (uint32_t)RTC_IRQHandler); |
biagiomkr | 0:f37bc13b9bbf | 463 | NVIC_EnableIRQ(RTC_WKUP_IRQn); |
biagiomkr | 0:f37bc13b9bbf | 464 | |
biagiomkr | 0:f37bc13b9bbf | 465 | core_util_critical_section_exit(); |
biagiomkr | 0:f37bc13b9bbf | 466 | debug(DEBUG, "STM32_LowPower::programRtcWakeUp() -> core_util_critical_section_exit()\n"); |
biagiomkr | 0:f37bc13b9bbf | 467 | } |
biagiomkr | 0:f37bc13b9bbf | 468 | |
biagiomkr | 0:f37bc13b9bbf | 469 | /** |
biagiomkr | 0:f37bc13b9bbf | 470 | * @brief Attach a callback to a RTC WakeUp event. |
biagiomkr | 0:f37bc13b9bbf | 471 | * @param callback: callback function called when leaving the low power mode. |
biagiomkr | 0:f37bc13b9bbf | 472 | * @param data: optional pointer to callback data parameters (default NULL). |
biagiomkr | 0:f37bc13b9bbf | 473 | * @retval None |
biagiomkr | 0:f37bc13b9bbf | 474 | */ |
biagiomkr | 0:f37bc13b9bbf | 475 | void STM32_LowPower::enableWakeupFromRTC(voidFuncPtr callback, void *data, |
biagiomkr | 0:f37bc13b9bbf | 476 | uint32_t timer_s) |
biagiomkr | 0:f37bc13b9bbf | 477 | { |
biagiomkr | 0:f37bc13b9bbf | 478 | _rtc_wakeup = true; |
biagiomkr | 0:f37bc13b9bbf | 479 | if (timer_s > 0) { |
biagiomkr | 0:f37bc13b9bbf | 480 | _timer = timer_s; |
biagiomkr | 0:f37bc13b9bbf | 481 | } |
biagiomkr | 0:f37bc13b9bbf | 482 | RTCUserCallback = callback; |
biagiomkr | 0:f37bc13b9bbf | 483 | callbackUserData = data; |
biagiomkr | 0:f37bc13b9bbf | 484 | } |