1
\$\begingroup\$

I'm trying to generate an interrupt every 60 seconds using alarm A. I put a HAL_GPIO_Toggle instruction inside the interrupt HAL_RTC_AlarmAEventCallback to turn an LED on to see if it triggers but I get nothing. I'm not routing the alarm to the output pins. This board has lots of goodies. I'm using the base project that sets up all the stuff in the board. I disabled FREERTOS, SDMMC1 and FATFS.

I checked the registers for alarm enable (ALRAE bit in RTC_CR register) and interrupt enable (ALRAIE bit in RTC_CR register) and they're both set. I set the current time to 12:31:32 (HH:MM:SS) and the date to Tuesday June 27, 2023. I have alarm A "Alarm Mask Seconds" enable and the seconds set to 0. I'm thinking when the seconds match, an interrupt should happen? but the alarm flag never gets set (ALRAF in RTC_ISR register). I was thinking I need to disable the interrupt after it happens so that it doesn't trigger for a whole second but I'm not sure how that works ... I haven't gotten there yet.

Why doesn't the interrupt trigger?

Thanks

Here is the code for the RTC init:

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.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 = 0x12;
  sTime.Minutes = 0x31;
  sTime.Seconds = 0x32;
  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_TUESDAY;
  sDate.Month = RTC_MONTH_JUNE;
  sDate.Date = 0x27;
  sDate.Year = 0x23;
  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.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;  //RTC_DAYLIGHTSAVING_NONE=0
  sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET; //RTC_STOREOPERATION_RESET=0
  sAlarm.AlarmMask = RTC_ALARMMASK_SECONDS;                   //RTC_ALARMMASK_SECONDS=(0x1UL << (7U))
  sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;     //RTC_ALARMSUBSECONDMASK_ALL=0
  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;//RTC_ALARMDATEWEEKDAYSEL_DATE=0
  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 */

}
\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

I got it to work. The problem is that I got the mask settings backwards. The correct way of thinking is by enabling the mask the field is ignored. Here is the code for the alarm that triggers an interrupt for every minute. It actually triggers when the seconds roll over to 0. So only the seconds field is used. The seconds mask is disabled.

/** Enable the Alarm A
  */
  sAlarm.AlarmTime.Hours = 0x0;
  sAlarm.AlarmTime.Minutes = 0x0;
  sAlarm.AlarmTime.Seconds = 0x0;
  sAlarm.AlarmTime.SubSeconds = 0x0;
  sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
  sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS
                              |RTC_ALARMMASK_MINUTES;
  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();
  }

Alarm Settings

\$\endgroup\$
0
\$\begingroup\$

TLDR: You interpret alarm mask meaning inverted. Mask everything except seconds to make your code working.

Imagine that RTC timer work in a way that it every second (in fact it is subsecond) checks actual time agains time specified in alarm configuration. In your code you set alarm to:

2000-00-00 00:00:00

Mask specify parts of date and time which are not checked. For interpretation simple replace masked value by XX (don't care). In your configuration you enabled seconds mask which means that compared date and time is:

2000-00-00 00:00:XX

This means that for example at time 2000-00-00 00:00:34 it will trigger, but at 2000-00-15 00:00:00 it will not (because 15 != 00).

If you want to trigger alarm every minute you do not worry about year, month, date and hour. You worry only about second because you want to trigger alarm once per minute, not a 60 times. So the idea on configuring alarm is that you mask all fields you do not worry (year, month, date, hour and minute) and set second to second at which you want to trigger alarm (for example, 0 but possibly configurable to other second). In that case alarm mask looks as follows:

XXXX-XX-XX XX:XX:00

as an example alarm configured in this way will trigger at following 3 consecutive times:

2023-06-28 20:54:00
2023-06-28 20:55:00
2023-06-28 20:56:00

but it will not trigger when the second counter is set to non-zero value (for example at 2023-06-28 20:55:34).

You can configure RTC alarm in a even crazy configurations like masking all except hours and seconds. With setting hour match value to 20 and second to 00 you get alarm pattern

XXXX-XX-XX 20:XX:00

and alrm will trigger every minute between 20 and 21 hour. Then 23 hours you will get no trigger and next day at 20:00:00 it start generating interrupts every minute again until 21 hour.

RTC Alarm with obscure pattern

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.