cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F722 clock initialization error

Roach
Associate II

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();
  }
}

9 REPLIES 9
TDK
Guru

> 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?

If you feel a post has answered your question, please click "Accept as Solution".
Roach
Associate II

Yes, HSE_VALUE is set to 12000000 and I already checked with an oscilloscope. Everything seems to be fine, the frequency is 12 MHz.

TDK
Guru

> __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?

If you feel a post has answered your question, please click "Accept as Solution".
MM..1
Chief

How other external hw you have initialised? Hard fault exist on SDRAM usw...

Roach
Associate II

Supply voltage is 3.3 V. Error handler is just an empty while loop.

Code never reaches initialization of other peripherals.

Bassett.David
Associate III

Hello,

Have you attended to the number of Flash wait states?

Regards,

Dave

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.

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