cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103x strange behavior using HAL_RTC_GetTime() together with RTC interrupts (ALR and SEC flags)

Cgelectronics
Associate II

Hello all,

I'm working on a project with the STM32F103C8T6 microcontroller, using STMCubeIDE STM32CubeIDE Version: 1.13.2, and the HAL STM32Cube FW 1.8.5. In the example program I've attached, I set an alarm for 00:00:00, and once the alarm interrupt triggers, I reprogram the alarm to go off again 20 seconds later.

I've obtained part of this example from the following website: https://medium.com/@jobenas_25464/power-management-and-rtc-alarms-in-stm32f103-d144a214cc40, and I've attempted some modifications, which I'll explain below.

In this project,attached below, I'm using the two interrupts provided by the RTC: the interrupt that occurs every second and the alarm interrupt (I also have the Timer 3 interrupt enabled for additional testing).

The interrupt priorities are set in the following order (from highest to lowest priority):

  1. SysTick interrupt.
  2. Alarm interrupt.
  3. Global RTC interrupt.
  4. Timer 3 interrupt.

I must clarify that the priority of the SysTick interrupt should be higher than any of the RTC interrupts since it is used as a time reference for calculating timeouts in various functions of the RTC module.

Cgelectronics_0-1697397953043.png

When I execute the HAL_RTC_GetTime() function inside the seconds callback, the alarm is triggered at the correct time, but it appears that during the interrupt handling process, one second is somehow lost. I'm trying to understand the reason behind this behavior, and it seems that the operations performed within the HAL_RTC_GetTime function might not be entirely appropriate when executed in this context.

Cgelectronics_2-1697399996302.png

void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc){
	if(hrtc->Instance == RTC){
		HAL_RTC_GetTime(hrtc, &now_Time, RTC_FORMAT_BIN);
		(void)snprintf (message_buffer, (size_t)sizeof(message_buffer), "Current Hour %d:%d:%d\r\n", now_Time.Hours, now_Time.Minutes, now_Time.Seconds);
		HAL_UART_Transmit(&huart1, (uint8_t *)message_buffer, strlen (message_buffer), HAL_MAX_DELAY);
		secondsUpdate++;
		seconds_flag = 1;
	}
}
/* loop on main */
  while (1)
  {
	  if(seconds_flag ==1){
//		  HAL_RTC_GetTime(&hrtc, &now_Time, RTC_FORMAT_BIN);
//		  (void)snprintf (message_buffer, (size_t)sizeof(message_buffer), "Current Hour %d:%d:%d\r\n", now_Time.Hours, now_Time.Minutes, now_Time.Seconds);
//		  HAL_UART_Transmit(&huart1, (uint8_t *)message_buffer, strlen (message_buffer), HAL_MAX_DELAY);
		  seconds_flag =0;
	  }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

Since I personally prefer not to run code within an interrupt, what I've done is set a flag to 1 when the second interrupt occurs, and in the while loop, I read the time and reset this flag to 0. In this case, the alarm interrupt doesn't trigger.

Cgelectronics_1-1697398280170.png

void HAL_RTCEx_RTCEventCallback(RTC_HandleTypeDef *hrtc){
	if(hrtc->Instance == RTC){
//		HAL_RTC_GetTime(hrtc, &now_Time, RTC_FORMAT_BIN);
//		(void)snprintf (message_buffer, (size_t)sizeof(message_buffer), "Current Hour %d:%d:%d\r\n", now_Time.Hours, now_Time.Minutes, now_Time.Seconds);
//		HAL_UART_Transmit(&huart1, (uint8_t *)message_buffer, strlen (message_buffer), HAL_MAX_DELAY);
		secondsUpdate++;
		seconds_flag = 1;
	}
}
while (1)
  {
	  if(seconds_flag ==1){
		  HAL_RTC_GetTime(&hrtc, &now_Time, RTC_FORMAT_BIN);
		  (void)snprintf (message_buffer, (size_t)sizeof(message_buffer), "Current Hour %d:%d:%d\r\n", now_Time.Hours, now_Time.Minutes, now_Time.Seconds);
		  HAL_UART_Transmit(&huart1, (uint8_t *)message_buffer, strlen (message_buffer), HAL_MAX_DELAY);
		  seconds_flag =0;
	  }

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }

If I don't use the HAL_RTC_GetTime() function in either the callback or the while loop, the alarm seems it is triggered correctly, although I cannot determine if one second is being lost.

I would like to know if I'm doing something wrong, and if others are experiencing the same issue.

Does anyone have any idea of what might be happening? Could it be a bug in the HAL layer?

 

2 REPLIES 2
TDK
Guru

Looks like HAL_RTCEx_RTCEventCallback is getting called once per second, but you don't handle it in time so the time ticks over from "0:0:0" to "0:0:1". Notice that "Current Hour 0:0:0" is missing from the first output.

Perhaps log HAL_GetTick as well so you can see how quickly/slowly these second interrupts are getting handled when the alarm goes off. As you noted, you do have blocking calls in your interrupts.

 

If you feel a post has answered your question, please click "Accept as Solution".
Cgelectronics
Associate II

Thank you, @TDK , for your response. I'm investigating what might be happening. The HAL_RTC_GetTime function modifies the alarm registers, and I will check what might be happening right at the point where both interrupts and the alarm are triggered, and I will bring a solution. In parallel, I will also submit a ticket to ST for them to investigate the case, and if they see any error in the HAL related to this, they can address it in the future.