cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 LL RTC and RCC are a total disaster

MKsen.1
Associate II

Hi all,

I would like to point out a total disaster if you are using the LL library for RCC and RTC for the F4 series family. Let me start with the system clock config, which falls under RCC. Why the hell is there a default wipe of backup domain registers? For some unclear reason this finds its way into a generated code:

  LL_PWR_EnableBkUpAccess();
  LL_RCC_ForceBackupDomainReset();
  LL_RCC_ReleaseBackupDomainReset();

Then we move on to the RTC LL part. In the calendar init function this snippet is generated.

  RTC_TimeStruct.Hours = 0;
  RTC_TimeStruct.Minutes = 0;
  RTC_TimeStruct.Seconds = 0;
  LL_RTC_TIME_Init(RTC, LL_RTC_FORMAT_BCD, &RTC_TimeStruct);
  RTC_DateStruct.WeekDay = LL_RTC_WEEKDAY_WEDNESDAY;
  RTC_DateStruct.Month = LL_RTC_MONTH_JULY;
  RTC_DateStruct.Year = 20;
  LL_RTC_DATE_Init(RTC, LL_RTC_FORMAT_BCD, &RTC_DateStruct);
    LL_RTC_BAK_SetRegister(RTC,LL_RTC_BKP_DR0,0x32F2);
  }

I don't know, but where I live it is also important which day it is, don't you think?

Moving on to time management and I quote:

/**
  * @brief  Get Year in BCD format
  * @note if shadow mode is disabled (BYPSHAD=0), need to check if RSF flag is set
  *       before reading this bit
  * @note helper macro __LL_RTC_CONVERT_BCD2BIN is available to convert Year from BCD to Binary format
  * @rmtoll DR           YT            LL_RTC_DATE_GetYear\n
  *         DR           YU            LL_RTC_DATE_GetYear
  * @param  RTCx RTC Instance
  * @retval Value between Min_Data=0x00 and Max_Data=0x99
  */
__STATIC_INLINE uint32_t LL_RTC_DATE_GetYear(RTC_TypeDef *RTCx)

It should return year as BCD format, but it does not. It returns it in a BIN format, like

  // Add date & time to log message
  safeprintf(pcStringToWrite, u16StringLen, addZone ? ZoneTimeFormat : UtcTimeFormat, \
      (uint16_t)(70 == LL_RTC_DATE_GetYear(RTC) ? 1970 : 2000 + LL_RTC_DATE_GetYear(RTC)), \
      __LL_RTC_CONVERT_BCD2BIN(LL_RTC_DATE_GetMonth(RTC)), \
      __LL_RTC_CONVERT_BCD2BIN(LL_RTC_DATE_GetDay(RTC)), \
      __LL_RTC_CONVERT_BCD2BIN(LL_RTC_TIME_GetHour(RTC)), \
      __LL_RTC_CONVERT_BCD2BIN(LL_RTC_TIME_GetMinute(RTC)), \
      __LL_RTC_CONVERT_BCD2BIN(LL_RTC_TIME_GetSecond(RTC)));

Setting date is also hilarious as the flag is BCD but non of the parameters are actually in BCD format. If you implement it right (according to docs) it simply does not work correctly.

int16_t i = sscanf(acDateTime, "%4hu-%2hu-%2huT%2hu:%2hu:%2hu+", &u16Year, &u16Month, &u16Day, &u16Hour, &u16Min, &u16Sec);
 
    // Set date
    LL_RTC_DateTypeDef RTC_DateStruct = {0, (uint8_t)u16Month, (uint8_t)u16Day, (uint8_t)((u16Year > 2000u) ? u16Year - 2000u : u16Year - 1900u)};
    LL_RTC_DATE_Init(RTC, LL_RTC_FORMAT_BCD, &RTC_DateStruct);

And a few more thinks that I can't remember right now. Does anyone even test this thing before releasing it to the public???

BR

0 REPLIES 0