2023-03-07 08:31 PM
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?
Solved! Go to Solution.
2023-03-08 08:15 PM
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.
2023-03-07 08:56 PM
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:
2023-03-07 09:00 PM
@christop Yup, tried that, no bueno still seeing the same results
2023-03-07 11:16 PM
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.
2023-03-07 11:32 PM
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.
2023-03-08 12:16 AM
Actually interesting, when manually writing into the D3CR regiester I see the contents within the resgister change oppose to using the LL API variant of it then when switching to PLL1_P clock the MCU crashes
2023-03-08 12:19 AM
Ah, thanks! Another difference to the H735 that I am working on currently.
2023-03-08 01:11 PM
@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)
2023-03-08 01:17 PM
.
2023-03-08 08:15 PM
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.