cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F7 can't use default STM32CubeMX config, can't enable PLL, and can't switch to Over-drive

MMcAl.1
Associate III

Hello,

I'm using STM32CubeMX 6.3.0 with the bundled version of STM32CubeF4

I create a new project by selecting my STM32F769I-DISCO board and letting Cube initialize all peripherals to their default modes. I generate the project into an SW4STM32 toolchain.

I then open the project and deploy or debug, and it fails on stm32f7xx_hal_rcc.c line 675. I think this is due to a bug caused by a few coding issues when trying to fix https://github.com/STMicroelectronics/STM32CubeF4/issues/17

Notably, it's comparing single bits instead of multiple bit fields, the PLLP logic is wrong, and it isn't bit-shifting the PLLSource or PLLM fields. It's just a mess.

If I bypass that broken check by having it return HAL_OK, it fails on HAL_PWREx_EnableOverDrive() with a timeout.

Here's the SystemClock_Config(void) that STM32CubeMX generates:

void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
  /** Configure LSE Drive Capability
  */
  HAL_PWR_EnableBkUpAccess();
  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI
                              |RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLM = 25;
  RCC_OscInitStruct.PLL.PLLN = 432;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  RCC_OscInitStruct.PLL.PLLR = 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 buses 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_SPDIFRX|RCC_PERIPHCLK_LTDC
                              |RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART1
                              |RCC_PERIPHCLK_USART6|RCC_PERIPHCLK_UART5
                              |RCC_PERIPHCLK_SAI1|RCC_PERIPHCLK_SAI2
                              |RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_I2C4
                              |RCC_PERIPHCLK_SDMMC2|RCC_PERIPHCLK_CLK48
                              |RCC_PERIPHCLK_CEC;
  PeriphClkInitStruct.PLLI2S.PLLI2SN = 192;
  PeriphClkInitStruct.PLLI2S.PLLI2SP = RCC_PLLP_DIV2;
  PeriphClkInitStruct.PLLI2S.PLLI2SR = 2;
  PeriphClkInitStruct.PLLI2S.PLLI2SQ = 2;
  PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
  PeriphClkInitStruct.PLLSAI.PLLSAIR = 2;
  PeriphClkInitStruct.PLLSAI.PLLSAIQ = 3;
  PeriphClkInitStruct.PLLSAI.PLLSAIP = RCC_PLLSAIP_DIV4;
  PeriphClkInitStruct.PLLI2SDivQ = 1;
  PeriphClkInitStruct.PLLSAIDivQ = 1;
  PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
  PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI;
  PeriphClkInitStruct.Sai2ClockSelection = RCC_SAI2CLKSOURCE_PLLSAI;
  PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
  PeriphClkInitStruct.Uart5ClockSelection = RCC_UART5CLKSOURCE_PCLK1;
  PeriphClkInitStruct.Usart6ClockSelection = RCC_USART6CLKSOURCE_PCLK2;
  PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
  PeriphClkInitStruct.I2c4ClockSelection = RCC_I2C4CLKSOURCE_PCLK1;
  PeriphClkInitStruct.CecClockSelection = RCC_CECCLKSOURCE_HSI;
  PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48SOURCE_PLLSAIP;
  PeriphClkInitStruct.Sdmmc2ClockSelection = RCC_SDMMC2CLKSOURCE_CLK48;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1);
}

It fails on line 30, then on 36.

Does anyone know how to enable the over-drive mode for this chip? Thanks

2 REPLIES 2
TDK
Guru

> I'm using STM32CubeMX 6.3.0 with the bundled version of STM32CubeF4

You have an STM32F7, so you will be using the STM32CubeF7 library. The bug you linked is fixed in the latest F4 and F7 packages.

> and it isn't bit-shifting the PLLSource or PLLM fields.

Here's the line it checks for changes in PLLSRC:

(READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||

The right side of which is RCC_PLLSOURCE_HSE in your example file. RCC_PLLSOURCE_HSE is 1 << 22. Seems right to me. Why do you think it's wrong?

#define READ_BIT(REG, BIT) ((REG) & (BIT))

#define RCC_PLLSOURCE_HSE        RCC_PLLCFGR_PLLSRC_HSE

#define RCC_PLLCFGR_PLLSRC_HSE       RCC_PLLCFGR_PLLSRC_HSE_Msk

#define RCC_PLLCFGR_PLLSRC_HSE_Msk     (0x1UL << RCC_PLLCFGR_PLLSRC_HSE_Pos) /*!< 0x00400000

#define RCC_PLLCFGR_PLLSRC_HSE_Pos     (22U)

Same logic applies for PLLM field.

If you feel a post has answered your question, please click "Accept as Solution".
TDK
Guru

It seems like the HSE should be in bypass mode here based on the schematic.

0693W00000D1p22QAB.png 

However, the examples in CubeMX don't use it in bypass mode and I'm not sure why. The examples usually run correctly.

https://github.com/STMicroelectronics/STM32CubeF7/blob/c7c5ec99c7482ea8bcdbf0a869c930af4547088f/Projects/STM32F769I-Discovery/Examples/I2C/I2C_TwoBoards_ComPolling/Src/main.c#L247

I would try HSE in bypass mode and see if that works.

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