Skip to main content
Visitor II
August 18, 2020
Question

RTC Alarm interrupt skipped sometimes

  • August 18, 2020
  • 11 replies
  • 5603 views

Hi all!

uC: STM32L433VCT

CubeMX, CubeIDE, CubeProgrammer

I've configured my RTC to set an alarm every minute. When an alarm occurs, the next alarm gets set and so on.

About once to twice a day, the rtc alarm is skipped, so there's a continous error, because no future alarms are set.

My function to calculate the next alarm is correct (rtc_get_next_time()) and the alarm was set to the correct time, regarding to the rtc handle (RTC_HandleTypeDef hrtc;) Just the alarm interrupt doesn't get triggered.

It is not happening at the same time of the day, it's pretty random. It never happend from 23:xx to 0:xx.

Here's how I set the alarm:

void main_set_rtc_alarm(uint8_t hour, uint8_t minute, uint8_t second)
{
	RTC_AlarmTypeDef sAlarm = {0};
	sAlarm.AlarmTime.Hours = hour;
	sAlarm.AlarmTime.Minutes = minute;
	sAlarm.AlarmTime.Seconds = second;
	sAlarm.AlarmTime.SubSeconds = 0x0;
	sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
	sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
	sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
	sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
	sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
	sAlarm.AlarmDateWeekDay = 0x1;
	sAlarm.Alarm = RTC_ALARM_A;
 
	HAL_StatusTypeDef state = HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BIN);
 
	if (state != HAL_OK)
	{
		Error_Handler();
	}
}

When the alarm occurs:

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{
	timestamp_t next = rtc_get_next_time(rtc_get_current_time(),delay); // delay is 60s
 main_set_rtc_alarm(next.hour, next.minute, next.second);
}

I know this only works correct for delays up to 24h. That's just for testing purposes.

There are lots of different interrupts in this program. Maybe this causes the problem?

