2026-01-30 2:12 AM - last edited on 2026-01-30 2:15 AM by Gyessine
Post Edited by ST moderator to apply source code formatting
Hi ST Community,
I am using STm32U575VGTX. I configure RTC as default, enable RTC non-secure interrupt, activate alarm A trigger each 10 seconds as below:
*******************************************
static void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 0 */
RTC_PrivilegeStateTypeDef privilegeState = {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;
hrtc.Init.OutPutPullUp = RTC_OUTPUT_PULLUP_NONE;
hrtc.Init.BinMode = RTC_BINARY_NONE;
if (HAL_RTC_Init(&hrtc) != HAL_OK)
{
Error_Handler();
}
privilegeState.rtcPrivilegeFull = RTC_PRIVILEGE_FULL_NO;
privilegeState.backupRegisterPrivZone = RTC_PRIVILEGE_BKUP_ZONE_NONE;
privilegeState.backupRegisterStartZone2 = RTC_BKP_DR0;
privilegeState.backupRegisterStartZone3 = RTC_BKP_DR0;
if (HAL_RTCEx_PrivilegeModeSet(&hrtc, &privilegeState) != 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 = 0x0;
sAlarm.AlarmTime.SubSeconds = 0x0;
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 */
__HAL_RTC_ALARM_ENABLE_IT(&hrtc, RTC_IT_ALRA);
/* USER CODE END RTC_Init 2 */
}
********************************
I add IWDG period 20 seconds and refresh in alarm call back function:
********************************
void SetRTCAlarm(void)
{
RTC_AlarmTypeDef sAlarm = {0};
RTC_TimeTypeDef sTime = {0};
RTC_DateTypeDef sDate = {0};
__HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF);
/* Get current time */
HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
/* Set alarm for every 10 seconds */
sAlarm.AlarmTime.Hours = sTime.Hours;
sAlarm.AlarmTime.Minutes = sTime.Minutes;
sAlarm.AlarmTime.Seconds = (sTime.Seconds + 10) % 60;
/* Handle minute rollover (not hour directly) */
if (sAlarm.AlarmTime.Seconds < sTime.Seconds) { // wrap happened
sAlarm.AlarmTime.Minutes = (sTime.Minutes + 1) % 60;
if (sAlarm.AlarmTime.Minutes == 0) { // minute wrapped → hour
sAlarm.AlarmTime.Hours = (sTime.Hours + 1) % 24;
} else {
sAlarm.AlarmTime.Hours = sTime.Hours;
}
} else {
sAlarm.AlarmTime.Minutes = sTime.Minutes;
sAlarm.AlarmTime.Hours = sTime.Hours;
}
/* Configure alarm settings */
sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
sAlarm.AlarmDateWeekDay = 1;
sAlarm.Alarm = RTC_ALARM_A;
/* Set and enable the alarm */
HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A);
HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
}
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
HAL_IWDG_Refresh(&hiwdg);
/* Set next alarm */
SetRTCAlarm();
}
********************************
I init peripherals:
********************************
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_GPDMA1_Init();
MX_ADC1_Init();
MX_LPTIM1_Init();
MX_RTC_Init();
MX_IWDG_Init();
********************************
Errata said I must disable WUTF because I use GDMA1. STM32U575xx and STM32U585xx device errata - Errata sheet
********************************
void RTC_IRQHandler(void)
{
/* USER CODE BEGIN RTC_IRQn 0 */
SET_BIT(RTC->CR, RTC_CR_WUTE);
SET_BIT(RTC->SCR, RTC_SCR_CWUTF); // See https://www.st.com/resource/en/errata_sheet/es0499-stm32u575xx-and-stm32u585xx-device-errata-stmicroelectronics.pdf (Section 2.2.4)
/* USER CODE END RTC_IRQn 0 */
HAL_RTC_AlarmIRQHandler(&hrtc);
/* USER CODE BEGIN RTC_IRQn 1 */
/* USER CODE END RTC_IRQn 1 */
}
********************************
Until now, everything is good. Alarm trigger and watchdog is refreshed. Then I want MCU goes to stop mode 2 and will be waken up by Alarm A
********************************
static void BMS_EnterStopMode(void)
{
HAL_SuspendTick();
__HAL_RCC_PWR_CLK_ENABLE();
HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI);
SystemClock_Config();
HAL_ResumeTick();
// Led on to check wake up
}
********************************
Surprisingly, after entering stop mode 2, no wake up happen. WD reset MCU and then hard fault occur due to I access WD (in alarm irq) without init WD first.
Am I wrong somewhere? Sorry I cannot attach project here. Thank you all.