AnsweredAssumed Answered

PLL configuration with HSE bypass bit

Question asked by iorbitearth on Feb 13, 2014
Latest reply on Oct 12, 2014 by Clive One
I have the STM32F303 on a custom board with an external clock. For testing firmware development, I'm using the STM32F3 Discovery board, also with an external clock.

We need to run at 72MHz, so we use the PLL with the external clock (HSE).

/**
  * @brief  Setup the microcontroller system
  *         Initialize the Embedded Flash Interface, the PLL and update the
  *         SystemFrequency variable.
  * @param  None
  * @retval None
  */
void SystemInit(void)
{
  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif
 
  /* Reset the RCC clock configuration to the default reset state ------------*/
  /* Set HSION bit */
  RCC->CR |= (uint32_t)0x00000001;
 
  /* Reset CFGR register */
  RCC->CFGR &= 0xF87FC00C;
 
  /* Reset HSEON, CSSON and PLLON bits */
  RCC->CR &= (uint32_t)0xFEF6FFFF;
 
  /* Reset HSEBYP bit */
  RCC->CR &= (uint32_t)0xFFFBFFFF;
 
  /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE bits */
  RCC->CFGR &= (uint32_t)0xFF80FFFF;
 
  /* Reset PREDIV1[3:0] bits */
  RCC->CFGR2 &= (uint32_t)0xFFFFFFF0;
 
  /* Reset USARTSW[1:0], I2CSW and TIMs bits */
  RCC->CFGR3 &= (uint32_t)0xFF00FCCC;
   
  /* Disable all interrupts */
  RCC->CIR = 0x00000000;
 
  /* Configure the System clock source, PLL Multiplier and Divider factors,
     AHB/APBx prescalers and Flash settings ----------------------------------*/
 
 
  /* Set the system clock source
   */
  SetSysClock_PLL();
 
 
#ifdef VECT_TAB_SRAM
  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#else
  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif 
}
 
 
 
 
 
/**
 
  * @brief  Configures the System clock source, PLL Multiplier and Divider factors,
 
  *               AHB/APBx prescalers and Flash settings
 
  * @note   This function should be called only once the RCC clock configuration
 
  *         is reset to the default reset state (done in SystemInit() function).
 
  * @param  None
 
  * @retval None
 
  */
 
void SetSysClock_PLL(void)
 
{
 
  __IO uint32_t StartUpCounter = 0, HSEStatus = 0;
 
  SystemCoreClock = 72000000;
 
 
 
/******************************************************************************/
 
/*            PLL (clocked by HSE) used as System clock source                */
 
/******************************************************************************/
 
 
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------*/

 
  /* Enable HSE */
 
#ifdef CUSTOM_BOARD 
  RCC->CR |= ((uint32_t)RCC_CR_HSEON | (uint32_t) RCC_CR_HSEBYP);
#else
  RCC->CR |= ((uint32_t)RCC_CR_HSEON);  /* HSE bypass is not required on the stm32f3 discovery board */
#endif
 
 
 
  /* Wait till HSE is ready and if Time out is reached exit */
 
  do
 
  {
 
    HSEStatus = RCC->CR & RCC_CR_HSERDY;
 
    StartUpCounter++;
 
  } while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
 
 
 
  if ((RCC->CR & RCC_CR_HSERDY) != RESET)
 
  {
 
    HSEStatus = (uint32_t)0x01;
 
  }
 
  else
 
  {
 
    HSEStatus = (uint32_t)0x00;
 
  }
 
 
 
  if (HSEStatus == (uint32_t)0x01)
 
  {
 
    /* Enable Prefetch Buffer and set Flash Latency */
 
    FLASH->ACR =  (uint32_t)(FLASH_ACR_PRFTBE | FLASH_Latency_2);
 
 
 
     /* HCLK = SYSCLK / 1 */
 
     RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
 
 
 
     /* PCLK2 = HCLK / 2 */
 
     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV2;
 
 
 
     /* PCLK1 = HCLK / 2 */
 
     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
 
 
 
    /* PLL configuration */
 
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
 
    RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_PREDIV1 | RCC_CFGR_PLLMULL3);
 
 
 
    /* Enable PLL */
 
    RCC->CR |= RCC_CR_PLLON;
 
 
 
    /* Wait till PLL is ready */
 
    while(!(RCC->CR & RCC_CR_PLLRDY));
 
 
 
    /* Select PLL as system clock source */
 
    RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
 
    RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
 
 
 
    /* Wait till PLL is used as system clock source */
 
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)RCC_CFGR_SWS_PLL)
 
    {
 
    }
 
  }
 
  else
 
  { /* If HSE fails to start-up, the application will have wrong clock
 
         configuration. User can add here some code to deal with this error */
 
  }
 
}

In the SetSycClock_PLL function, we first enable the HSE using the RCC clock control register. The mystery is in this step: on the discovery board, we do NOT need to set the HSE bypass bit (
RCC_CR_HSEBYP). This seems to be necessary on the custom board, otherwise HSE fails to stabilize and the system falls back to the 8MHz HSI clock.

Is there any insight to this behavior based on the software configuration?

Outcomes