2020-07-31 01:33 AM
Hi,
I'm working on a project that uses STM32F722RE and I wanted to set the system clock to max value of 216 MHz using 12MHz external crystal as the input for the PLL. The problem is, if I set the SYSCLK and HCLK to 216 MHz, the code fails to initialize, but if I set it below 104 MHz it runs fine. When program enters the SystemClock_Config(void) function in debugger, it ends up in the hard fault handler after a few seconds. Everything is set up using CubeMX and no code is changed prior to compiling and flashing the MCU. I'm using Keil uVision 5 by the way. Does enyone know what is the problem here and how to solve it?
Here is the snippet of the code generated by CubeMX.
System clock set to 96 MHz:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 128;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C1
|RCC_PERIPHCLK_I2C3;
PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
PeriphClkInitStruct.I2c3ClockSelection = RCC_I2C3CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
}
System clock set to 216 MHz:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
/** Configure the main internal regulator output voltage
*/
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 288;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Activate the Over-Drive mode
*/
if (HAL_PWREx_EnableOverDrive() != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB busses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_I2C1
|RCC_PERIPHCLK_I2C3;
PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
PeriphClkInitStruct.I2c3ClockSelection = RCC_I2C3CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
}
2020-07-31 03:50 PM
> 12MHz external crystal
Is HSE_VALUE set to 12000000? Not sure that would be an issue though.
Can you verify your crystal is 12MHz on a scope? Could be 16MHz which would be overclocking the chip and causing it to fail. 12MHz is not as common.
What info is provided in the hard fault handler?
2020-08-01 06:43 AM
Yes, HSE_VALUE is set to 12000000 and I already checked with an oscilloscope. Everything seems to be fine, the frequency is 12 MHz.
2020-08-01 07:04 AM
> __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
From the reference manual:
- When VOS[1:0] = '0x01', the maximum value of fHCLK is 144 MHz.
You need to use PWR_REGULATOR_VOLTAGE_SCALE1, activate overdrive mode and also meet the voltage requirements to get 216 MHz.
See "SystemClock_Config" within:
https://github.com/STMicroelectronics/STM32CubeF7/blob/3600603267ebc7da619f50542e99bbdfd7e35f4a/Projects/STM32F746ZG-Nucleo/Examples/HAL/HAL_TimeBase_TIM/Src/main.c
But modify it since you have 12MHz HSE crystal instead of 8 MHz HSE bypass.
Edit: Missed that there were two clock inits.
Is your VDD 2.7V or more?
Is Error_Handler actually defined to report an error and not just an empty function which returns immediately?
2020-08-01 07:10 AM
How other external hw you have initialised? Hard fault exist on SDRAM usw...
2020-08-02 07:15 AM
Supply voltage is 3.3 V. Error handler is just an empty while loop.
2020-08-02 07:18 AM
Code never reaches initialization of other peripherals.
2020-08-02 08:11 AM
Hello,
Have you attended to the number of Flash wait states?
Regards,
Dave
2020-08-03 11:52 AM
Hi,
I'm not sure what you're asking me but the number of flash wait states is set to FLASH_LATENCY_7 in code generated by CubeMX. This is the same as in RM0431, page 69.
2020-08-03 10:44 PM
Try on a "known good" board such as Disco or Nucleo. Double-check your primary clock source. Read out and check the RCC registers content, or, better, write your own initialization, avoiding Cube. Use a minimal code (blinky). Debug the hardfault.
JW