cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_TIMEOUT while trying to combine several STM32L4R9 HAL examples into one project.

magene
Senior II

I'm building up an app on the STM32L4R9-Discovery board that needs a lot of IO: UARTs, USARTs, I2C, SPI,RTC, FatFS on the SD Card and others. I'm pretty new to the STMCubeIDE and C/C++ world so I've build up several test apps that start for the Discovery board based on examples from the HAL library. Now I'm trying to combine my SD card example with my RTC example. They work find separately but when I try to put them together I get a HAL_Timeout error in the RTC_EnterInitMode method in the STM32L4xx_hal_rtc.c file. This happens with the STMCubeIDE and in VisualGDB.

HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef *hrtc)
{
  uint32_t tickstart;
  HAL_StatusTypeDef status = HAL_OK;
 
  /* Check if the Initialization mode is set */
#if defined(STM32L412xx) || defined(STM32L422xx) || defined (STM32L4P5xx) || defined (STM32L4Q5xx)
  if ((hrtc->Instance->ICSR & RTC_ICSR_INITF) == 0U)
  {
    /* Set the Initialization mode */
    SET_BIT(hrtc->Instance->ICSR, RTC_ICSR_INIT);
 
    tickstart = HAL_GetTick();
    /* Wait till RTC is in INIT state and if Time out is reached exit */
    while ((READ_BIT(hrtc->Instance->ICSR, RTC_ICSR_INITF) == 0U) && (status != HAL_TIMEOUT))
    {
      if ((HAL_GetTick()  - tickstart) > RTC_TIMEOUT_VALUE)
      {
        status = HAL_TIMEOUT;
        hrtc->State = HAL_RTC_STATE_TIMEOUT;
      }
    }
  }
#else /* #if defined(STM32L412xx) || defined(STM32L422xx) || defined (STM32L4P5xx) || defined (STM32L4Q5xx) */
  if ((hrtc->Instance->ISR & RTC_ISR_INITF) == 0U)
  {
    /* Set the Initialization mode */
    hrtc->Instance->ISR = (uint32_t)RTC_INIT_MASK;
 
    tickstart = HAL_GetTick();
    /* Wait till RTC is in INIT state and if Time out is reached exit */
    while ((READ_BIT(hrtc->Instance->ISR, RTC_ISR_INITF) == 0U) && (status != HAL_TIMEOUT))
    {
      if ((HAL_GetTick()  - tickstart) > RTC_TIMEOUT_VALUE)
      {
        status = HAL_TIMEOUT;
        hrtc->State = HAL_RTC_STATE_TIMEOUT;
      }
    }
  }
#endif /* #if defined(STM32L412xx) || defined(STM32L422xx) || defined (STM32L4P5xx) || defined (STM32L4Q5xx) */
	status = HAL_OK;  //Temporary fix by Gene Massin 2020Apr25 
  return status;
}

As a test, I just put a status = HAL_OK before the return status at the end of this method and the rest of my little project runs fine. Obviously, this isn't the right way to fix the problem but I can figure out what the difference is between my individual projects and the combined project. Suggestions will be greatly appreciated. Thanks - Gene

BTW - I started the whole project by defining IO functionality (and pins) using the CubeMX functionality in CubeIDE with no obvious conflicts.

1 ACCEPTED SOLUTION

Accepted Solutions
TDK
Guru

Did you enable the RTC clock?

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

View solution in original post

6 REPLIES 6
TDK
Guru

Did you enable the RTC clock?

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

Well that was incredibly helpful on your part and incredibly dumb on my part. Many thanks.

But it does lead to another question. The CubeMX generated code enables the RTC Clock in the HAL_RTC_MspInit() method in the STM32l4xx_hal_msp.c file which is an override of the weak HAL_RTC_MspInit method in stm32l4xx_hal_rtc.c. HAL_RTC_MspInit is called by HAL_RTC_Init in stm32l4xx_hal_rtc.c which is called by HAL_RTC_Init() in MX_RTC_Init() which is in the main.cpp file. I had to move the stm32l4xx_hal_rtc.c file in my VisualGDB solution explorer in order for the override of HAL_RTC_MspInit to happen. Doesn't that seem like an awful lot of indirection for something as critical as enabling a peripheral clock?

Just one more step in my incredibly painful journey to minimal competence with embedded C/C++

Thanks again

TDK
Guru

> Well that was incredibly helpful on your part and incredibly dumb on my part. Many thanks.

No worries, we've all been there.

> Doesn't that seem like an awful lot of indirection for something as critical as enabling a peripheral clock?

Yes, CubeMX does a lot of overriding of weak functions. The IRQ handlers are also handled this way. I'm not sure of the best approach if I was to architect CubeMX. I don't particularly care for the ability to define "weak" variables/functions in C.

If you want to use HAL, you need to accept some of its ways. If you do that, I think you'll find it works pretty well. But it is a bit of a learning experience.

There are a lot of libraries out there with this massive amount of indirection. HAL is not the worst offender. Go try to find the definition for something in LwIP and you'll find it's hidden behind 6 levels of defines. Maddening. But that's the price you pay for using someone else's code. It is what it is.

Just my opinion.

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

It's nice to know someone else finds HAL a little overly complex and it isn't just my ignorance. Eventually I might see what it takes to simplify the default HAL organization into one or maybe 2 files per peripheral. Or better yet, a class per peripheral.

Cheers

It's kind of unfair to put those two in a same basket. lwIP has many defines and levels because it's a truly flexible and universal software for many very different platforms and use cases. And even with all that it works very well! HAL on the other hand is so broken, that you can't even do USART reception in a sane way with it. Hell, even the trivial pin toggling is broken! And if some parts architecturally could be seen as usable, the "ingenious" lock mechanism and bunches of other bugs brakes them all anyway.

Hi TDK,

Please let me know if you have any idea to resolve my RTC issue addressed at https://community.st.com/t5/stm32-mcus-products/stm32f4-rtc-issue-when-coincell-vbat-is-removed/m-p/605408/thread-id/226795

Thanks,

Dhanoosh B