2021-03-08 03:43 AM
Here are my codes and I confirmed that the chip went to standby mode, but could not get any sign of waking up.
If you have some idea to wake the arduino up, it will be appreciative if you share me.
Best regards,
bool ActionRtcSleep()
{
int8_t i;
delay(3000);
// Configure board specific settin
/* Enable PWR clock */
__HAL_RCC_PWR_CLK_ENABLE();
/* TODO Enable BKP clock */
// __HAL_RCC_BKPSRAM_CLK_ENABLE();
/* Allow access to BKP Domain */
HAL_PWR_EnableBkUpAccess();
// 1.Configure and enable the EXTI Line 22 in interrupt mode and select the rising edge sensitivity.
__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
__HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_RISING_EDGE();
// 2. Configure and enable the RTC_WKUP IRQ channel in the NVIC.
__NVIC_EnableIRQ(RTC_WKUP_IRQn);
// 3. Configure the RTC to generate the RTC wakeup timer event.
/* Configure RTC clock source and prescaler */
ConfigureRTC();
/*******************************************************/
// Clear flags
Serial.println("Start clearing flags");
/* Check and Clear the Wakeup flag */
if(__HAL_PWR_GET_FLAG(PWR_FLAG_WU) != RESET)
{
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
}
/* Check if the system was resumed from StandBy mode */
if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB) != RESET)
{
/* Clear StandBy flag */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
}
/* wait to stabilize COM output */
for (i=3;i>0;i--)
{
Serial.printf("%u...", i);
delay(1000);
}
Serial.println("Entering into Standby Mode");
delay(100);
/*******************************************************/
// Set up RTC
/* Wait till RTC Second event occurs */
__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAWF);
while(__HAL_RTC_ALARM_GET_FLAG(&hrtc, RTC_FLAG_ALRAWF) == HAL_RTC_STATE_RESET);
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Set the RTC Alarm after 4s */
SetupWakeupTimer();
/* Wait until last write operation on RTC registers has finished */
RTC_WaitForLastTask();
/* Request to enter STANDBY mode (Wake Up flag is cleared in PWR_EnterSTANDBYMode function) */
PWR_EnterSTANDBYMode();
Serial.println("Action: Action sleep ended.");
return true;
}
void RTC_WaitForLastTask(void)
{
__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);
}
/**
* @brief Enters STANDBY mode.
* @param None
* @retval None
*/
void PWR_EnterSTANDBYMode(void)
{
// Clear Wake-up flag
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
// Select STANDBY mode
PWR->CR |= PWR_FLAG_SB;
// Set SLEEPDEEP bit of Cortex System Control Register
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
// This option is used to ensure that store operations are completed
__DSB();
// Request Wait For Interrupt
Serial.println("Going to sleep.");
delay(2000);
__WFI();
Serial.println("Woke up by a timer before delay.");
delay(5000);
Serial.println("Woke up by a timer after delay.");
}
#include <Arduino.h>
#include "SetupWakeupTimer.h"
#include "ConfigureRTC.h"
#include "stm32f4xx_hal_rtc.h"
#include "stm32f4xx_hal_rtc_ex.h"
#define RTC_WUT_TIME ((uint32_t)5) /* 5 s */
/**
*
* */
bool SetupWakeupTimer()
{
uint32_t tickstart;
// 1. Disable the RTC registers Write protection
__HAL_RTC_WRITEPROTECTION_DISABLE(&hrtc);
// 2. Disable the wakeup timer.
__HAL_RTC_WAKEUPTIMER_DISABLE(&hrtc);
// __HAL_RTC_WAKEUPTIMER_DISABLE_IT(&hrtc, RTC_IT_WUT);
// __HAL_RTC_WAKEUPTIMER_EXTI_DISABLE_IT();
// 3. Ensure access to Wakeup auto-reload counter & bits WUCKSEL[2:0] is allowed.
__HAL_RTC_WAKEUPTIMER_GET_FLAG(&hrtc, RTC_FLAG_WUTWF);
// 4. Program the value into the wakeup timer.
/*## Setting the Wake up time ############################################*/
/* RTC Wakeup Interrupt Generation:
Wakeup Time Base = (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI))
Wakeup Time = Wakeup Time Base * WakeUpCounter
= (RTC_WAKEUPCLOCK_RTCCLK_DIV /(LSE or LSI)) * WakeUpCounter
==> WakeUpCounter = Wakeup Time / Wakeup Time Base
To configure the wake up timer to 4s the WakeUpCounter is set to 0x1FFF:
RTC_WAKEUPCLOCK_RTCCLK_DIV = RTCCLK_Div16 = 16
Wakeup Time Base = 16 /(~39.000KHz) = ~0,410 ms
Wakeup Time = ~4s = 0,410ms * WakeUpCounter
==> WakeUpCounter = ~4s/0,410ms = 9750 = 0x2616 */
// 24375 -> 0x5F37
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 0x5F37, RTC_WAKEUPCLOCK_RTCCLK_DIV16);
// 5. Select the desired clock source.
tickstart = HAL_GetTick();
while((hrtc.Instance->ISR & RTC_ISR_RSF) == 0U)
{
if((HAL_GetTick() - tickstart ) > RTC_TIMEOUT_VALUE)
{
Serial.println("Failure: Couldn't get RTC Tick.");
return false;
}
}
// /////////�?Start】 Temporarily added /////////
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
HAL_RTCEx_WakeUpTimerIRQHandler(&hrtc);
// ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
// /////////�?End 】 Temporarily added /////////
// 6. Re-enable the wakeup timer.
__HAL_RTC_WAKEUPTIMER_ENABLE(&hrtc);
// __HAL_RTC_WAKEUPTIMER_ENABLE_IT(&hrtc, RTC_IT_WUT);
// __HAL_RTC_WAKEUPTIMER_EXTI_ENABLE_IT();
// 7. Enable the RTC registers Write protection
__HAL_RTC_WRITEPROTECTION_ENABLE(&hrtc);
Serial.println("Wake-up timer is ready.");
return true;
}
#include <ctime>
#include <Arduino.h>
tm* GetCurrentTime()
{
// current date/time based on current system
time_t now = time(0);
tm *ltm = localtime(&now);
Serial.printf("Local time is ... %d/%d/%d %d:%d:%d\n", ltm->tm_year, (ltm->tm_mon + 1), ltm->tm_mday, ltm->tm_hour, ltm->tm_min, ltm->tm_sec);
return ltm;
}
#include <ctime>
#include <Arduino.h>
#include "ConfigureRTC.h"
#include "GetCurrentTime.h"
RTC_HandleTypeDef hrtc;
/**
* This function configures an instance of RTC_HandleTypeDef
* @param None
* @return None
*/
void ConfigureRTC(void)
{
RTC_TimeTypeDef sTime;
RTC_DateTypeDef sDate;
tm *ltm = GetCurrentTime();
hrtc.Instance = RTC;
hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
hrtc.Init.AsynchPrediv = 127;
hrtc.Init.SynchPrediv = 255;
hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
hrtc.Lock = HAL_UNLOCKED;
hrtc.State = HAL_RTC_STATE_READY;
HAL_RTC_MspInit(&hrtc); // Execute the method to enable RTC
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
/* Initialisation Error */
Serial.println("RTC Initialisation failed.");
return;
}
// Configure RTC Handler settings if date and time are not set yet
if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2)
{
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
// Configure all settings
sTime.TimeFormat = RTC_HOURFORMAT_24; // 24 hours
sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE ; // non-summer time
sTime.StoreOperation = RTC_STOREOPERATION_RESET; // no settings of summer time
sTime.Seconds = (uint8_t)ltm->tm_sec;
sTime.Minutes = (uint8_t)ltm->tm_min;
sTime.Hours = (uint8_t)ltm->tm_hour;
sTime.SecondFraction = (uint32_t) 0;
if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
{
/* Time Setting Error */
Serial.println("RTC Time setting failed.");
return;
}
Serial.printf("RTC hours:minutes:seconds ... %d:%d:%d\n", sTime.Hours, sTime.Minutes, sTime.Seconds);
sDate.WeekDay = (uint8_t)((ltm->tm_wday % 7 != 0) ? ltm->tm_wday : 7);
sDate.Date = (uint8_t)ltm->tm_mday;
sDate.Month = (uint8_t)(ltm->tm_mon + 1);
sDate.Year = (uint8_t)(ltm->tm_year % 100);
if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
{
/* Date Setting Error */
Serial.println("RTC Date setting failed.");
return;
}
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, MAGIC_NO);
}
Serial.println("RTC Configuration successfully finished.");
return;
}