AnsweredAssumed Answered

RTC_ALARM configure fail sometimes (STM32F042)

Question asked by jeremy_cis on Feb 1, 2016
Latest reply on Feb 1, 2016 by jeremy_cis
I'm trying to make a program that enter STOP_MODE and wake up by RTC_ALARM in 10 second intervals. I made a function that reconfigures the alarm for 10 seconds in the future. This function is called each time the microcontroller returns from STOP_MODE and serial puts the current time.
But sometimes the alarm setting seems to be failing and the alarm occurs in the second set before but the next minute. The days, hours and minutes of RTC_ALARM do not matter, because they are masked.

I tried to make the checks "while(HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A) != HAL_OK);" and "while(HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BIN) != HAL_OK);" but it still fails.

I appreciate any suggestions for my problem. Thanks in advance.

Below is the SERIAL LOG:

15:14:16.058 [RX] - Time: 00:00:13
 
15:14:26.296 [RX] - Time: 00:00:23
 
15:14:36.535 [RX] - Time: 00:00:33
 
15:14:46.774 [RX] - Time: 00:00:43
 
15:14:57.014 [RX] - Time: 00:00:53
 
15:15:07.253 [RX] - Time: 00:01:03
 
15:16:08.690 [RX] - Time: 00:02:03 -> HERE THE ALARM SETTING FAILED
 
15:16:18.929 [RX] - Time: 00:02:13
 
15:17:20.368 [RX] - Time: 00:03:13 -> HERE THE ALARM SETTING FAILED
 
15:17:30.608 [RX] - Time: 00:03:23
 
15:18:32.047 [RX] - Time: 00:04:23 -> HERE THE ALARM SETTING FAILED
 
15:18:42.286 [RX] - Time: 00:04:33
 
15:18:52.526 [RX] - Time: 00:04:43
 
15:19:02.765 [RX] - Time: 00:04:53
 
15:19:13.004 [RX] - Time: 00:05:03
 
15:19:23.244 [RX] - Time: 00:05:13
 
15:19:33.484 [RX] - Time: 00:05:23
 
15:19:43.724 [RX] - Time: 00:05:33
 
15:19:53.964 [RX] - Time: 00:05:43
 
15:20:04.204 [RX] - Time: 00:05:53
 
15:20:14.444 [RX] - Time: 00:06:03
 
15:20:24.684 [RX] - Time: 00:06:13
 
15:20:34.924 [RX] - Time: 00:06:23
 
15:20:45.164 [RX] - Time: 00:06:33
 
15:20:55.404 [RX] - Time: 00:06:43
 
15:21:05.643 [RX] - Time: 00:06:53
 
15:21:15.883 [RX] - Time: 00:07:03
 
15:22:17.322 [RX] - Time: 00:08:03 -> HERE THE ALARM SETTING FAILED
 
15:22:27.562 [RX] - Time: 00:08:13
 
15:23:29.002 [RX] - Time: 00:09:13 -> HERE THE ALARM SETTING FAILED
 
15:23:39.243 [RX] - Time: 00:09:23
 
15:24:40.683 [RX] - Time: 00:10:23 -> HERE THE ALARM SETTING FAILED
 
15:24:50.923 [RX] - Time: 00:10:33
 
15:25:01.162 [RX] - Time: 00:10:43

And below my code:

/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx_hal.h"
 
/* USER CODE BEGIN Includes */
 
#include <stdint.h>
#include "string.h"
#include <stdlib.h>
 
/* USER CODE END Includes */
 
/* Private variables ---------------------------------------------------------*/
RTC_HandleTypeDef hrtc;
 
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
 
/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_RTC_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USART2_UART_Init(void);
 
/* USER CODE BEGIN PFP */
/* Private function prototypes -----------------------------------------------*/
 
/* USER CODE END PFP */
 
/* USER CODE BEGIN 0 */
 
//This flag receives 1 in the RTC Alarm interruption
uint8_t flagRTC_IRQHandler = 0;
 
        //Configure the interval of time for RTC Alarm. 1-59 seconds
        void configAlarm(uint8_t rtcIrqInterval) {
             
        uint8_t alarmSeconds = 0;
         
        RTC_AlarmTypeDef sAlarm;
        RTC_TimeTypeDef sTime;
        RTC_DateTypeDef sDate;
         
        if ((HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK)
                    && (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) == HAL_OK)) {
             
            alarmSeconds = sTime.Seconds + rtcIrqInterval;
             
            //Verify and adjust the seconds
            if(alarmSeconds > 59) {
                alarmSeconds = alarmSeconds - 60;
        }
    }
 
    while(HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A) != HAL_OK);
         
    /**Reconfig the Alarm A*/
  sAlarm.AlarmTime.Hours = 0;
  sAlarm.AlarmTime.Minutes = 0;
  sAlarm.AlarmTime.Seconds = alarmSeconds;
  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; //Ignora dia, hora e minuto
  sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  sAlarm.AlarmDateWeekDay = 1; //Irrelevant value
  sAlarm.Alarm = RTC_ALARM_A;
     
  while(HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BIN) != HAL_OK);
    }
 