Thank you!

    This topic has been closed for replies.

    11 replies

    Super User
    August 18, 2020

    > There are lots of different interrupts in this program.

    Do they wake up the system too? If yes, then if it goes back to sleep, is there a check whether the RTC-alarm hasn't go off meantime?

    JW

    Visitor II
    August 19, 2020

    The system never goes into sleep mode. I don't need the alarm to wake up the system, I just misuse it as a timer.

    Super User
    August 19, 2020

    OK.

    Read out the RTC registers content in case when the alarm happens and compare them to case when it does not happen.

    If you use external interrupts or any interrupts going through EXTI, try disabling them to see if this makes any difference.

    JW

    Visitor II
    August 19, 2020

    I'll have to wait till it happens again :face_with_tears_of_joy: I'm going to share my results later.

    Yeah there are external interrupts enabled. I'll also try that.

    Thanks!

    Visitor II
    August 19, 2020

    When you process the alarm interrupt check to make sure you haven't passed the next alarm setting already. The latency involved in responding to and resetting the alarm might be causing a miss on the exact minute.

    As a check you can mask the minutes to fire at multiple minute settings. This will tell you if the problem is post dating the alarm setting.

    Jack Peacock

    Visitor II
    August 19, 2020

    I don't really understand what you mean. When the rtc interrupt occurs, I get the current time from the rtc and add one minute to that time. How can i pass the next alarm? Only way is if this process would take more than one minute.

    Maybe I misunderstood your message

    Visitor II
    August 20, 2020

    You read the RTC time. It happens to be 1 minute, 59 seconds and 999.99 msec. You set the alarm for 2 seconds. Between the time you read TOD and set alarm the TOD rolls over to 2 seconds. You just missed the interrupt.

    The fix is to verify minutes have not rolled over after setting alarm.

    Jack Peacock

    Visitor II
    August 19, 2020

    I've disabled the external interrupts and it still happened.

    It happend while two uart interfaces were receiving data.

    It's rare that these interfaces are receiving data at the same time, but it's possible. I would say that this can also happen 2-3 times a day.

    Visitor II
    August 19, 2020

    Now I've a timer, that is set to one minute and two seconds. The timer gets reset with every rtc alarm.

    If there's a timer interrupt, the alarm has been missed.

    This happened a few minutes ago. The rtc alarm was set to 13:27:12 in the RTC register. The timer interrupt happened at 13:27:14, so the RTC alarm was set up correctly, but I'm missing the interrupt.

    My Code:

    void application_alarm_missed(void)
    {
    	error_handle(APP_RTC_ALARM_MISSED,SOFT);
    	RTC_AlarmTypeDef AlarmA;
    	HAL_RTC_GetAlarm(&hrtc,&AlarmA,RTC_ALARM_A,RTC_FORMAT_BIN);
     timestamp_t now = rtc_get_current_time();
     //breakpoint here
    	application_set_next_alarm();
    }

    Super User
    August 19, 2020

    Read out and check/post the RTC registers content. There's a long way from your code to the registers.

    Also, do what Jack suggested above: mask the minutes. In that way, you should get an interrupt every minute. Observe what happens.

    Also, how do you know the alarm has or has not occured?

    JW

    Visitor II
    August 20, 2020

    Ok, I'll do that the next time it happens.

    Yeah, I'll try that.

    Another function is called in the RTC interrupt and this function is not called if no interrupt happens.

    That's what it looks like exactly:

    void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
    {
     application_save(); //save data to sd card
    	timestamp_t next = rtc_get_next_time(rtc_get_current_time(),delay); // delay is 60s
     main_set_rtc_alarm(next.hour, next.minute, next.second);
    }

    Visitor II
    August 20, 2020

    Everytime the rtc interrupt is missing, I saved Error 43 to the sd card.

    It happend more often then I thought.

    [19.08.2020 14:45:18] Errors: 43
    [19.08.2020 15:05:17] Errors: 43
    [19.08.2020 16:30:16] Errors: 43
    [19.08.2020 16:35:15] Errors: 43
    [19.08.2020 16:45:14] Errors: 43
    [19.08.2020 17:55:13] Errors: 43
    [19.08.2020 18:10:12] Errors: 43
    [19.08.2020 18:15:11] Errors: 43
    [19.08.2020 18:40:10] Errors: 43
    [19.08.2020 18:45:10] Errors: 43
    [19.08.2020 18:55:09] Errors: 43
    [19.08.2020 19:35:08] Errors: 43
    [19.08.2020 20:50:07] Errors: 43
    [19.08.2020 21:20:06] Errors: 43
    [19.08.2020 21:45:05] Errors: 43
    [19.08.2020 21:55:04] Errors: 43
    [19.08.2020 22:25:04] Errors: 43
    [19.08.2020 22:55:04] Errors: 43
    [19.08.2020 23:10:01] Errors: 43
    [20.08.2020 00:20:00] Errors: 43
    [20.08.2020 01:05:59] Errors: 43
    [20.08.2020 02:15:58] Errors: 43
    [20.08.2020 02:45:57] Errors: 43
    [20.08.2020 03:50:56] Errors: 43
    [20.08.2020 04:00:55] Errors: 43
    [20.08.2020 04:25:54] Errors: 43
    [20.08.2020 04:40:53] Errors: 43

    It's noticable that is has something to do with 5 minutes.

    Every 5 minutes a lpwa module gets enabled in my program. There's a lot of uart communication going on.

    Is it possible that the rtc alarm gets delayed because of the uart interrupts?

    They have the same priority.

    The probability that what Jack said would happen would be very high.

    Super User
    August 22, 2020

    The registers are essentially identical (next time you should present them in hexadecimal, decimal is mostly useless in microcontrolers settings). Namely. RTC_ISR.ALRAWF is set in both cases (while interrupt is enabled by RTC_CR.ALRAIE). So the problem is probably not there.

    RTC alarms are EXTI18, so you should look at the EXTI registers and finally at the NVIC registers to find out why you don't have an interrupt.

    Also, make sure you are indeed looking at the interrupt (e.g. by toggling a pin directly at the IRQ routine entry), and not just being tangled into some Cube/HAL nonsense tacked onto it.

    JW

    Visitor II
    August 24, 2020

    Ok, that's good to know. I forgot to set it to hex because I mostly use this view in dec, next time I'll set it to hex!

    I don't really know how to check the EXTI registers. I've implemented it like that now and waiting for the error to occur:

    uint32_t volatile nvic_test = NVIC_GetEnableIRQ(RTC_Alarm_IRQn);
    EXTI_HandleTypeDef hexti;
    HAL_EXTI_GetHandle(&hexti,EXTI_LINE_18);

    I'm also toggling a pin at the IRQ routine entry now.

    Thanks for your help!

    Visitor II
    August 24, 2020

    The interrupt was enabled in the nvic, so nvic_test was 1.

    hexti.Line = 0x12000012;

    hexti.PendingCallback = 0x20006270 <htim15>

    The pin was set, but void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) hasn't been called.

    That's how I toggle the pin:

    void RTC_Alarm_IRQHandler(void)
    {
     /* USER CODE BEGIN RTC_Alarm_IRQn 0 */
    	//RTC_DEBUG
     rtc_debug_pinstate = HAL_GPIO_ReadPin(RTC_DEBUG_GPIO_Port, RTC_DEBUG_Pin);
     rtc_debug_pinstate = !rtc_debug_pinstate;
     HAL_GPIO_WritePin(RTC_DEBUG_GPIO_Port, RTC_DEBUG_Pin, rtc_debug_pinstate);
     /* USER CODE END RTC_Alarm_IRQn 0 */
     HAL_RTC_AlarmIRQHandler(&hrtc);
     /* USER CODE BEGIN RTC_Alarm_IRQn 1 */
     
     /* USER CODE END RTC_Alarm_IRQn 1 */
    }

    rtc_debug_pinstate was GPIO_PIN_SET when HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) was skipped. The GPIO Pin is high, so the interrupt occured correctly, but it seems HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) hasn't been called this time.