cancel
Showing results for 
Search instead for 
Did you mean: 

I found a bug in HAL_RCC_OscConfig for stm32f2xx (file stm32f2xx_hal_rcc.c).

SStei.3
Associate

When this function is called with the OSC configured, e.g. from bootloader, it checks if the PLLM/N/P/Q in RCC PLLCFGR reg are the same as requested. That check fails, even if the parameters in the second config request are the same.

Problem is located in following part of the code:

      else
      {
        /* Do not return HAL_ERROR if request repeats the current configuration */
        uint32_t pllcfgr = RCC->PLLCFGR;
      
        if((READ_BIT(pllcfgr, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
           (READ_BIT(pllcfgr, RCC_PLLCFGR_PLLM) != RCC_OscInitStruct->PLL.PLLM) ||
           ((READ_BIT(pllcfgr, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos) != RCC_OscInitStruct->PLL.PLLN) ||
           (READ_BIT(pllcfgr, RCC_PLLCFGR_PLLP) != RCC_OscInitStruct->PLL.PLLP) ||
           (READ_BIT(pllcfgr, RCC_PLLCFGR_PLLQ) != RCC_OscInitStruct->PLL.PLLQ))
        {
          return HAL_ERROR;
        }
     }

PLLP and PLLQ needs shifting before checking, PLLP needs mapping, too.

The following code worked for me:

      else
      {
        /* Do not return HAL_ERROR if request repeats the current configuration */
        uint32_t pllcfgr = RCC->PLLCFGR;
      
        if((READ_BIT(pllcfgr, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
           (READ_BIT(pllcfgr, RCC_PLLCFGR_PLLM) != RCC_OscInitStruct->PLL.PLLM) ||
           ((READ_BIT(pllcfgr, RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos) != RCC_OscInitStruct->PLL.PLLN) ||
           ((READ_BIT(pllcfgr, RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) != (RCC_OscInitStruct->PLL.PLLP >> 1) - 1) ||
           ((READ_BIT(pllcfgr, RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos) != RCC_OscInitStruct->PLL.PLLQ))
        {
          return HAL_ERROR;
        }
      }

Thought it would be worth reporting, as others might run into the same issue.

Regards,

1 REPLY 1
Amel NASRI
ST Employee

Hi @SStei.3​ ,

Thanks for bringing this issue to our attention.

Besides to the workaround you found, you can also apply the following update (aligned with STM32F4 implementation):

if((READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
            (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) ||
            (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) ||
            (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) ||
            (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)))

The issue you highlighted is reported internally.

Internal ticket number: 121423 (PS: This is an internal tracking number and is not accessible or usable by customers).

-Amel

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.