cancel
Showing results for 
Search instead for 
Did you mean: 

LL drivers PLL initialization

simo zz
Senior

Hi all,

I am experiencing some problem with PLL initialization using LL drivers.

The code I am using for HSE, PLL and SYS clock is the following:

void init_RCC_HSE(void)
{
	//LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOH);
 
	LL_RCC_HSE_Enable();
	while(! LL_RCC_HSE_IsReady())
		;
 
	LL_RCC_HSI_Disable();
 
	//LL_RCC_HSE_EnableCSS();
 
	LL_RCC_PLL_Disable();
	LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_5, 200, LL_RCC_PLLP_DIV_2);
	LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
	LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_4);
	LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
	LL_RCC_PLL_Enable();
 
	while(!LL_RCC_PLL_IsReady())
		;
 
	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
 
	SystemCoreClockUpdate();
}

But the firmware stops after a few ms.

What is the proper way to initialise it using LL drivers ?

Thanks.

s.

1 ACCEPTED SOLUTION

Accepted Solutions
Piranha
Chief II

You haven't told for what MCU this is.

You can't disable HSI, while You are running on it. Switch to PLL, wait for switch to happen and then disable HSI.

Also voltage scale and flash latency must be set accordingly before switching to higher clock rate.

View solution in original post

4 REPLIES 4
Piranha
Chief II

You haven't told for what MCU this is.

You can't disable HSI, while You are running on it. Switch to PLL, wait for switch to happen and then disable HSI.

Also voltage scale and flash latency must be set accordingly before switching to higher clock rate.

simo zz
Senior

Hello @Piranha​ ,

the MCU is the STM32F407VG.

Of course you are right that HSI must not be disabled before setting other clocks, this is also stated in its TRM.

I modified the function according to your hint.

void init_RCC_HSE(void)
{
	LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOH);
 
	LL_PWR_EnableOverDriveMode();
	LL_FLASH_SetLatency(LL_FLASH_LATENCY_5);
	LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
 
	LL_RCC_HSE_Enable();
	LL_RCC_HSE_EnableCSS();
	while(! LL_RCC_HSE_IsReady())
		;
 
	LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_5, 200, LL_RCC_PLLP_DIV_2);
	LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
	LL_RCC_PLL_Enable();
 
	while(!LL_RCC_PLL_IsReady())
		;
 
	LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
	while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
	{
	  ;
	}
 
	LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_4);
	LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
 
	LL_RCC_HSI_Disable();
	SystemCoreClockUpdate();
}

Thanks.

s.

Piranha
Chief II

When switching to higher frequency, all bus dividers (including APB1 and APB2) must be updated before switching like it was in the first code version.

Also consider enabling prefetch and instruction/data caches in FLASH_ACR to maximize performance.

simo zz
Senior

Thank you @Piranha​ for your suggestions.

Cheers.

s.