Skip to main content
clark
Associate
April 1, 2017
Solved

Bug Report: HAL_RCC_GetSysClockFreq() does not support PLLMUL value 6.5

  • April 1, 2017
  • 3 replies
  • 1033 views
Posted on April 01, 2017 at 08:00

This code snippet is generated by STMCubeMx 4.6.0 and STM32Cube FW_F1 V1.4.0 for STM32F107

964 uint32_t HAL_RCC_GetSysClockFreq(void)

965 {

966 #if defined(RCC_CFGR2_PREDIV1SRC)

967 const uint8_t aPLLMULFactorTable[12] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0, 13};

968 const uint8_t aPredivFactorTable[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16};

969 #else

970 const uint8_t aPLLMULFactorTable[16] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16};

971 #if defined(RCC_CFGR2_PREDIV1)

972 const uint8_t aPredivFactorTable[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16};

973 #else

974 const uint8_t aPredivFactorTable[2] = { 1, 2};

975 #endif /*RCC_CFGR2_PREDIV1*/

In my setup, I have SYSCLK from PLLCLK which is generated from HSI. When PLLMUL is set to 6.5, 

HAL_RCC_GetSysClockFreq() will try to access the 13th (0x1101) element which is outside the array. Plus where is 13 from?

I am working around this problem by setting PLLMUL to 9 in STMCubeMx.

    This topic has been closed for replies.
    Best answer by Imen.D
    Posted on April 03, 2017 at 12:57

    Hi

    Li.Hongliang

    ,

    I confirmed theHAL issueon the aPLLMULFactorTable, inside

    STM32CubeF1 V1.4.0

    (stm32f1xx_hal_rcc.c and stm32f1xx_hal_rcc_ex.c)which should be :

    const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0,

    0, 0,

    13};

    This issue is already reported internally and will be fixed in the coming version.

    Imen

    3 replies

    Technical Moderator
    April 2, 2017
    Posted on April 02, 2017 at 18:21

    Hi

    Li.Hongliang

    ,

    You should use the CubeMx version 4.20 as contains enhancements and bug fixes.

    I will check your reported issue and come back to you.

    Imen

    In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
    Imen.DBest answer
    Technical Moderator
    April 3, 2017
    Posted on April 03, 2017 at 12:57

    Hi

    Li.Hongliang

    ,

    I confirmed theHAL issueon the aPLLMULFactorTable, inside

    STM32CubeF1 V1.4.0

    (stm32f1xx_hal_rcc.c and stm32f1xx_hal_rcc_ex.c)which should be :

    const uint8_t aPLLMULFactorTable[14] = {0, 0, 4, 5, 6, 7, 8, 9, 0, 0, 0,

    0, 0,

    13};

    This issue is already reported internally and will be fixed in the coming version.

    Imen

    In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
    clark
    clarkAuthor
    Associate
    April 3, 2017
    Posted on April 03, 2017 at 16:30

    Thanks Imen. Nice work!

    mycall
    Associate
    December 16, 2018

    I can confirm that the problem still exists in STM32F1 version 1.7.0 In particular, at line 1128 in HAL_RCC_GetSysClockFreq there is an if statement

    if ((tmpreg & RCC_CFGR_PLLSRC) != RCC_PLLSOURCE_HSI_DIV2)

    If this evaluates to false - that is if PLL2Mul is not the input to the PLL and the else path is taken - we bypass this code which successfully deals with a PLL mult of 6.5

           /* If PLLMUL was set to 13 means that it was to cover the case PLLMUL 6.5 (avoid using float) */

           /* In this case need to divide pllclk by 2 */

           if (pllmul == aPLLMULFactorTable[(uint32_t)(RCC_CFGR_PLLMULL6_5) >> RCC_CFGR_PLLMULL_Pos])

           {

               pllclk = pllclk / 2; // MY COMMENT: <-------------- This fixes the 6.5 PLL option

           }

    Instead all we execute is

         else

         {

           /* HSI used as PLL clock source : PLLCLK = HSI/2 * PLLMUL */

           pllclk = (uint32_t)((HSI_VALUE >> 1) * pllmul); // MY COMMENT: We divide by 2 here to take into account Prediv1

         }

         sysclockfreq = pllclk; // MY COMMENT: <------------- no fix for the pll 6.5 option

         break;

       }

    leaving the clock frequency off by a factor of 2 if pllmul = 0x0D