stm32l4 RTC HAL not working

taquionbcn picture taquionbcn · Oct 31, 2017 · Viewed 7.4k times · Source

I'm having a strange behavior with the RTC on a stm32L476 with FreeRTOS.

It only reads the first time in RUN mode, RTC is working, because from run to run it saves the value of the internal register and is going up.

Also if I do DEBUG when I put breakpoint at stm32l4xx_hal_rtc.c at line 583:

tmpreg = (uint32_t)(hrtc->Instance->TR & RTC_TR_RESERVED_MASK);    
*breakpoint* sTime->Hours = (uint8_t)((tmpreg & (RTC_TR_HT | RTC_TR_HU)) >> 16);

I can see the tmpreg and TR register how they update, and then when I click jump to next breakpoint witch is the same I saw the display updated.

So why it's not working when normal RUN?

Init code (cube MX generated):

void MX_RTC_Init(void)
{
  RTC_TimeTypeDef sTime;
  RTC_DateTypeDef sDate;

    /**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(__FILE__, __LINE__);
  }

    /**Initialize RTC and set the Time and Date 
    */
  if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != 0x32F2){
  sTime.Hours = 0;
  sTime.Minutes = 0;
  sTime.Seconds = 0;
  sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
  sTime.StoreOperation = RTC_STOREOPERATION_RESET;
  if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BIN) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

  sDate.WeekDay = RTC_WEEKDAY_MONDAY;
  sDate.Month = RTC_MONTH_JANUARY;
  sDate.Date = 1;
  sDate.Year = 0;

  if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BIN) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }

    HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR0,0x32F2);
  }

}

void HAL_RTC_MspInit(RTC_HandleTypeDef* rtcHandle)
{

  if(rtcHandle->Instance==RTC)
  {
  /* USER CODE BEGIN RTC_MspInit 0 */

  /* USER CODE END RTC_MspInit 0 */
    /* RTC clock enable */
    __HAL_RCC_RTC_ENABLE();
  /* USER CODE BEGIN RTC_MspInit 1 */

  /* USER CODE END RTC_MspInit 1 */
  }
}

task where clock is readed and printed all this task and functions are at the same menu.c:

void MenuTask(void const *argument){
    for(;;){

        /*
         * Menus
         */
        DrawMenu();

        osDelay(100);
    }
}

void DrawMenu(){
    switch(menuTaskStatus){

/* Not important code */

    case MENU_INFO:
        menuInfoBar();

        break;

    }
}

I print on the LCD a bar with the clock in the middle

void menuInfoBar(){

    //Clock
    CheckClock();
    if(updateNeeded.Clock){
        DrawClock();
        updateNeeded.Clock = 0;
    }

}

Here is the problematic part, as you can see I have tried a wait for synchro but also didn't work. I have some doubts of how does this syncro and RTC reading works.

void CheckClock(){
    RTC_TimeTypeDef timeVar;
    //  HAL_GPIO_TogglePin(LEDR_GPIO_Port, LEDR_Pin);
//  if(HAL_RTC_WaitForSynchro(&hrtc) == HAL_OK){
        while(HAL_RTC_GetTime(&hrtc,&timeVar,RTC_FORMAT_BIN)!= HAL_OK);
        if(timeVar.Seconds != timeVarAnt.Seconds){
            timeVarAnt.Minutes = timeVar.Minutes;
            timeVarAnt.Hours = timeVar.Hours;
            timeVarAnt.Seconds = timeVar.Seconds;
            updateNeeded.Clock = 1;
        }
//  }
}

Here I only draw the clock on my display

void DrawClock(){
    DISP_locate(49,0);
    sprintf((char *)stringBuffer,"%02d:%02d:%02d",(int)timeVarAnt.Hours,(int)timeVarAnt.Minutes,(int)timeVarAnt.Seconds);
    DISP_puts((char *)stringBuffer);
}

It's possible I can't read the RTC fast as 100ms? some one could explain to me why is needed a syncronitzation? datasheet explains that if the clock is 7 time faster is ok, I'm using an 80Mhz APB1 clock

some tutorials and examples I've found the do the exact same I do, but they read on the main loop with osDelay() of many values. Is a problem using freeRTOS and reading from a task?

time has nothing to do I've tried with 5s delay and also don't works

Thanks

Answer

John Wick picture John Wick · May 7, 2018

A little late may be but I ran into the same problem and it turns out that the HAL_GetTime(..) function has a quirk. HAL_RTC_GetDate() must be called after it to unlock the values.

You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values * in the higher-order calendar shadow registers to ensure consistency between the time and date values. * Reading RTC current time locks the values in calendar shadow registers until current date is read.

This is written as a note in their documentation as well as in the source code of the RTC HAL driver.

Personally, I believe that ST's guys should've made a HAL_RTC_GetTimeAndDate() and spare us falling in this trap.