Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
STM32_LowPower.cpp
00001 /** 00002 ****************************************************************************** 00003 * @file STM32_LowPower.cpp 00004 * @author Biagio Montaruli, STM32duino team (STMicroelectronics) 00005 * @version V1.0.0 00006 * @date 12-April-2019 00007 * @brief Mbed Library to manage Low Power modes on STM32 boards 00008 * 00009 ****************************************************************************** 00010 * @attention 00011 * 00012 * <h2><center>© COPYRIGHT(c) 2019 STMicroelectronics</center></h2> 00013 * <h2><center>© COPYRIGHT(c) 2019 Biagio Montaruli</center></h2> 00014 * 00015 * Redistribution and use in source and binary forms, with or without modification, 00016 * are permitted provided that the following conditions are met: 00017 * 1. Redistributions of source code must retain the above copyright notice, 00018 * this list of conditions and the following disclaimer. 00019 * 2. Redistributions in binary form must reproduce the above copyright notice, 00020 * this list of conditions and the following disclaimer in the documentation 00021 * and/or other materials provided with the distribution. 00022 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00023 * may be used to endorse or promote products derived from this software 00024 * without specific prior written permission. 00025 * 00026 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00027 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00029 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00030 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00031 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00032 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00033 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00034 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00035 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00036 * 00037 ****************************************************************************** 00038 */ 00039 00040 #include "STM32_LowPower.h" 00041 #include "rtc_api_hal.h" 00042 00043 STM32_LowPower LowPower; 00044 00045 static RTC_HandleTypeDef RtcHandle; 00046 static voidFuncPtr RTCUserCallback = NULL; 00047 static void *callbackUserData = NULL; 00048 00049 void HAL_RTCEx_WakeUpTimerEventCallback(RTC_HandleTypeDef *hrtc) 00050 { 00051 UNUSED(hrtc); 00052 00053 if (RTCUserCallback != NULL) { 00054 RTCUserCallback(callbackUserData); 00055 } 00056 } 00057 00058 void RTC_IRQHandler(void) 00059 { 00060 HAL_RTCEx_WakeUpTimerIRQHandler(&RtcHandle); 00061 } 00062 00063 #ifdef STM32G0xx 00064 #define PWR_FLAG_WU PWR_FLAG_WUF 00065 #endif 00066 00067 STM32_LowPower::STM32_LowPower() 00068 { 00069 _configured = false; 00070 _rtc_wakeup = false; 00071 _timer = 0; 00072 } 00073 00074 /** 00075 * @brief Initializes the low power mode 00076 * @param None 00077 * @retval None 00078 */ 00079 void STM32_LowPower::init(void) 00080 { 00081 debug(DEBUG, "Starting STM32_LowPower::init()\n"); 00082 /* Initialize Low Power mode using STM32 HAL */ 00083 #if !defined(STM32H7xx) && !defined(STM32WBxx) 00084 /* Enable Power Clock */ 00085 __HAL_RCC_PWR_CLK_ENABLE(); 00086 debug(DEBUG, "STM32_LowPower::init() -> __HAL_RCC_PWR_CLK_ENABLE()\n"); 00087 #endif 00088 /* Allow access to Backup domain */ 00089 HAL_PWR_EnableBkUpAccess(); 00090 debug(DEBUG, "STM32_LowPower::init() -> HAL_PWR_EnableBkUpAccess()\n"); 00091 00092 #ifdef __HAL_RCC_WAKEUPSTOP_CLK_CONFIG 00093 /* Ensure that HSI is wake-up system clock */ 00094 __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI); 00095 debug(DEBUG, "STM32_LowPower::init() -> __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI)\n"); 00096 #endif 00097 /* Check if the system was resumed from StandBy mode */ 00098 if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET) { 00099 /* Clear Standby flag */ 00100 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB); 00101 debug(DEBUG, "STM32_LowPower::init() -> __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB)\n"); 00102 } 00103 00104 /* Clear all related wakeup flags */ 00105 __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU); 00106 debug(DEBUG, "STM32_LowPower::init() -> __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU)\n"); 00107 00108 /* start RTC */ 00109 set_time(0); 00110 00111 _configured = true; 00112 debug(DEBUG, "Exiting STM32_LowPower::init()...\n"); 00113 } 00114 00115 /** 00116 * @brief Enable the STM32 sleep mode. 00117 * Exit this mode on interrupt using the attachInterruptWakeup() method 00118 * or in timer_s seconds. 00119 * @param reg: type of power regulator. 00120 * @param timer_s: optional delay before leaving the sleep mode (default: 0). 00121 * @retval None 00122 */ 00123 void STM32_LowPower::sleep(STM32_RegulatorType reg, uint32_t timer_s) 00124 { 00125 debug(DEBUG, "Starting STM32_LowPower::sleep()...\n"); 00126 00127 uint32_t regulator; 00128 00129 /* Enable STM32 Sleep Mode: regulator in main mode */ 00130 if (reg == STM32_MAIN_REGULATOR) { 00131 regulator = PWR_MAINREGULATOR_ON; 00132 debug(DEBUG, "STM32_LowPower::sleep() -> regulator: PWR_MAINREGULATOR_ON\n"); 00133 } 00134 /* Enable STM32 Low-power Sleep Mode: regulator in low-power mode */ 00135 else if (reg == STM32_LOWPOWER_REGULATOR) { 00136 regulator = PWR_LOWPOWERREGULATOR_ON; 00137 debug(DEBUG, "STM32_LowPower::sleep() -> regulator: PWR_LOWPOWERREGULATOR_ON\n"); 00138 } else { 00139 regulator = PWR_MAINREGULATOR_ON; 00140 } 00141 00142 if (timer_s > 0) { 00143 programRtcWakeUp(timer_s); 00144 debug(DEBUG, "STM32_LowPower::sleep() -> programRtcWakeUp(timer_s)\n"); 00145 } 00146 else if (_rtc_wakeup && (_timer > 0)) { 00147 programRtcWakeUp(_timer); 00148 debug(DEBUG, "STM32_LowPower::sleep() -> programRtcWakeUp(_timer)\n"); 00149 } 00150 00151 /* 00152 * Suspend Tick increment to prevent wakeup by Systick interrupt. 00153 * Otherwise the Systick interrupt will wake up the device within 00154 * 1ms (HAL time base) 00155 */ 00156 HAL_SuspendTick(); 00157 debug(DEBUG, "STM32_LowPower::sleep() -> HAL_SuspendTick()\n"); 00158 00159 /* Enter Sleep Mode */ 00160 debug(DEBUG, "STM32_LowPower::sleep() -> HAL_PWR_EnterSLEEPMode()\n"); 00161 HAL_PWR_EnterSLEEPMode(regulator, PWR_SLEEPENTRY_WFI); 00162 00163 /* Resume Tick interrupt if disabled before switching into Sleep mode */ 00164 HAL_ResumeTick(); 00165 debug(DEBUG, "STM32_LowPower::sleep() -> HAL_ResumeTick()\n"); 00166 00167 if ((timer_s > 0) || _rtc_wakeup) { 00168 rtc_deactivate_wake_up_timer(); 00169 } 00170 00171 debug(DEBUG, "Exiting STM32_LowPower::sleep()...\n"); 00172 } 00173 00174 /** 00175 * @brief Enable the STM32 stop mode. 00176 * Exit this mode on interrupt using the attachInterruptWakeup() method 00177 * or in timer_s seconds. 00178 * @param reg: type of power regulator. 00179 * @param timer_s: optional delay before leaving the stop mode (default: 0). 00180 * @retval None 00181 */ 00182 void STM32_LowPower::stop(STM32_RegulatorType reg, uint32_t timer_s) 00183 { 00184 debug(DEBUG, "Starting STM32_LowPower::stop()\n"); 00185 00186 __disable_irq(); 00187 debug(DEBUG, "STM32_LowPower::stop() -> __disable_irq()\n"); 00188 00189 uint32_t regulator; 00190 /* Use regulator in main mode */ 00191 if (reg == STM32_MAIN_REGULATOR) { 00192 regulator = PWR_MAINREGULATOR_ON; 00193 debug(DEBUG, "STM32_LowPower::stop() -> regulator: PWR_MAINREGULATOR_ON\n"); 00194 } 00195 /* Use regulator in low-power mode */ 00196 else if (reg == STM32_LOWPOWER_REGULATOR) { 00197 regulator = PWR_LOWPOWERREGULATOR_ON; 00198 debug(DEBUG, "STM32_LowPower::stop() -> regulator: PWR_LOWPOWERREGULATOR_ON\n"); 00199 } else { 00200 regulator = PWR_LOWPOWERREGULATOR_ON; 00201 } 00202 00203 if (timer_s > 0) { 00204 programRtcWakeUp(timer_s); 00205 debug(DEBUG, "STM32_LowPower::stop() -> programRtcWakeUp(timer_s)\n"); 00206 } 00207 else if (_rtc_wakeup && (_timer > 0)) { 00208 programRtcWakeUp(_timer); 00209 debug(DEBUG, "STM32_LowPower::stop() -> programRtcWakeUp(_timer)\n"); 00210 } 00211 00212 #if defined(STM32L0xx) || defined(STM32L1xx) 00213 /* Enable Ultra low power mode */ 00214 HAL_PWREx_EnableUltraLowPower(); 00215 debug(DEBUG, "STM32_LowPower::stop() -> HAL_PWREx_EnableUltraLowPower()\n"); 00216 00217 /* Enable the fast wake up from Ultra low power mode */ 00218 HAL_PWREx_EnableFastWakeUp(); 00219 debug(DEBUG, "STM32_LowPower::stop() -> HAL_PWREx_EnableFastWakeUp()\n"); 00220 #endif 00221 #ifdef __HAL_RCC_WAKEUPSTOP_CLK_CONFIG 00222 /* Select HSI as system clock source after Wake Up from Stop mode */ 00223 __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI); 00224 debug(DEBUG, "STM32_LowPower::stop() -> __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(RCC_STOP_WAKEUPCLOCK_HSI)\n"); 00225 #endif 00226 00227 /* Enter Stop mode */ 00228 debug(DEBUG, "STM32_LowPower::stop() -> HAL_PWR_EnterSTOPMode()\n"); 00229 HAL_Delay(20); 00230 HAL_PWR_EnterSTOPMode(regulator, PWR_STOPENTRY_WFI); 00231 00232 /* Exit Stop mode reset clocks */ 00233 SetSysClock(); 00234 00235 __enable_irq(); 00236 debug(DEBUG, "STM32_LowPower::stop() -> __enable_irq()\n"); 00237 00238 HAL_Delay(100); 00239 debug(DEBUG, "STM32_LowPower::stop() -> SetSysClock()\n"); 00240 00241 if ((timer_s > 0) || _rtc_wakeup) { 00242 rtc_deactivate_wake_up_timer(); 00243 } 00244 00245 debug(DEBUG, "Exiting STM32_LowPower::stop()...\n"); 00246 } 00247 00248 /** 00249 * @brief Enable the STM32 shutdown or standby mode. 00250 * Exit this mode on interrupt using the attachInterruptWakeup() method 00251 * or in timer_s seconds. 00252 * @param timer_s: optional delay before leaving the standby mode (default: 0). 00253 * @retval None 00254 */ 00255 void STM32_LowPower::standby(uint32_t timer_s) 00256 { 00257 __disable_irq(); 00258 debug(DEBUG, "STM32_LowPower::standby() -> __disable_irq()\n"); 00259 00260 debug(DEBUG, "Starting STM32_LowPower::standby()...\n"); 00261 if (timer_s > 0) { 00262 programRtcWakeUp(timer_s); 00263 debug(DEBUG, "STM32_LowPower::standby() -> programRtcWakeUp(timer_s)\n"); 00264 } 00265 else if (_rtc_wakeup && (_timer > 0)) { 00266 programRtcWakeUp(_timer); 00267 debug(DEBUG, "STM32_LowPower::standby() -> programRtcWakeUp(_timer)\n"); 00268 } 00269 00270 #if defined(STM32L0xx) || defined(STM32L1xx) 00271 /* Enable Ultra low power mode */ 00272 HAL_PWREx_EnableUltraLowPower(); 00273 debug(DEBUG, "STM32_LowPower::standby() -> HAL_PWREx_EnableUltraLowPower()\n"); 00274 00275 /* Enable the fast wake up from Ultra low power mode */ 00276 HAL_PWREx_EnableFastWakeUp(); 00277 debug(DEBUG, "STM32_LowPower::standby() -> HAL_PWREx_EnableFastWakeUp()\n"); 00278 #endif 00279 debug(DEBUG, "STM32_LowPower::standby() -> HAL_PWR_EnterSTANDBYMode()\n"); 00280 HAL_PWR_EnterSTANDBYMode(); 00281 } 00282 00283 /** 00284 * @brief Enable GPIO pin in interrupt mode. If the pin is a wakeup pin, it is 00285 * configured as wakeup source. 00286 * @param pin: pin name (PX_Y, where X = GPIO port and Y = GPIO number) 00287 * @param callback: pointer to callback function. 00288 * @param mode: interrupt mode (IT_MODE_RISING, IT_MODE_FALLING, IT_MODE_RISING_FALLING) 00289 * @retval None 00290 */ 00291 void STM32_LowPower::attachInterruptWakeup(PinName pin, voidFuncPtrVoid callback, 00292 Interrupt_Mode mode) 00293 { 00294 debug(DEBUG, "Starting STM32_LowPower::attachInterruptWakeup()...\n"); 00295 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> pin: %u\n", pin); 00296 _wakeupPin = new InterruptIn(pin); 00297 00298 switch (mode) { 00299 case IT_MODE_RISING : 00300 _wakeupPin->rise(callback); 00301 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wakeupPin->rise(callback)\n"); 00302 break; 00303 case IT_MODE_FALLING : 00304 _wakeupPin->fall(callback); 00305 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wakeupPin->fall(callback)\n"); 00306 break; 00307 case IT_MODE_RISING_FALLING : 00308 default: 00309 _wakeupPin->rise(callback); 00310 _wakeupPin->fall(callback); 00311 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wakeupPin->rise & fall\n"); 00312 break; 00313 } 00314 00315 /* If Gpio is a Wake up pin activate it in order to wake up the STM32 MCU */ 00316 #if !defined(PWR_WAKEUP_PIN1_HIGH) 00317 UNUSED(mode); 00318 #endif 00319 uint32_t wkup_pin; 00320 if (pin != NC) { 00321 switch (pin) { 00322 #ifdef PWR_WAKEUP_PIN1 00323 00324 #if defined(TARGET_DISCO_F100RB) || defined(TARGET_DISCO_F407VG) || \ 00325 defined(TARGET_DISCO_F401VC) || defined(TARGET_DISCO_F429ZI) || \ 00326 defined(TARGET_NUCLEO_F103RB) || defined(TARGET_NUCLEO_F207ZG) || \ 00327 defined(TARGET_NUCLEO_F401RE) || defined(TARGET_NUCLEO_F411RE) || \ 00328 defined(TARGET_NUCLEO_F429ZI) || defined(TARGET_NUCLEO_F439ZI) || \ 00329 defined(TARGET_NUCLEO_F469NI) || defined(TARGET_MTB_STM_S2LP) 00330 case SYS_WKUP : 00331 #else 00332 case SYS_WKUP1 : 00333 #endif 00334 wkup_pin = PWR_WAKEUP_PIN1; 00335 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN1.\n"); 00336 #ifdef PWR_WAKEUP_PIN1_HIGH 00337 if (mode != IT_MODE_RISING) { 00338 wkup_pin = PWR_WAKEUP_PIN1_LOW; 00339 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN1_LOW.\n"); 00340 } 00341 #endif 00342 break; 00343 #endif /* PWR_WAKEUP_PIN1 */ 00344 #ifdef PWR_WAKEUP_PIN2 00345 case SYS_WKUP2 : 00346 wkup_pin = PWR_WAKEUP_PIN2; 00347 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN2.\n"); 00348 #ifdef PWR_WAKEUP_PIN2_HIGH 00349 if (mode != IT_MODE_RISING) { 00350 wkup_pin = PWR_WAKEUP_PIN2_LOW; 00351 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN2_LOW\n"); 00352 } 00353 #endif 00354 break; 00355 #endif /* PWR_WAKEUP_PIN2 */ 00356 #ifdef PWR_WAKEUP_PIN3 00357 case SYS_WKUP3 : 00358 wkup_pin = PWR_WAKEUP_PIN3; 00359 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN3\n"); 00360 #ifdef PWR_WAKEUP_PIN3_HIGH 00361 if (mode != IT_MODE_RISING) { 00362 wkup_pin = PWR_WAKEUP_PIN3_LOW; 00363 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN3_LOW\n"); 00364 } 00365 #endif 00366 break; 00367 #endif /* PWR_WAKEUP_PIN3 */ 00368 #ifdef PWR_WAKEUP_PIN4 00369 case SYS_WKUP4 : 00370 wkup_pin = PWR_WAKEUP_PIN4; 00371 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN4\n"); 00372 #ifdef PWR_WAKEUP_PIN4_HIGH 00373 if (mode != IT_MODE_RISING) { 00374 wkup_pin = PWR_WAKEUP_PIN4_LOW; 00375 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN4_LOW\n"); 00376 } 00377 #endif 00378 break; 00379 #endif /* PWR_WAKEUP_PIN4 */ 00380 #ifdef PWR_WAKEUP_PIN5 00381 case SYS_WKUP5 : 00382 wkup_pin = PWR_WAKEUP_PIN5; 00383 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN5\n"); 00384 #ifdef PWR_WAKEUP_PIN5_HIGH 00385 if (mode != IT_MODE_RISING) { 00386 wkup_pin = PWR_WAKEUP_PIN5_LOW; 00387 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN5_LOW\n"); 00388 } 00389 #endif 00390 break; 00391 #endif /* PWR_WAKEUP_PIN5 */ 00392 #ifdef PWR_WAKEUP_PIN6 00393 case SYS_WKUP6 : 00394 wkup_pin = PWR_WAKEUP_PIN6; 00395 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN6\n"); 00396 #ifdef PWR_WAKEUP_PIN6_HIGH 00397 if (mode != IT_MODE_RISING) { 00398 wkup_pin = PWR_WAKEUP_PIN6_LOW; 00399 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN6_LOW\n"); 00400 } 00401 #endif 00402 break; 00403 #endif /* PWR_WAKEUP_PIN6 */ 00404 #ifdef PWR_WAKEUP_PIN7 00405 case SYS_WKUP7 : 00406 wkup_pin = PWR_WAKEUP_PIN7; 00407 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN7\n"); 00408 break; 00409 #endif /* PWR_WAKEUP_PIN7 */ 00410 #ifdef PWR_WAKEUP_PIN8 00411 case SYS_WKUP8 : 00412 wkup_pin = PWR_WAKEUP_PIN8; 00413 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN7\n"); 00414 break; 00415 #endif /* PWR_WAKEUP_PIN8 */ 00416 default : 00417 wkup_pin = PWR_WAKEUP_PIN1; 00418 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN1 (default case)\n"); 00419 #ifdef PWR_WAKEUP_PIN1_HIGH 00420 if (mode != IT_MODE_RISING) { 00421 wkup_pin = PWR_WAKEUP_PIN1_LOW; 00422 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> wkup_pin = PWR_WAKEUP_PIN1_LOW (default case)\n"); 00423 } 00424 #endif 00425 break; 00426 } 00427 00428 HAL_PWR_EnableWakeUpPin(wkup_pin); 00429 debug(DEBUG, "STM32_LowPower::attachInterruptWakeup() -> HAL_PWR_EnableWakeUpPin()\n"); 00430 debug(DEBUG, "Exiting STM32_LowPower::attachInterruptWakeup()...\n"); 00431 } 00432 } 00433 00434 /** 00435 * @brief Configure the RTC WakeUp Interrupt. 00436 * @param millis: time (in seconds) to generate a RTC WakeUp event. 00437 * @retval None 00438 */ 00439 void STM32_LowPower::programRtcWakeUp(uint32_t timer_s) 00440 { 00441 uint32_t rtc_clock; 00442 00443 core_util_critical_section_enter(); 00444 debug(DEBUG, "STM32_LowPower::programRtcWakeUp() -> core_util_critical_section_enter()\n"); 00445 00446 rtc_clock = RTC_WAKEUPCLOCK_CK_SPRE_16BITS; 00447 00448 /* Clear wakeup flag, just in case. */ 00449 SET_BIT(PWR->CR, PWR_CR_CWUF); 00450 00451 /* HAL_RTCEx_SetWakeUpTimer_IT will assert that timer_s is 0xFFFF at max */ 00452 if (timer_s > 0xFFFF) { 00453 timer_s -= 0x10000; 00454 rtc_clock = RTC_WAKEUPCLOCK_CK_SPRE_17BITS; 00455 } 00456 00457 RtcHandle.Instance = RTC; 00458 00459 HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, timer_s, rtc_clock); 00460 debug(DEBUG, "STM32_LowPower::programRtcWakeUp() -> HAL_RTCEx_SetWakeUpTimer_IT()\n"); 00461 00462 NVIC_SetVector(RTC_WKUP_IRQn, (uint32_t)RTC_IRQHandler); 00463 NVIC_EnableIRQ(RTC_WKUP_IRQn); 00464 00465 core_util_critical_section_exit(); 00466 debug(DEBUG, "STM32_LowPower::programRtcWakeUp() -> core_util_critical_section_exit()\n"); 00467 } 00468 00469 /** 00470 * @brief Attach a callback to a RTC WakeUp event. 00471 * @param callback: callback function called when leaving the low power mode. 00472 * @param data: optional pointer to callback data parameters (default NULL). 00473 * @retval None 00474 */ 00475 void STM32_LowPower::enableWakeupFromRTC(voidFuncPtr callback, void *data, 00476 uint32_t timer_s) 00477 { 00478 _rtc_wakeup = true; 00479 if (timer_s > 0) { 00480 _timer = timer_s; 00481 } 00482 RTCUserCallback = callback; 00483 callbackUserData = data; 00484 }
Generated on Wed Jul 13 2022 07:20:35 by
1.7.2