/* USER CODE END 0 */
 
int main(void)
{
 
  /* USER CODE BEGIN 1 */
     
    char str[25];
    RTC_TimeTypeDef sTime;
  RTC_DateTypeDef sDate;
 
  /* USER CODE END 1 */
 
  /* MCU Configuration----------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_RTC_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();
 
  /* USER CODE BEGIN 2 */
 
    HAL_GPIO_TogglePin(LED_STS_GPIO_Port, LED_STS_Pin);
    HAL_Delay(1000);
    HAL_GPIO_TogglePin(LED_STS_GPIO_Port, LED_STS_Pin);
    HAL_Delay(1000);
    HAL_GPIO_TogglePin(LED_STS_GPIO_Port, LED_STS_Pin);
    HAL_Delay(1000);
    HAL_GPIO_TogglePin(LED_STS_GPIO_Port, LED_STS_Pin);
    HAL_Delay(1000);
 
    configAlarm(10);
     
//  HAL_PWR_EnterSTANDBYMode(); //3mA -> 0.30mA
//  HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFE); //3mA -> 0.30mA
//  HAL_PWR_EnterSLEEPMode(0, PWR_SLEEPENTRY_WFI); //no difference as yet
 
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
    flagRTC_IRQHandler = 0;
  while (1)
  {
  /* USER CODE END WHILE */
 
  /* USER CODE BEGIN 3 */
         
            if (flagRTC_IRQHandler == 1) { //This flag receives 1 in the RTC Alarm interruption
                flagRTC_IRQHandler = 0;
                configAlarm(10); //Configure the alarm for 10 seconds from now
                HAL_GPIO_TogglePin(LED_STS_GPIO_Port, LED_STS_Pin); //Toggle state of board led
                 
                if ((HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN) == HAL_OK)
                    && (HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN) == HAL_OK)) {
 
                // Format time and date
                memset(str, '\0', sizeof(str));
                sprintf(str, "Time: %02d:%02d:%02d\r\n", sTime.Hours, sTime.Minutes, sTime.Seconds);
                HAL_UART_Transmit(&huart1, str, strlen(str), 100);
                    }
            HAL_PWR_EnterSTOPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFE); //~3mA -> ~0.30mA
            }
  }
  /* USER CODE END 3 */
}
 
/** System Clock Configuration
*/
void SystemClock_Config(void)
{
 
  RCC_OscInitTypeDef RCC_OscInitStruct;
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_PeriphCLKInitTypeDef PeriphClkInit;
 
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
 
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_RTC;
  PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1;
  PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);
 
  HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
 
  HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
 
  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}
 
/* RTC init function */
void MX_RTC_Init(void)
{
 
  RTC_TimeTypeDef sTime;
  RTC_DateTypeDef sDate;
  RTC_AlarmTypeDef sAlarm;
 
    /**Initialize RTC and set the Time and Date
    */
  hrtc.Instance = RTC;
  hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
//  hrtc.Init.AsynchPrediv = 125;
//  hrtc.Init.SynchPrediv = 3000;
    hrtc.Init.AsynchPrediv = 100;
  hrtc.Init.SynchPrediv = 400;
  hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
  hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
  hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
  HAL_RTC_Init(&hrtc);
 
  sTime.Hours = 0;
  sTime.Minutes = 0;
  sTime.Seconds = 0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BIN);
 
  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 1;
  sDate.Year = 0;
 
  HAL_RTC_SetDate(&hrtc, &sDate, FORMAT_BIN);
 
    /**Enable the Alarm A
    */
  sAlarm.AlarmTime.Hours = 0;
  sAlarm.AlarmTime.Minutes = 0;
  sAlarm.AlarmTime.Seconds = 10;
  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; //Ignore day, hour and minuts
  sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL;
  sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE;
  sAlarm.AlarmDateWeekDay = 1;
  sAlarm.Alarm = RTC_ALARM_A;
  HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BIN);
 
}
 
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
 
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED ;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  HAL_UART_Init(&huart1);
 
}
 
/* USART2 init function */
void MX_USART2_UART_Init(void)
{
 
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED ;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  HAL_UART_Init(&huart2);
 
}
 
/** Configure pins as
        * Analog
        * Input
        * Output
        * EVENT_OUT
        * EXTI
*/
void MX_GPIO_Init(void)
{
 
  GPIO_InitTypeDef GPIO_InitStruct;
 
  /* GPIO Ports Clock Enable */
  __GPIOF_CLK_ENABLE();
  __GPIOA_CLK_ENABLE();
 
  /*Configure GPIO pin : LED_STS_Pin */
  GPIO_InitStruct.Pin = LED_STS_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
  HAL_GPIO_Init(LED_STS_GPIO_Port, &GPIO_InitStruct);
 
}

Outcomes