2025-07-25 6:28 AM - last edited on 2025-07-25 7:36 AM by Andrew Neil
I am trying to get the RTC alarm working whilst also using a periodic wake, I can get each working independently but not both together.
If I DON'T shutdown for RTC wakeup, the RTC alarm DOES work.
If I DO shutdown for RTC wakeup, the RTC alarm DOES NOT work.
To summarize:
Below is the function I call to shutdown the mcu for 5 seconds, before waking up again...
void shutdownRun (void){
/* The Following Wakeup sequence is highly recommended prior to each Standby mode entry
mainly when using more than one wakeup source this is to not miss any wakeup event.
- Disable all used wakeup sources,
- Clear all related wakeup flags,
- Re-enable all used wakeup sources,
- Enter the shutdown mode.
*/
// Save pressure before shutdwon
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, *(uint32_t*)&pressure_bak);
/* Disable all used wakeup sources*/
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
/* Clear all related wakeup flags */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
ampPowerDown();
/* Enter the shutdown mode */
HAL_PWREx_EnterSHUTDOWNMode();
}
Below is the RTC initialization (note I have commented where hours/minutes/seconds is set to zero, otherwise it would be reset each time the RTC wakes the mcu and would never trigger the alarm)...
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 = 0x1;
sAlarm.AlarmTime.Seconds = 0x0;
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 */
}
Below is my alarm interrupt, which is only triggered if I never call the 'shutdownRun' function ...
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) {
shutdownFull();
}
2025-07-25 6:56 AM
Don't shut down within the RTC interrupt. It will not pre-empt itself.
Instead, set a flag within the interrupt and shut down within the main thread itself.
2025-07-25 7:35 AM
I changed the interrupt and main as you suggested but its still not working.
Interrupt is now....
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) {
flgReqShudownFull = 1;
}
And main is now...
while (1) {
if (flgReqShudownFull){
shutdownFull();
}
}
Going into shutdown and using the RTC to wake after 5 seconds prevents the alarm interrupt from working, but I cant find the issue
If I dont go into shutdown and wake every 5 seconds, the alarm interrupt works.
2025-07-25 7:39 AM
Can you show the full code? Doesn't seem to be any issues with the code you've presented.
2025-07-25 7:54 AM
2025-07-27 1:25 PM - edited 2025-07-27 1:27 PM
Is the problem caused because sAlarm.AlarmTime.Seconds is reset when shutdown ?
For test purposes, I am using the following settings:
The MCU runs for 10 seconds, then shuts down for 5 seconds using the functions:
When the MCU wakes, sAlarm.AlarmTime.Seconds is zero, so I have to set it back to 0x30 (should it be 0x30 or decimal 30, I'm not sure because its BCD ?).
The diagram below explains what I think might be happening, it should fully shut down and not wake again when the alarm is reached (30 seconds). But maybe it doesn't because sAlarm.AlarmTime.Seconds is reset when shutdown. ?
The application is battery powered and once manually switched on, it is supposed to read a pressure sensor every few minutes then shutdown between each measurement.
After 12 hours of being switched on, it is supposed to permanently shutdown and not wake again until switched manually on again.
I am using shorter times for test purposed, the 5 second shutdown and wake for 10 seconds works.
But the permanent shutdown (set by sAlarm.AlarmTime) is not working.
I have either implemted this wrong or it is not possible ?
2025-07-27 2:16 PM
I suspect it's because, on startup, you're initializing RTC regardless of its current state. You should check to see if it's already initialized and, if so, don't touch it.
Implement code in the first user block within MX_RTC_Init that checks to see if it's initialized already.
2025-07-28 4:00 AM - edited 2025-07-28 5:09 AM
I only initialize the RTC once, because I check if the MCU was woken by the RTC as follows...
if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB)) {
// Woke from standby
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
}
else
{
MX_RTC_Init();
}
I set a breakpoint on the line MX_RTC_Init() and the breakpoint is only hit on the first startup. When the RTC wakes the MCU, the breakpoint is not hit.
The diagram below shows the behavior I expect...
The diagram below shows what is actually happening, with the following observations made...
The diagram below shows the alarm works if I don't shutdown with RTC wake...
Below is the main code...
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_DMA_Init();
MX_DAC1_Init();
MX_TIM6_Init();
MX_SPI2_Init();
MX_LPUART1_UART_Init();
MX_SPI1_Init();
MX_I2C1_Init();
MX_USART3_UART_Init();
MX_ADC1_Init();
MX_TIM7_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
if (__HAL_PWR_GET_FLAG(PWR_FLAG_SB)) {
// Woke from shutdown
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_SB);
}
else
{
MX_RTC_Init();
}
Enable_PC13_EXTI(); // enable power switch wake up
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS); // enable RTC wake up
while (1) {
HAL_Delay(10000);
shutdownRun();
if (flgReqShudownFull){
shutdownFull();
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
Below is the RTC init function (only called once)...
static void MX_RTC_Init(void)
{
/* USER CODE BEGIN RTC_Init 0 */
/* USER CODE END RTC_Init 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 = 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(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN RTC_Init 2 */
/* USER CODE END RTC_Init 2 */
}
Below is the shutdownRun function...
void shutdownRun (void){
/* Disable all used wakeup sources*/
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 5, RTC_WAKEUPCLOCK_CK_SPRE_16BITS);
/* Clear all related wakeup flags */
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_WU);
/* Enter the shutdown mode */
HAL_PWREx_EnterSHUTDOWNMode();
}
Below is the shutdownFull function...
void shutdownFull (void){
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc); // disable RTC wakeup
Enable_PC13_Wakeup();
HAL_PWREx_EnterSHUTDOWNMode();
}
Below is the RTC alarm interrupt, I set a breakpoint here but it never hits...
void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) {
flgReqShudownFull = 1;
}
2025-07-28 6:38 AM - edited 2025-07-28 6:42 AM
I am going around in circles with this issue, so I had to resort to ChatGPT.
If ChatGPT is correct, then it is not possible to implement the functionality I require and I need to use a different approach.
ChatGPT said...
Wake Source | EXTI Line | Wake from Shutdown | Wake from Standby | Notes |
RTC Wakeup Timer | EXTI Line 22 | Yes | Yes | 16-bit counter, limited max duration |
RTC Alarm A | EXTI Line 17 | Yes | Yes | One-shot alarm, precise |
The problem is you cannot use both at the same time for wakeup from Shutdown or Standby without reconfiguring the EXTI line.
When you set HAL_RTCEx_SetWakeUpTimer_IT, it configures EXTI line 22.
Then, if you later configure HAL_RTC_SetAlarm_IT, it sets EXTI line 17.
But the STM32 only supports one EXTI wakeup at a time in Shutdown.
So the last one you configure takes precedence, and the other is ignored.
The suggested fix is
Read current RTC time
Store the UNIX timestamp or RTC_TimeTypeDef + RTC_DateTypeDef in RTC_BKP_DRx0
RTC_TimeTypeDef time;
RTC_DateTypeDef date;
HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
uint32_t startSeconds = RTC_to_unix(&time, &date);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR1, (startSeconds >> 16) & 0xFFFF);
HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, startSeconds & 0xFFFF);
Read current time and compute elapsed seconds:
HAL_RTC_GetTime(&hrtc, &time, RTC_FORMAT_BIN);
HAL_RTC_GetDate(&hrtc, &date, RTC_FORMAT_BIN);
uint32_t currentSeconds = RTC_to_unix(&time, &date);
uint32_t startHigh = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1);
uint32_t startLow = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2);
uint32_t startSeconds = (startHigh << 16) | startLow;
if ((currentSeconds - startSeconds) >= (14UL * 60 * 60)) {
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
HAL_PWREx_EnterSHUTDOWNMode();
}
2025-07-29 9:26 AM - edited 2025-07-29 9:37 AM
Hey there! Can you send your HAL_RTC_MspInit ? Just want to check you have NVIC lines properly enabled. Just to calm you down, the setup you intend is perfectly doable irl, i have multiple projects where i used that rtc management.
Also beforehand for acquiring good practises i recommend you always clear flags before setting interrupts, example:
HAL_NVIC_DisableIRQ(RTC_WKUP_IRQn);
HAL_RTCEx_DeactivateWakeUpTimer(&hrtc);
__HAL_RTC_WAKEUPTIMER_CLEAR_FLAG(hrtc, RTC_FLAG_WUTF);
NVIC_ClearPendingIRQ(RTC_WKUP_IRQn);
HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
HAL_RTCEx_SetWakeUpTimer_IT(&hrtc, 599, RTC_WAKEUPCLOCK_CK_SPRE_16BITS, 0);
Although from your graphic i guess the first wakeup from wakuptimer is happening, isn't it? Make sure the wakup flag is getting cleared properly, usually generated automatically in stm32xx_it.c file. Can you sum up the current issue in 3 lines max clearly please?