Skip to main content
CLeo.1
Senior II
March 8, 2023
Solved

Can't get max frequency out of STM32H7

  • March 8, 2023
  • 6 replies
  • 3373 views

Hi everyone,

I am having a hard time trying to get the max clock frequency out of the STM32H753ZIT6U.

This is the revision V model and is capable of hitting 480MHz unlike its Y revision.

This is my code to get to 480MHz:

LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
	LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
	LL_APB4_GRP1_EnableClock(LL_APB4_GRP1_PERIPH_SYSCFG);
	SYSCFG_PWRCR_REG |= (0x01 << 0);
	while(LL_PWR_IsActiveFlag_VOS() == 0);
 
	FLASH_ACR_REG &= ~(0x3F << 0);
	FLASH_ACR_REG |= (0x3F << 0);
 
	LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSI);
	LL_RCC_PLL1_SetM(4);
	LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16);
	LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
	LL_RCC_PLL1P_Enable();
	LL_RCC_PLL1_SetP(1);
	LL_RCC_PLL1_SetN(30);
	LL_RCC_PLL1_Enable();
	while(LL_RCC_PLL1_IsReady() == 0);
 
	LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
	LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
	LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
	LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
	LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_2);
	LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_2);
	LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);

After all this its hitting 240MHz proven via the oscillscope and polling a USART Rx that suppose to timeouts on 1 second, but It timesout actually on 2 seconds.

I have no idea whats wrong here as I double checked my numbers for the PLL as it should achieve 480MHz

Using HSI Clock = 64MHz thus,

64MHz / 4 (M) = 16MHz * 30 (N) = 480MHz / 1 (P)

Any ideas?

This topic has been closed for replies.
Best answer by CLeo.1

Thank you guys for the input, I found the issue, it was just my assumption that it executes its instructions within one clock cycle, I have now moved the software delay implementation into hardware and all seems fine.

6 replies

christop
ST Employee
March 8, 2023

For STM32H753, LL_RCC_PLL11_SetP() can only accept values between 2 and 128:

/**

 * @brief Set PLL1 P Coefficient

 * @note  This API shall be called only when PLL1 is disabled.

 * @rmtoll PLL1DIVR    P1     LL_RCC_PLL1_SetP

 * @param P parameter can be a value between 2 (or 1*) and 128 (ODD division factor not supported)

 *

 * (*) : For stm32h72xxx and stm32h73xxx family lines.

 */

__STATIC_INLINE void LL_RCC_PLL1_SetP(uint32_t P)

{

 MODIFY_REG(RCC->PLL1DIVR, RCC_PLL1DIVR_P1, (P - 1UL) << RCC_PLL1DIVR_P1_Pos);

}

To achieve 480MHz, you need to set PLL1 P = 2 and PLL1 N = 60:

  1. LL_RCC_PLL1_SetP(2);
  2. LL_RCC_PLL1_SetN(60);
CLeo.1
CLeo.1Author
Senior II
March 8, 2023

@christop​  Yup, tried that, no bueno still seeing the same results

LCE
Principal II
March 8, 2023

Don't you have to set voltage scaling to VOS0 to get fulll 480 MHz?

For RCC setup I would use CubeMX at least to check all settings.

CLeo.1
CLeo.1Author
Senior II
March 8, 2023

Yes sir I do, however throughout the reference manual its mentioned that to get to VOS0 its simply getting the Voltage Scale to 1 and enabling the ODEN bit with in SYSCFG, to my understanding.

LCE
Principal II
March 8, 2023

Ah, thanks! Another difference to the H735 that I am working on currently.

christop
ST Employee
March 8, 2023

@CLeo.1​ You can try with the below clock configuration generated with STM32CubeMX 6.8.0, it uses LL driver API from STM32CubeH7 v1.11.0. I have output the PLL1P clock/10 on MCO2 and I can see 48Mhz signal on MCO2 (PC9).

void SystemClock_Config(void)
{
 LL_FLASH_SetLatency(LL_FLASH_LATENCY_4);
 while(LL_FLASH_GetLatency()!= LL_FLASH_LATENCY_4)
 {
 }
 LL_PWR_ConfigSupply(LL_PWR_LDO_SUPPLY);
 LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE0);
 while (LL_PWR_IsActiveFlag_VOS() == 0)
 {
 }
 LL_RCC_HSI_Enable();
 
 /* Wait till HSI is ready */
 while(LL_RCC_HSI_IsReady() != 1)
 {
 
 }
 LL_RCC_HSI_SetCalibTrimming(64);
 LL_RCC_HSI_SetDivider(LL_RCC_HSI_DIV1);
 LL_RCC_PLL_SetSource(LL_RCC_PLLSOURCE_HSI);
 LL_RCC_PLL1P_Enable();
 LL_RCC_PLL1Q_Enable();
 LL_RCC_PLL1_SetVCOInputRange(LL_RCC_PLLINPUTRANGE_8_16);
 LL_RCC_PLL1_SetVCOOutputRange(LL_RCC_PLLVCORANGE_WIDE);
 LL_RCC_PLL1_SetM(4);
 LL_RCC_PLL1_SetN(60);
 LL_RCC_PLL1_SetP(2);
 LL_RCC_PLL1_SetQ(2);
 LL_RCC_PLL1_SetR(2);
 LL_RCC_PLL1_Enable();
 
 /* Wait till PLL is ready */
 while(LL_RCC_PLL1_IsReady() != 1)
 {
 }
 
 /* Intermediate AHB prescaler 2 when target frequency clock is higher than 80 MHz */
 LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
 
 LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL1);
 
 /* Wait till System clock is ready */
 while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL1)
 {
 
 }
 LL_RCC_SetSysPrescaler(LL_RCC_SYSCLK_DIV_1);
 LL_RCC_SetAHBPrescaler(LL_RCC_AHB_DIV_2);
 LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
 LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_2);
 LL_RCC_SetAPB3Prescaler(LL_RCC_APB3_DIV_2);
 LL_RCC_SetAPB4Prescaler(LL_RCC_APB4_DIV_2);
 LL_SetSystemCoreClock(480000000);
 
 /* Update the time base */
 if (HAL_InitTick (TICK_INT_PRIORITY) != HAL_OK)
 {
 Error_Handler();
 }
 LL_RCC_ConfigMCO(LL_RCC_MCO1SOURCE_HSI, LL_RCC_MCO1_DIV_1);
 LL_RCC_ConfigMCO(LL_RCC_MCO2SOURCE_PLL1PCLK, LL_RCC_MCO2_DIV_10);
}

(edited to have the source code as code snippet)

Pavel A.
Super User
March 8, 2023

.

CLeo.1
CLeo.1AuthorBest answer
Senior II
March 9, 2023

Thank you guys for the input, I found the issue, it was just my assumption that it executes its instructions within one clock cycle, I have now moved the software delay implementation into hardware and all seems fine.