AnsweredAssumed Answered

bug: HAL_RCC_GetSysClockFreq() in STM32Cube_FW_F4_V1.5.0

Question asked by zhang.jianjun on Apr 23, 2015
Latest reply on Apr 23, 2015 by zhang.jianjun
Test data: HSE_VALUE = 24000000, pllm=196, plln=14, pllp=2,
result: sysclockfreq=167,999,930,but the correct one is 168,000,000
reason: in expression
pllvco = ((HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN)));
(HSE_VALUE / pllm) =1,714,285.71 round to 1,714,285

fix:
pllvco = ((uint64_t)HSE_VALUE * plln / pllm)

full code:

uint32_t HAL_RCC_GetSysClockFreq(void)
{
  uint32_t pllm = 0, plln=0, pllvco = 0, pllp = 0;
  uint32_t sysclockfreq = 0;

  /* Get SYSCLK source -------------------------------------------------------*/
  switch (RCC->CFGR & RCC_CFGR_SWS)
  {
    case RCC_CFGR_SWS_HSI:  /* HSI used as system clock source */
    {
      sysclockfreq = HSI_VALUE;
       break;
    }
    case RCC_CFGR_SWS_HSE:  /* HSE used as system clock  source */
    {
      sysclockfreq = HSE_VALUE;
      break;
    }
    case RCC_CFGR_SWS_PLL:  /* PLL used as system clock  source */
    {
      /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN
      SYSCLK = PLL_VCO / PLLP */
      pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
      plln = (RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN);
      pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> POSITION_VAL(RCC_PLLCFGR_PLLP)) + 1 ) *2;
      if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI)
      {
        /* HSE used as PLL clock source */
        pllvco = ((uint64_t)HSE_VALUE * plln / pllm);
      }
      else
      {
        /* HSI used as PLL clock source */
        pllvco = ((uint64_t)HSI_VALUE * plln / pllm);    
      }
      
      
      sysclockfreq = pllvco/pllp;
      break;
    }
    default:
    {
      sysclockfreq = HSI_VALUE;
      break;
    }
  }
  return sysclockfreq;
}

Outcomes