cancel
Showing results for 
Search instead for 
Did you mean: 

How to wake up a STM32F412RG using RTC Wakeup timer interrupt after going to standby mode?

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);
}
  • A function to enter standby mode
/**
  * @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.");
}
  • SetupWakeupTimer
#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;
}
  • Function to get the current time
#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;
}
  • Function to configure a RTC Handler
#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;
}

0 REPLIES 0