cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 Does not wake up from STOP Mode with the RTC alarm

KKili.1
Associate II

Hi all,

I am using STM32L431 and the device is not waking up from STOP mode with an RTC alarm interrupt. Can somebody pinpoint where my issues are?

My configurations in the code configurator:

0693W00000AOx6zQAD.jpg0693W00000AOx7JQAT.jpg0693W00000AOx7nQAD.jpgI am enabling the crystal oscillator, enabling the calendar, alarm, and the interrupt through EXTI18, the only parameter I change is the time of the alarm set to 5 seconds.

This is what the code of the configurator looks like:

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
  /** Configure LSE Drive Capability
  */
  HAL_PWR_EnableBkUpAccess();
  __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_LSE
                              |RCC_OSCILLATORTYPE_MSI;
  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  RCC_OscInitStruct.MSICalibrationValue = 0;
  RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_I2C1;
  PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the main internal regulator output voltage
  */
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Enable MSI Auto calibration
  */
  HAL_RCCEx_EnableMSIPLLMode();
}
 
 
/**
  * @brief RTC Initialization Function
  * @param None
  * @retval None
  */
static void MX_RTC_Init(void)
{
 
  /* USER CODE BEGIN RTC_Init 0 */
 
  /* USER CODE END RTC_Init 0 */
 
  RTC_TimeTypeDef sTime = {0};
  RTC_DateTypeDef sDate = {0};
  RTC_AlarmTypeDef sAlarm = {0};
 
  /* USER CODE BEGIN RTC_Init 1 */
 
  /* USER CODE END RTC_Init 1 */
  /** Initialize RTC Only
  */
  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.OutPutRemap = RTC_OUTPUT_REMAP_NONE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  if (HAL_RTC_Init(&hrtc) != HAL_OK)
  {
    Error_Handler();
  }
 
  /* USER CODE BEGIN Check_RTC_BKUP */
 
  /* USER CODE END Check_RTC_BKUP */
 
  /** Initialize RTC and set the Time and Date
  */
  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();
  }
  /** Enable the Alarm A
  */
  sAlarm.AlarmTime.Hours = 0x0;
  sAlarm.AlarmTime.Minutes = 0x0;
  sAlarm.AlarmTime.Seconds = 0x5;
  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();
  }
  /* USER CODE BEGIN RTC_Init 2 */
 
  /* USER CODE END RTC_Init 2 */
 
}

And this is where I enter the stop mode:

		case sleep:
			robot_stop_movement();
 
			nTime.Seconds = 0;
			HAL_RTC_SetTime(&hrtc,&nTime,RTC_FORMAT_BCD);
 
			HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);
			steps++;
 
			current_state = go_to_start;
			break;

I set the time to 0 seconds before I go into stop mode, then I expect to wake up after 5 seconds, however, the device never wakes up. It does wake up from a pin interrupt though so I'm not entirely sure if I am doing something wrong here.

Can anybody pinpoint what the mistake is that I am making?

9 REPLIES 9
Ons KOOLI
Senior III

Hi @Kerim Kiliç​ ,

Please refer to the STM32CubeL4. You can find useful examples under Projects/$Board_Name$/Examples/PWR directory.

For example PWR_STOP1_RTC and PWR_STOP2_RTC projects.

Hope this is helpful.

Best Regards,

Ons.

Note: If the problem is resolved, please mark this topic as answered by checking Select as best. This will help other users find that answer faster.

KKili.1
Associate II

Hi @Ons KOOLI​ ,

I cannot find any example for the part number STM32L431 in folder. Would it work to select NUCLEO-L432KC instead?

Hi @Kerim Kiliç​ ,

Yes. This should work, since they have the same reference manual. I don't think that you should make any modifications.

For more details, please refer to RM0394, STM32L432KB STM32L432KC, and STM32L431xx.

Best Regards,

Ons.

Note: If the problem is resolved, please mark this topic as answered by checking Select as best. This will help other users find that answer faster.

it1
Associate

Hi @Kerim Kiliç​,

I am also facing similar issue, if you have got the solution then please share the solution. This will help others too.

Thanks

Tanuj 

Hi, I haven't got the solution yet. I will post any solution in this thread to keep others up to date.

AFahr.1
Associate III

Hi all,

I faced a similar problem...

  • The device needs to go to sleep at 6 PM using HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFE), and wake up at 6 AM again next day. I have RTC running through sleep mode and set the alarm and triggers like shown below, at startup of the device.
if(EXTI->PR1 & EXTI_PR1_PIF18)
{
	EXTI->PR1 |= EXTI_PR1_PIF18;	///< Clear pending interrupt if necessary
}
EXTI->EMR1 |= EXTI_EMR1_EM18; ///< RTC Alarm Mask
EXTI->RTSR1 |= EXTI_RTSR1_RT18; ///< Rising trigger
 
 
/* Set the alarm values with the config values */
 
HAL_PWREx_EnableInternalWakeUpLine();
__HAL_RTC_ALARMA_ENABLE(&hrtc);
__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF);
 
alarm_Time.Hours = storage_config.wup_time.Hours;
alarm_Time.Minutes = storage_config.wup_time.Minutes;
alarm_Time.Seconds = storage_config.wup_time.Seconds;
alarm_Time.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
 
alrm_a.Alarm = RTC_ALARM_A;
alrm_a.AlarmMask = RTC_ALRMAR_MSK4;
alrm_a.AlarmDateWeekDay = RTC_WEEKDAY_MONDAY;
alrm_a.AlarmTime = alarm_Time;
alrm_a.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
 
HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 7, 0);			///< Set the interrupt priority and enable
HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn);
 
HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);
if (HAL_RTC_SetAlarm_IT(&hrtc, &alrm_a, RTC_FORMAT_BIN) != HAL_OK)
{
  log_msg(LOG_ERR, "dg_system.c: Error setting alarm Line: %u", __LINE__);
}
 
log_msg(LOG_INFO, "Setting alarm: %02d:%02d:%02d", alrm_a.AlarmTime.Hours, alrm_a.AlarmTime.Minutes, alrm_a.AlarmTime.Seconds);

The log_msg function us a printf wrapper. I don't know if this is the most elegant or efficient way... probably not, but it works. I'll see what code is unnecessary and remove it later on.

Cheers,

Alberto

Hi Alberto,

Thanks a lot for sending the code. Can you recommend me a configuration in the code? My MCU needs to sleep for about 5 minutes and then wake up and do things. How can I modify the code above to go to sleep for 5 minutes?

Kind regards,

AFahr.1
Associate III

Should be straightforward...

Read the time with HAL_RTC_GetTime (I believe that is the function) and add 5 minutes to your current minutes value. If it's > 60, add 1 to the hour value and the rest to the minute value. Set the alarm with the new values as above. The only thing you need to do is read time really.

You should read the time with HAL_RTC_GetTime twice and compare the value, if they are different, read them again. Sometimes the RTC registers do not return the current time because of the shadow registers or something related.

Cheers,

Alberto

Hi Alberto,

It is just a little bit confusing to me, should the device wake up only at 6 AM and go to sleep at 6 PM. So how would that translate to for instance sleeping just for 5 minutes, would that be going to sleep at 6:00 PM and waking up at 6:05 PM. Can you please enlighten me on this matter?

Kind regards,

Kerim