cancel
Showing results for 
Search instead for 
Did you mean: 

(STM32WLE5CC) How to set up RTC Calendar Alarm for WakeUP from STANDBY Mode?

IFant.1
Associate II

Greetings, i have been trying to set up a STM32WLE5CC MCU to wake up from STANDBY Mode after a period of time (30 seconds for the testing phase, 1 week in the final product) using HAL Library functions.

Unfortunately i have not been able to accomplish this, despite my best efforts.

I am using STM32CubeIDE.

Follows the code, partly abridged of comments and autogenerated MX functions:

//Includes
#include "main.h"
#include "string.h"
 
//Private var
RTC_HandleTypeDef hrtc;
UART_HandleTypeDef huart2;
 
//MX generated function prototypes
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART2_UART_Init(void);
static void MX_RTC_Init(void);
 
//Own function prototype
void Set_Alarm(void);
 
int main(void)
{
 
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART2_UART_Init();
 
  MX_RTC_Init();
  /*Check if we woke up from STANDBY mode*/
 
  if(__HAL_PWR_GET_FLAG(PWR_FLAG_SB)!=RESET){
  	  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB); //clear the flag
  	  char *str="Woke up from STANDBY Mode\r\n";
  	  HAL_UART_Transmit(&huart2, (uint8_t*)str, strlen(str), HAL_MAX_DELAY);
 
  	  /*Disable WAKEUP PIN */
  	  HAL_PWR_DisableWakeUpPin(PWR_WAKEUP_PIN1);
 
  	  /*Disable RTC Wakeup*/
           if(HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A)!=HAL_OK){}
  }
 
 
 
  /*enter STANDBY mode*/
  /* Clear the WU FLAG */
  __HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
  /*Clear RTC Wakeup flag*/
  __HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(&hrtc, RTC_FLAG_WUTF);
  HAL_Delay(1000);
 
  char *str = "About to enter the STANDBY MODE\r\n";
  HAL_UART_Transmit(&huart2, (uint8_t *)str, strlen (str), HAL_MAX_DELAY);
  
  /* Enable the WAKEUP PIN */
  HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
  Set_Alarm();
  char *str2 = "STANDBY MODE is ON\r\n";
  HAL_UART_Transmit(&huart2, (uint8_t *)str2, strlen (str2), HAL_MAX_DELAY);
  
/*Now entering STANDBY mode*/
  HAL_PWR_EnterSTANDBYMode();
 
 
  while (1)
  {
 
  }
 
}
 
 
static void MX_RTC_Init(void)
{
 
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
 
  /** Initialize RTC Only
  */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
  hrtc.Init.AsynchPrediv = 127;
  hrtc.Init.SynchPrediv = 249;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
  hrtc.Init.BinMode = RTC_BINARY_NONE;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
 
  sTime.Hours = 0x0;
  sTime.Minutes = 0x0;
  sTime.Seconds = 0x0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 0x1;
  sDate.Year = 0x0;
 
  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK)
  {
    Error_Handler();
  }
}
 
void Set_Alarm(void){
	/** Enable the Alarm A
	 */
	RTC_AlarmTypeDef sAlarm = {0};
 
	sAlarm.AlarmTime.Hours = 0x0;
	  sAlarm.AlarmTime.Minutes = 0x0;
	  sAlarm.AlarmTime.Seconds = 0x30;
	  sAlarm.AlarmTime.SubSeconds = 0x0;
	  sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	  sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
	  sAlarm.AlarmMask = RTC_ALARMMASK_NONE;
	  sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
	  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
	  sAlarm.AlarmDateWeekDay = 0x1;
	  sAlarm.Alarm = RTC_ALARM_A;
	  if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
	  {
	    Error_Handler();
	  }
}

The idea of the above code is to put the CPU in STANDBY Mode and wake it up 30 seconds later (the wakeup time will be later set up to one week so the normal RTC internal WakeUp cannot be used as it has a maximum time of 36 hours)

What am i doing incorrectly here?

Thank you in advance.

2 REPLIES 2
Chloe Meunier
ST Employee

Hello,

could you please share your SystemClock_Config() function?

Thank you

IFant.1
Associate II

Unfortunately i may have accidentally deleted the project, however i'm 99% sure of it being the same autogenerated one from STMCubeMx.

Using LSI for RTC and HSI+PLLCLK for SYSCLK

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the CPU, AHB and APB busses clocks
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  RCC_OscInitStruct.LSIDiv = RCC_LSI_DIV1;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 24;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the SYSCLKSource, HCLK, PCLK1 and PCLK2 clocks dividers
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK3|RCC_CLOCKTYPE_HCLK
                              |RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1
                              |RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.AHBCLK3Divider = RCC_SYSCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}