From 4e1f335ccb4331c4b252bdd2a3ffdf5ce252221d Mon Sep 17 00:00:00 2001 From: Jamie Smith Date: Wed, 20 Mar 2024 01:37:54 -0700 Subject: [PATCH] Rework STM32H7x clocking configuration --- .../TARGET_STM/TARGET_STM32H7/CMakeLists.txt | 10 + .../TARGET_STM32H723xG/CMakeLists.txt | 1 - .../TARGET_NUCLEO_H743ZI2/CMakeLists.txt | 1 - .../TARGET_STM32H745xI/CMakeLists.txt | 5 - .../TARGET_STM32H745xI/system_clock.c | 206 ------------------ .../TARGET_STM32H747xI/CMakeLists.txt | 5 - .../TARGET_STM32H747xI/system_clock.c | 205 ----------------- .../TARGET_STM32H7/analogin_device.c | 35 +-- .../TARGET_STM32H7_280MHZ}/system_clock.c | 127 ++++++++--- .../TARGET_STM32H7_480MHZ}/system_clock.c | 158 ++++++++++---- .../TARGET_STM32H7_550MHZ}/system_clock.c | 150 +++++++++---- .../TARGET_STM/TARGET_STM32H7/i2c_device.h | 21 ++ targets/TARGET_STM/i2c_api.c | 76 +++++++ targets/targets.json | 78 ++++--- 14 files changed, 489 insertions(+), 589 deletions(-) delete mode 100644 targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H745xI/system_clock.c delete mode 100644 targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/system_clock.c rename targets/TARGET_STM/TARGET_STM32H7/{TARGET_STM32H7A3xIQ => clock_cfg/TARGET_STM32H7_280MHZ}/system_clock.c (60%) rename targets/TARGET_STM/TARGET_STM32H7/{TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI2 => clock_cfg/TARGET_STM32H7_480MHZ}/system_clock.c (54%) rename targets/TARGET_STM/TARGET_STM32H7/{TARGET_STM32H723xG => clock_cfg/TARGET_STM32H7_550MHZ}/system_clock.c (58%) diff --git a/targets/TARGET_STM/TARGET_STM32H7/CMakeLists.txt b/targets/TARGET_STM/TARGET_STM32H7/CMakeLists.txt index 3ecc17c99ab1..7440274559ce 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/CMakeLists.txt +++ b/targets/TARGET_STM/TARGET_STM32H7/CMakeLists.txt @@ -33,3 +33,13 @@ target_include_directories(mbed-stm32h7 ) target_link_libraries(mbed-stm32h7 INTERFACE mbed-stm mbed-stm32h7cube-fw) + + +# Add clock file depending on the frequency +if("STM32H7_480MHZ" IN_LIST MBED_TARGET_LABELS) + target_sources(mbed-stm32h7 INTERFACE clock_cfg/TARGET_STM32H7_480MHZ/system_clock.c) +elseif("STM32H7_550MHZ" IN_LIST MBED_TARGET_LABELS) + target_sources(mbed-stm32h7 INTERFACE clock_cfg/TARGET_STM32H7_550MHZ/system_clock.c) +elseif("STM32H7_280MHZ" IN_LIST MBED_TARGET_LABELS) + target_sources(mbed-stm32h7 INTERFACE clock_cfg/TARGET_STM32H7_280MHZ/system_clock.c) +endif() \ No newline at end of file diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/CMakeLists.txt b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/CMakeLists.txt index 6c4d9652ed5e..9b2626701808 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/CMakeLists.txt +++ b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/CMakeLists.txt @@ -21,7 +21,6 @@ target_include_directories(mbed-stm32h723xg target_sources(mbed-stm32h723xg INTERFACE ${STARTUP_FILE} - system_clock.c ) mbed_set_linker_script(mbed-stm32h723xg ${CMAKE_CURRENT_SOURCE_DIR}/${LINKER_FILE}) diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI2/CMakeLists.txt b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI2/CMakeLists.txt index 09d933d1ca93..24fa63899f1d 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI2/CMakeLists.txt +++ b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI2/CMakeLists.txt @@ -6,7 +6,6 @@ add_library(mbed-nucleo-h743zi2 INTERFACE) target_sources(mbed-nucleo-h743zi2 INTERFACE PeripheralPins.c - system_clock.c ) target_include_directories(mbed-nucleo-h743zi2 diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H745xI/CMakeLists.txt b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H745xI/CMakeLists.txt index 201f0df04506..1cce4eae7f6d 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H745xI/CMakeLists.txt +++ b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H745xI/CMakeLists.txt @@ -6,9 +6,4 @@ add_subdirectory(TARGET_STM32H745xI_CM7 EXCLUDE_FROM_ALL) add_library(mbed-stm32h745xi INTERFACE) -target_sources(mbed-stm32h745xi - INTERFACE - system_clock.c -) - target_link_libraries(mbed-stm32h745xi INTERFACE mbed-stm32h7) diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H745xI/system_clock.c b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H745xI/system_clock.c deleted file mode 100644 index 2803161af690..000000000000 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H745xI/system_clock.c +++ /dev/null @@ -1,206 +0,0 @@ -/* mbed Microcontroller Library - * SPDX-License-Identifier: BSD-3-Clause - ****************************************************************************** - * - * Copyright (c) 2015-2020 STMicroelectronics. - * All rights reserved. - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/** - * This file configures the system clock as follows: - *-------------------------------------------------------------------- - * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) - * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) - * | 3- USE_PLL_HSI (internal 64 MHz clock) - *-------------------------------------------------------------------- - * SYSCLK(MHz) | 480 - * AHBCLK (MHz) | 240 - * APB1CLK (MHz) | 120 - * APB2CLK (MHz) | 120 - * APB3CLK (MHz) | 120 - * APB4CLK (MHz) | 120 - * USB capable (48 MHz) | YES - *-------------------------------------------------------------------- -**/ - -#include "stm32h7xx.h" -#include "mbed_error.h" - -// clock source is selected with CLOCK_SOURCE in json config -#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) -#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) -#define USE_PLL_HSI 0x2 // Use HSI internal clock - -#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) -uint8_t SetSysClock_PLL_HSE(uint8_t bypass); -#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ - -#if ((CLOCK_SOURCE) & USE_PLL_HSI) -uint8_t SetSysClock_PLL_HSI(void); -#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ - -/** - * @brief Configures the System clock source, PLL Multiplier and Divider factors, - * AHB/APBx prescalers and Flash settings - * @note This function should be called only once the RCC clock configuration - * is reset to the default reset state (done in SystemInit() function). - * @param None - * @retval None - */ - -void SetSysClock(void) -{ -#if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) - /* 1- Try to start with HSE and external clock (MCO from STLink PCB part) */ - if (SetSysClock_PLL_HSE(1) == 0) -#endif - { -#if ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) - /* 2- If fail try to start with HSE and external xtal */ - if (SetSysClock_PLL_HSE(0) == 0) -#endif - { -#if ((CLOCK_SOURCE) & USE_PLL_HSI) - /* 3- If fail start with HSI clock */ - if (SetSysClock_PLL_HSI() == 0) -#endif - { - error("SetSysClock failed\n"); - } - } - } -} - -#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) -/******************************************************************************/ -/* PLL (clocked by HSE) used as System clock source */ -/******************************************************************************/ -MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; - - /* Configure the main internal regulator output voltage */ - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); - - while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} - - /* Enable HSE Oscillator and activate PLL with HSE as source */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI48; - if (bypass) { - RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; - } else { - RCC_OscInitStruct.HSEState = RCC_HSE_ON; - } - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; -#if HSE_VALUE==25000000 - RCC_OscInitStruct.PLL.PLLM = 5; // 5 MHz - RCC_OscInitStruct.PLL.PLLN = 192; // 960 MHz -#elif HSE_VALUE==8000000 - RCC_OscInitStruct.PLL.PLLM = 4; // 2 MHz - RCC_OscInitStruct.PLL.PLLN = 480; // 960 MHz -#endif - RCC_OscInitStruct.PLL.PLLP = 2; // PLLCLK = SYSCLK = 480 MHz - RCC_OscInitStruct.PLL.PLLQ = 96; // PLL1Q used for FDCAN = 10 MHz - RCC_OscInitStruct.PLL.PLLR = 2; - RCC_OscInitStruct.PLL.PLLFRACN = 0; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - return 0; // FAIL - } - - /* Select PLL as system clock source and configure bus clocks dividers */ - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | - RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | - RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_D3PCLK1; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; - RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; - RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; - RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; - RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { - return 0; // FAIL - } - -#if DEVICE_USBDEVICE - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; - PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { - return 0; // FAIL - } - - HAL_PWREx_EnableUSBVoltageDetector(); -#endif /* DEVICE_USBDEVICE */ - - __HAL_RCC_CSI_ENABLE() ; - - __HAL_RCC_SYSCFG_CLK_ENABLE() ; - - HAL_EnableCompensationCell(); - - return 1; // OK -} -#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ - -#if ((CLOCK_SOURCE) & USE_PLL_HSI) -/******************************************************************************/ -/* PLL (clocked by HSI) used as System clock source */ -/******************************************************************************/ -uint8_t SetSysClock_PLL_HSI(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* Configure the main internal regulator output voltage */ - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); - - while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} - - // Enable HSI oscillator and activate PLL with HSI as source - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_CSI; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSEState = RCC_HSE_OFF; - RCC_OscInitStruct.CSIState = RCC_CSI_OFF; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLM = 8; // 8 MHz - RCC_OscInitStruct.PLL.PLLN = 120; // 960 MHz - RCC_OscInitStruct.PLL.PLLP = 2; // 480 MHz - RCC_OscInitStruct.PLL.PLLQ = 96; // PLL1Q used for FDCAN = 10 MHz - RCC_OscInitStruct.PLL.PLLR = 2; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - return 0; // FAIL - } - - /* Select PLL as system clock source and configure bus clocks dividers */ - RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ - RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; - RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; - RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; - RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; - RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { - return 0; // FAIL - } - - return 1; // OK -} -#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/CMakeLists.txt b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/CMakeLists.txt index 48a08337733f..6dc33fd7acf8 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/CMakeLists.txt +++ b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/CMakeLists.txt @@ -8,9 +8,4 @@ add_subdirectory(TARGET_PORTENTA_H7 EXCLUDE_FROM_ALL) add_library(mbed-stm32h747xi INTERFACE) -target_sources(mbed-stm32h747xi - INTERFACE - system_clock.c -) - target_link_libraries(mbed-stm32h747xi INTERFACE mbed-stm32h7) diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/system_clock.c b/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/system_clock.c deleted file mode 100644 index b2e1661388d3..000000000000 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H747xI/system_clock.c +++ /dev/null @@ -1,205 +0,0 @@ -/* mbed Microcontroller Library - * SPDX-License-Identifier: BSD-3-Clause - ****************************************************************************** - * - * Copyright (c) 2015-2020 STMicroelectronics. - * All rights reserved. - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/** - * This file configures the system clock as follows: - *-------------------------------------------------------------------- - * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) - * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) - * | 3- USE_PLL_HSI (internal 64 MHz clock) - *-------------------------------------------------------------------- - * SYSCLK(MHz) | 480 - * AHBCLK (MHz) | 240 - * APB1CLK (MHz) | 120 - * APB2CLK (MHz) | 120 - * APB3CLK (MHz) | 120 - * APB4CLK (MHz) | 120 - * USB capable (48 MHz) | YES - *-------------------------------------------------------------------- -**/ - -#include "stm32h7xx.h" -#include "mbed_error.h" - -// clock source is selected with CLOCK_SOURCE in json config -#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) -#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) -#define USE_PLL_HSI 0x2 // Use HSI internal clock - -#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) -uint8_t SetSysClock_PLL_HSE(uint8_t bypass); -#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ - -#if ((CLOCK_SOURCE) & USE_PLL_HSI) -uint8_t SetSysClock_PLL_HSI(void); -#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ - -/** - * @brief Configures the System clock source, PLL Multiplier and Divider factors, - * AHB/APBx prescalers and Flash settings - * @note This function should be called only once the RCC clock configuration - * is reset to the default reset state (done in SystemInit() function). - * @param None - * @retval None - */ - -MBED_WEAK void SetSysClock(void) -{ -#if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) - /* 1- Try to start with HSE and external clock (MCO from STLink PCB part) */ - if (SetSysClock_PLL_HSE(1) == 0) -#endif - { -#if ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) - /* 2- If fail try to start with HSE and external xtal */ - if (SetSysClock_PLL_HSE(0) == 0) -#endif - { -#if ((CLOCK_SOURCE) & USE_PLL_HSI) - /* 3- If fail start with HSI clock */ - if (SetSysClock_PLL_HSI() == 0) -#endif - { - error("SetSysClock failed\n"); - } - } - } -} - -#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) -/******************************************************************************/ -/* PLL (clocked by HSE) used as System clock source */ -/******************************************************************************/ -MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; - RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; - - /* Configure the main internal regulator output voltage */ - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); - - while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} - - /* Enable HSE Oscillator and activate PLL with HSE as source */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI48; - if (bypass) { - RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; - } else { - RCC_OscInitStruct.HSEState = RCC_HSE_ON; - } - RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; -#if HSE_VALUE==25000000 - RCC_OscInitStruct.PLL.PLLM = 5; // 5 MHz - RCC_OscInitStruct.PLL.PLLN = 192; // 960 MHz -#else -#error Unsupported externall clock value, check HSE_VALUE define -#endif - RCC_OscInitStruct.PLL.PLLP = 2; // PLLCLK = SYSCLK = 480 MHz - RCC_OscInitStruct.PLL.PLLQ = 96; // PLL1Q used for FDCAN = 10 MHz - RCC_OscInitStruct.PLL.PLLR = 2; - RCC_OscInitStruct.PLL.PLLFRACN = 0; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - return 0; // FAIL - } - - /* Select PLL as system clock source and configure bus clocks dividers */ - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | - RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | - RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_D3PCLK1; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; - RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; - RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; - RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; - RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { - return 0; // FAIL - } - -#if DEVICE_USBDEVICE - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; - PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { - return 0; // FAIL - } - - HAL_PWREx_EnableUSBVoltageDetector(); -#endif /* DEVICE_USBDEVICE */ - - __HAL_RCC_CSI_ENABLE() ; - - __HAL_RCC_SYSCFG_CLK_ENABLE() ; - - HAL_EnableCompensationCell(); - - return 1; // OK -} -#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ - -#if ((CLOCK_SOURCE) & USE_PLL_HSI) -/******************************************************************************/ -/* PLL (clocked by HSI) used as System clock source */ -/******************************************************************************/ -MBED_WEAK uint8_t SetSysClock_PLL_HSI(void) -{ - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; - - /* Configure the main internal regulator output voltage */ - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); - - while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} - - // Enable HSI oscillator and activate PLL with HSI as source - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_CSI; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSEState = RCC_HSE_OFF; - RCC_OscInitStruct.CSIState = RCC_CSI_OFF; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLM = 8; // 8 MHz - RCC_OscInitStruct.PLL.PLLN = 120; // 960 MHz - RCC_OscInitStruct.PLL.PLLP = 2; // 480 MHz - RCC_OscInitStruct.PLL.PLLQ = 96; // PLL1Q used for FDCAN = 10 MHz - RCC_OscInitStruct.PLL.PLLR = 2; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { - return 0; // FAIL - } - - /* Select PLL as system clock source and configure bus clocks dividers */ - RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ - RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; - RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; - RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; - RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; - RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { - return 0; // FAIL - } - - return 1; // OK -} -#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ diff --git a/targets/TARGET_STM/TARGET_STM32H7/analogin_device.c b/targets/TARGET_STM/TARGET_STM32H7/analogin_device.c index 449b3a3e0159..461d3482de11 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/analogin_device.c +++ b/targets/TARGET_STM/TARGET_STM32H7/analogin_device.c @@ -25,7 +25,7 @@ #include "PeripheralPins.h" -void analogin_pll_configuration(void) +void analogin_clock_configuration(void) { #if defined(DUAL_CORE) while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) { @@ -34,15 +34,7 @@ void analogin_pll_configuration(void) RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC; - PeriphClkInitStruct.PLL2.PLL2M = 4; - PeriphClkInitStruct.PLL2.PLL2N = 240; - PeriphClkInitStruct.PLL2.PLL2P = 2; - PeriphClkInitStruct.PLL2.PLL2Q = 2; - PeriphClkInitStruct.PLL2.PLL2R = 2; - PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_1; - PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE; - PeriphClkInitStruct.PLL2.PLL2FRACN = 0; - PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2; + PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_CLKP; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { error("analogin_init HAL_RCCEx_PeriphCLKConfig"); } @@ -77,6 +69,8 @@ void analogin_init(analogin_t *obj, PinName pin) MBED_ASSERT(obj->handle.Instance != (ADC_TypeDef *)NC); MBED_ASSERT(function != (uint32_t)NC); + analogin_clock_configuration(); + obj->channel = STM_PIN_CHANNEL(function); obj->differential = STM_PIN_INVERTED(function); @@ -85,7 +79,21 @@ void analogin_init(analogin_t *obj, PinName pin) // Configure ADC object structures obj->handle.State = HAL_ADC_STATE_RESET; - obj->handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; + + // PER_CLK is set to 64MHz HSI by SetSystemClock(). We want 32MHz for the ADC clock since + // that's the highest we can get to that's under 50MHz. + // On STM32H74x rev Y, the ADC does not have an internal divider so we need to divide the clock + // by 2. On all other STM32H7 chips, there is an internal /2 divider. +#ifdef TARGET_STM32H7_480MHZ + if(HAL_GetREVID() <= REV_ID_Y) + { + obj->handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV2; + } + else +#endif + { + obj->handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV1; + } obj->handle.Init.Resolution = ADC_RESOLUTION_16B; obj->handle.Init.ScanConvMode = ADC_SCAN_DISABLE; obj->handle.Init.EOCSelection = ADC_EOC_SINGLE_CONV; @@ -101,8 +109,6 @@ void analogin_init(analogin_t *obj, PinName pin) obj->handle.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE; obj->handle.Init.OversamplingMode = DISABLE; - analogin_pll_configuration(); - #if defined(ADC1) if ((ADCName)obj->handle.Instance == ADC_1) { __HAL_RCC_ADC12_CLK_ENABLE(); @@ -143,9 +149,6 @@ uint16_t adc_read(analogin_t *obj) { ADC_ChannelConfTypeDef sConfig = {0}; - /* Reconfigure PLL as it could be lost during deepsleep */ - analogin_pll_configuration(); - // Configure ADC channel sConfig.Rank = ADC_REGULAR_RANK_1; sConfig.SamplingTime = ADC_SAMPLETIME_64CYCLES_5; diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H7A3xIQ/system_clock.c b/targets/TARGET_STM/TARGET_STM32H7/clock_cfg/TARGET_STM32H7_280MHZ/system_clock.c similarity index 60% rename from targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H7A3xIQ/system_clock.c rename to targets/TARGET_STM/TARGET_STM32H7/clock_cfg/TARGET_STM32H7_280MHZ/system_clock.c index 60fd053d0af8..d603fd207dd0 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H7A3xIQ/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32H7/clock_cfg/TARGET_STM32H7_280MHZ/system_clock.c @@ -2,7 +2,7 @@ * SPDX-License-Identifier: BSD-3-Clause ****************************************************************************** * - * Copyright (c) 2015-2020 STMicroelectronics. + * Copyright (c) 2015-2024 STMicroelectronics. * All rights reserved. * * This software component is licensed by ST under BSD 3-Clause license, @@ -15,24 +15,42 @@ /** * This file configures the system clock as follows: - *-------------------------------------------------------------------- - * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) - * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) - * | 3- USE_PLL_HSI (internal 64 MHz clock) - *-------------------------------------------------------------------- - * SYSCLK(MHz) | 280 - * USB capable (48 MHz) | YES - *-------------------------------------------------------------------- + *------------------------------------------------------------------------------ + * System clock source | 1- USE_PLL_HSE_EXTC (overdrive) | 1- USE_PLL_HSE_EXTC + * | 2- USE_PLL_HSE_XTAL (overdrive) | 2- USE_PLL_HSE_XTAL + * | 3- USE_PLL_HSI (overdrive) | 3- USE_PLL_HSI + *------------------------------------------------------------------------------ + * SYSCLK(MHz) | 280 | 225 + * USB capable (48 MHz) | YES | YES + *------------------------------------------------------------------------------ + * + * It is used for all STM32H7 family microcontrollers with a top speed of 280MHz. + * The input clock from the external oscillator may be any frequency evenly divisible by + * 5MHz or 2MHz, and must be between 4MHz and 50MHz. + * + * Note that 280MHz is the "overdrive" mode and is basically an overclock. It is only supported + * under certain conditions (LDO in use) and cannot be used over the full temperature range. + * For industrial applications it is recommended to disable overdrive. Overdrive can be enabled/ + * disabled via the "target.enable-overdrive-mode" option in mbed_app.json. + * **/ #include "stm32h7xx.h" #include "mbed_error.h" // clock source is selected with CLOCK_SOURCE in json config -#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) -#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) +#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO or CMOS oscillator) +#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (not provided by default on nucleo boards) #define USE_PLL_HSI 0x2 // Use HSI internal clock +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE +#define FLASH_LATENCY FLASH_LATENCY_6 +#define VOLTAGE_SCALE PWR_REGULATOR_VOLTAGE_SCALE0 +#else +#define FLASH_LATENCY FLASH_LATENCY_5 +#define VOLTAGE_SCALE PWR_REGULATOR_VOLTAGE_SCALE1 +#endif + #if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) uint8_t SetSysClock_PLL_HSE(uint8_t bypass); #endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */ @@ -71,6 +89,16 @@ void SetSysClock(void) } } } + + /* Make sure that 64MHz HSI clock is selected as the PER_CLOCK source, as this + vastly simplifies peripheral clock logic (since peripherals' input clocks will always + be 64MHz regardless of HSE frequency)*/ + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CKPER; + PeriphClkInitStruct.CkperClockSelection = RCC_CLKPSOURCE_HSI; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { + error("HAL_RCCEx_PeriphCLKConfig failed\n"); + } } @@ -85,7 +113,7 @@ MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /* Configure the main internal regulator output voltage */ - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); + __HAL_PWR_VOLTAGESCALING_CONFIG(VOLTAGE_SCALE); while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} @@ -96,20 +124,50 @@ MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) } else { RCC_OscInitStruct.HSEState = RCC_HSE_ON; } -#if HSE_VALUE==8000000 - RCC_OscInitStruct.PLL.PLLM = 4; // 2 MHz - RCC_OscInitStruct.PLL.PLLN = 280; // 560 MHz + + + if(HSE_VALUE % 2000000 == 0) + { + // Clock divisible by 2. Divide down to 2MHz and then multiply up again. + RCC_OscInitStruct.PLL.PLLM = (HSE_VALUE / 2000000); // PLL1 input clock = 2MHz + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1; // PLL1 input clock is between 2 and 4 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLN = 280; // PLL1 internal (VCO) clock = 560 MHz +#else + RCC_OscInitStruct.PLL.PLLN = 225; // PLL1 internal (VCO) clock = 450 MHz +#endif + } + else if(HSE_VALUE % 5000000 == 0) + { + RCC_OscInitStruct.PLL.PLLM = (HSE_VALUE / 5000000); // PLL1 input clock = 5MHz + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; // PLL1 input clock is between 4 and 8 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLN = 112; // PLL1 internal (VCO) clock = 560 MHz #else -#error Unsupported externall clock value, check HSE_VALUE define + RCC_OscInitStruct.PLL.PLLN = 90; // PLL1 internal (VCO) clock = 450 MHz #endif + } + else + { + error("HSE_VALUE not divisible by 2MHz or 5MHz\n"); + } + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLP = 2; // PLLCLK = SYSCLK = 280 MHz + RCC_OscInitStruct.PLL.PLLP = 2; // PLLCLK = SYSCLK = 280/225 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE RCC_OscInitStruct.PLL.PLLQ = 56; // PLL1Q used for FDCAN = 10 MHz +#else + RCC_OscInitStruct.PLL.PLLQ = 45; // PLL1Q used for FDCAN = 10 MHz +#endif + RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLFRACN = 0; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // PLL1 VCO clock is between 128 and 560 MHz RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { return 0; // FAIL @@ -121,12 +179,12 @@ MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_D3PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6) != HAL_OK) { + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY) != HAL_OK) { return 0; // FAIL } @@ -154,7 +212,7 @@ uint8_t SetSysClock_PLL_HSI(void) RCC_OscInitTypeDef RCC_OscInitStruct; /* Configure the main internal regulator output voltage */ - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + __HAL_PWR_VOLTAGESCALING_CONFIG(VOLTAGE_SCALE); while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} // Enable HSI oscillator and activate PLL with HSI as source @@ -162,15 +220,28 @@ uint8_t SetSysClock_PLL_HSI(void) RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSEState = RCC_HSE_OFF; RCC_OscInitStruct.CSIState = RCC_CSI_OFF; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLM = 32; // 2 MHz - RCC_OscInitStruct.PLL.PLLN = 280; // 560 MHz - RCC_OscInitStruct.PLL.PLLP = 2; // PLLCLK = SYSCLK = 280 MHz + RCC_OscInitStruct.PLL.PLLM = 32; // PLL1 input clock = 2 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLN = 280; // PLL1 internal (VCO) clock = 550 MHz +#else + RCC_OscInitStruct.PLL.PLLN = 225; // PLL1 internal (VCO) clock = 450 MHz +#endif + + RCC_OscInitStruct.PLL.PLLP = 2; // PLLCLK = SYSCLK = 280/225 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE RCC_OscInitStruct.PLL.PLLQ = 56; // PLL1Q used for FDCAN = 10 MHz +#else + RCC_OscInitStruct.PLL.PLLQ = 45; // PLL1Q used for FDCAN = 10 MHz +#endif + RCC_OscInitStruct.PLL.PLLR = 2; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // PLL1 VCO clock is between 128 and 560 MHz + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1; // PLL1 input clock is between 2 and 4 MHz if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { return 0; // FAIL } @@ -181,12 +252,12 @@ uint8_t SetSysClock_PLL_HSI(void) RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_D3PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; - RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_6) != HAL_OK) { + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY) != HAL_OK) { return 0; // FAIL } diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI2/system_clock.c b/targets/TARGET_STM/TARGET_STM32H7/clock_cfg/TARGET_STM32H7_480MHZ/system_clock.c similarity index 54% rename from targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI2/system_clock.c rename to targets/TARGET_STM/TARGET_STM32H7/clock_cfg/TARGET_STM32H7_480MHZ/system_clock.c index 84c85173f78b..9ada72d1f317 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H743xI/TARGET_NUCLEO_H743ZI2/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32H7/clock_cfg/TARGET_STM32H7_480MHZ/system_clock.c @@ -2,7 +2,7 @@ * SPDX-License-Identifier: BSD-3-Clause ****************************************************************************** * - * Copyright (c) 2015-2020 STMicroelectronics. + * Copyright (c) 2015-2024 STMicroelectronics. * All rights reserved. * * This software component is licensed by ST under BSD 3-Clause license, @@ -15,27 +15,37 @@ /** * This file configures the system clock as follows: - *-------------------------------------------------------------------- - * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) - * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) - * | 3- USE_PLL_HSI (internal 64 MHz clock) - *-------------------------------------------------------------------- - * SYSCLK(MHz) | 480 - * AHBCLK (MHz) | 240 - * APB1CLK (MHz) | 120 - * APB2CLK (MHz) | 120 - * APB3CLK (MHz) | 120 - * APB4CLK (MHz) | 120 - * USB capable (48 MHz) | YES - *-------------------------------------------------------------------- + *------------------------------------------------------------------------------ + * System clock source | 1- USE_PLL_HSE_EXTC (overdrive) | 1- USE_PLL_HSE_EXTC + * | 2- USE_PLL_HSE_XTAL (overdrive) | 2- USE_PLL_HSE_XTAL + * | 3- USE_PLL_HSI (overdrive) | 3- USE_PLL_HSI + *------------------------------------------------------------------------------ + * SYSCLK(MHz) | 480 | 400 + * AHBCLK (MHz) | 240 | 200 + * APB1CLK (MHz) | 120 | 100 + * APB2CLK (MHz) | 120 | 100 + * APB3CLK (MHz) | 120 | 100 + * APB4CLK (MHz) | 120 | 100 + * USB capable (48 MHz) | YES | YES + *------------------------------------------------------------------------------ + * + * It is used for all STM32H7 family microcontrollers with a top speed of 480MHz. + * The input clock from the external oscillator may be any frequency evenly divisible by + * 5MHz or 2MHz, and must be between 4MHz and 50MHz. + * + * Note that 480MHz is the "overdrive" mode and is basically an overclock. It is only supported + * under certain conditions (LDO in use) and cannot be used over the full temperature range. + * For industrial applications it is recommended to disable overdrive. Overdrive can be enabled/ + * disabled via the "target.enable-overdrive-mode" option in mbed_app.json. + * **/ #include "stm32h7xx.h" #include "mbed_error.h" // clock source is selected with CLOCK_SOURCE in json config -#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) -#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) +#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO or CMOS oscillator) +#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (not provided by default on nucleo boards) #define USE_PLL_HSI 0x2 // Use HSI internal clock #if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) @@ -46,6 +56,12 @@ uint8_t SetSysClock_PLL_HSE(uint8_t bypass); uint8_t SetSysClock_PLL_HSI(void); #endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE +#define FLASH_LATENCY FLASH_LATENCY_4 +#else +#define FLASH_LATENCY FLASH_LATENCY_2 +#endif + /** * @brief Configures the System clock source, PLL Multiplier and Divider factors, * AHB/APBx prescalers and Flash settings @@ -76,6 +92,16 @@ void SetSysClock(void) } } } + + /* Make sure that 64MHz HSI clock is selected as the PER_CLOCK source, as this + vastly simplifies peripheral clock logic (since peripherals' input clocks will always + be 64MHz regardless of HSE frequency)*/ + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CKPER; + PeriphClkInitStruct.CkperClockSelection = RCC_CLKPSOURCE_HSI; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { + error("HAL_RCCEx_PeriphCLKConfig failed\n"); + } } @@ -94,6 +120,15 @@ MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + /* Enable overdrive mode (needed to hit 480MHz). Note that on STM32H74x/5x, + unlike other STM32H7x devices, you have to switch to VOS1 first, then switch to VOS0. */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); + + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} +#endif + /* Enable HSE Oscillator and activate PLL with HSE as source */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI48; if (bypass) { @@ -104,21 +139,46 @@ MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; -#if HSE_VALUE==8000000 - RCC_OscInitStruct.PLL.PLLM = 4; // 2 MHz - RCC_OscInitStruct.PLL.PLLN = 480; // 960 MHz -#elif HSE_VALUE==25000000 - RCC_OscInitStruct.PLL.PLLM = 5; // 5 MHz - RCC_OscInitStruct.PLL.PLLN = 192; // 960 MHz + + if(HSE_VALUE % 2000000 == 0) + { + // Clock divisible by 2. Divide down to 2MHz and then multiply up again. + RCC_OscInitStruct.PLL.PLLM = (HSE_VALUE / 2000000); // PLL1 input clock = 2MHz + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1; // PLL1 input clock is between 2 and 4 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLN = 480; // PLL1 internal (VCO) clock = 960 MHz +#else + RCC_OscInitStruct.PLL.PLLN = 400; // PLL1 internal (VCO) clock = 800 MHz +#endif + } + else if(HSE_VALUE % 5000000 == 0) + { + RCC_OscInitStruct.PLL.PLLM = (HSE_VALUE / 5000000); // PLL1 input clock = 5MHz + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; // PLL1 input clock is between 4 and 8 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLN = 192; // 960 MHz #else -#error Unsupported externall clock value, check HSE_VALUE define + RCC_OscInitStruct.PLL.PLLN = 160; // 800 MHz #endif - RCC_OscInitStruct.PLL.PLLP = 2; // PLLCLK = SYSCLK = 480 MHz + } + else + { + error("HSE_VALUE not divisible by 2MHz or 5MHz\n"); + } + + RCC_OscInitStruct.PLL.PLLP = 2; // PLLCLK = SYSCLK = 480/400 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE RCC_OscInitStruct.PLL.PLLQ = 96; // PLL1Q used for FDCAN = 10 MHz +#else + RCC_OscInitStruct.PLL.PLLQ = 80; // PLL1Q used for FDCAN = 10 MHz +#endif + RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLFRACN = 0; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // PLL1 VCO clock is between 192 and 960 MHz if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { return 0; // FAIL } @@ -134,7 +194,7 @@ MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY) != HAL_OK) { return 0; // FAIL } @@ -158,27 +218,49 @@ MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) /******************************************************************************/ uint8_t SetSysClock_PLL_HSI(void) { - RCC_ClkInitTypeDef RCC_ClkInitStruct; - RCC_OscInitTypeDef RCC_OscInitStruct; + RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_OscInitTypeDef RCC_OscInitStruct = {0}; - /* Configure the main internal regulator output voltage */ + /* First step voltage regulator up to full voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + /* Enable overdrive mode (needed to hit 480MHz). Note that on STM32H74x/5x, + unlike other STM32H7x devices, you have to switch to VOS1 first, then switch to VOS0. */ + __HAL_RCC_SYSCFG_CLK_ENABLE(); + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); + + while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} +#endif + // Enable HSI oscillator and activate PLL with HSI as source RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_CSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSEState = RCC_HSE_OFF; RCC_OscInitStruct.CSIState = RCC_CSI_OFF; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLM = 8; // 8 MHz - RCC_OscInitStruct.PLL.PLLN = 120; // 960 MHz - RCC_OscInitStruct.PLL.PLLP = 2; // 480 MHz - RCC_OscInitStruct.PLL.PLLQ = 96; // PLL1Q used for FDCAN = 10 MHz + RCC_OscInitStruct.PLL.PLLM = 8; //PLL1 input clock = 8 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLN = 120; // PLL1 internal (VCO) clock = 960 MHz +#else + RCC_OscInitStruct.PLL.PLLN = 100; // PLL1 internal (VCO) clock = 800 MHz +#endif + + RCC_OscInitStruct.PLL.PLLP = 2; // 480/400 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLQ = 96; // PLL1Q used for FDCAN = 10 MHz +#else + RCC_OscInitStruct.PLL.PLLQ = 80; // PLL1Q used for FDCAN = 10 MHz +#endif + RCC_OscInitStruct.PLL.PLLR = 2; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // PLL1 VCO clock is between 192 and 960 MHz + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; // PLL1 input clock is between 8 and 16 MHz if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { return 0; // FAIL } @@ -193,10 +275,10 @@ uint8_t SetSysClock_PLL_HSI(void) RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) { + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY) != HAL_OK) { return 0; // FAIL } - + return 1; // OK } #endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ diff --git a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/system_clock.c b/targets/TARGET_STM/TARGET_STM32H7/clock_cfg/TARGET_STM32H7_550MHZ/system_clock.c similarity index 58% rename from targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/system_clock.c rename to targets/TARGET_STM/TARGET_STM32H7/clock_cfg/TARGET_STM32H7_550MHZ/system_clock.c index 60dca8613bd8..e28c90c3ce79 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/TARGET_STM32H723xG/system_clock.c +++ b/targets/TARGET_STM/TARGET_STM32H7/clock_cfg/TARGET_STM32H7_550MHZ/system_clock.c @@ -2,7 +2,7 @@ * SPDX-License-Identifier: BSD-3-Clause ****************************************************************************** * - * Copyright (c) 2015-2020 STMicroelectronics. + * Copyright (c) 2015-2024 STMicroelectronics. * All rights reserved. * * This software component is licensed by ST under BSD 3-Clause license, @@ -15,27 +15,37 @@ /** * This file configures the system clock as follows: - *-------------------------------------------------------------------- - * System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock) - * | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal) - * | 3- USE_PLL_HSI (internal 64 MHz clock) - *-------------------------------------------------------------------- - * SYSCLK(MHz) | 550 - * AHBCLK (MHz) | 275 - * APB1CLK (MHz) | 137.5 - * APB2CLK (MHz) | 137.5 - * APB3CLK (MHz) | 137.5 - * APB4CLK (MHz) | 137.5 - * USB capable (48 MHz) | YES - *-------------------------------------------------------------------- + *------------------------------------------------------------------------------ + * System clock source | 1- USE_PLL_HSE_EXTC (overdrive) | 1- USE_PLL_HSE_EXTC + * | 2- USE_PLL_HSE_XTAL (overdrive) | 2- USE_PLL_HSE_XTAL + * | 3- USE_PLL_HSI (overdrive) | 3- USE_PLL_HSI + *------------------------------------------------------------------------------ + * SYSCLK(MHz) | 550 | 400 + * AHBCLK (MHz) | 275 | 200 + * APB1CLK (MHz) | 137.5 | 100 + * APB2CLK (MHz) | 137.5 | 100 + * APB3CLK (MHz) | 137.5 | 100 + * APB4CLK (MHz) | 137.5 | 100 + * USB capable (48 MHz) | YES | YES + *------------------------------------------------------------------------------ + * + * It is used for all STM32H7 family microcontrollers with a top speed of 550MHz. + * The input clock from the external oscillator may be any frequency evenly divisible by + * 5MHz or 2MHz, and must be between 4MHz and 50MHz. + * + * Note that 550MHz is the "overdrive" mode and is basically an overclock. It is only supported + * under certain conditions (LDO in use) and cannot be used over the full temperature range. + * For industrial applications it is recommended to disable overdrive. Overdrive can be enabled/ + * disabled via the "target.enable-overdrive-mode" option in mbed_app.json. + * **/ #include "stm32h7xx.h" #include "mbed_error.h" // clock source is selected with CLOCK_SOURCE in json config -#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO) -#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default) +#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO or CMOS oscillator) +#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (not provided by default on nucleo boards) #define USE_PLL_HSI 0x2 // Use HSI internal clock #if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) ) @@ -46,6 +56,14 @@ uint8_t SetSysClock_PLL_HSE(uint8_t bypass); uint8_t SetSysClock_PLL_HSI(void); #endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */ +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE +#define FLASH_LATENCY FLASH_LATENCY_3 +#define VOLTAGE_SCALE PWR_REGULATOR_VOLTAGE_SCALE0 +#else +#define FLASH_LATENCY FLASH_LATENCY_2 +#define VOLTAGE_SCALE PWR_REGULATOR_VOLTAGE_SCALE1 +#endif + /** * @brief Configures the System clock source, PLL Multiplier and Divider factors, * AHB/APBx prescalers and Flash settings @@ -76,6 +94,16 @@ void SetSysClock(void) } } } + + /* Make sure that 64MHz HSI clock is selected as the PER_CLOCK source, as this + vastly simplifies peripheral clock logic (since peripherals' input clocks will always + be 64MHz regardless of HSE frequency)*/ + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_CKPER; + PeriphClkInitStruct.CkperClockSelection = RCC_CLKPSOURCE_HSI; + if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { + error("HAL_RCCEx_PeriphCLKConfig failed\n"); + } } @@ -92,13 +120,9 @@ MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); /* Configure the main internal regulator output voltage */ - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); + __HAL_PWR_VOLTAGESCALING_CONFIG(VOLTAGE_SCALE); while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} - /* Configure LSE Drive Capability */ - HAL_PWR_EnableBkUpAccess(); - __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); - /* Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSE; @@ -110,14 +134,45 @@ MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; - RCC_OscInitStruct.PLL.PLLM = 1; // 8 MHz - RCC_OscInitStruct.PLL.PLLN = 68; // 550 MHz (see PLLFRACN) - RCC_OscInitStruct.PLL.PLLP = 1; // 550 MHz - RCC_OscInitStruct.PLL.PLLQ = 5; // 110 MHz - RCC_OscInitStruct.PLL.PLLR = 2; // 275 MHz - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; - RCC_OscInitStruct.PLL.PLLFRACN = 6144; + + if(HSE_VALUE % 2000000 == 0) + { + // Clock divisible by 2. Divide down to 2MHz and then multiply up again. + RCC_OscInitStruct.PLL.PLLM = (HSE_VALUE / 2000000); // PLL1 input clock = 2MHz + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1; // PLL1 input clock is between 2 and 4 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLN = 275; // PLL1 internal (VCO) clock = 550 MHz +#else + RCC_OscInitStruct.PLL.PLLN = 200; // PLL1 internal (VCO) clock = 400 MHz +#endif + } + else if(HSE_VALUE % 5000000 == 0) + { + RCC_OscInitStruct.PLL.PLLM = (HSE_VALUE / 5000000); // PLL1 input clock = 5MHz + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; // PLL1 input clock is between 4 and 8 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLN = 110; // PLL1 internal (VCO) clock = 550 MHz +#else + RCC_OscInitStruct.PLL.PLLN = 80; // PLL1 internal (VCO) clock = 400 MHz +#endif + } + else + { + error("HSE_VALUE not divisible by 2MHz or 5MHz\n"); + } + + RCC_OscInitStruct.PLL.PLLP = 1; // 550/400 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // PLL1 VCO clock is between 192 and 836 MHz + RCC_OscInitStruct.PLL.PLLQ = 55; // PLL1Q used for FDCAN = 10 MHz +#else + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; // PLL1 VCO clock is between 150 and 420 MHz + RCC_OscInitStruct.PLL.PLLQ = 40; // PLL1Q used for FDCAN = 10 MHz +#endif + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { return 0; // FAIL } @@ -134,7 +189,7 @@ MBED_WEAK uint8_t SetSysClock_PLL_HSE(uint8_t bypass) RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) { + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY) != HAL_OK) { return 0; // FAIL } @@ -166,13 +221,9 @@ uint8_t SetSysClock_PLL_HSI(void) HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); /* Configure the main internal regulator output voltage */ - __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); + __HAL_PWR_VOLTAGESCALING_CONFIG(VOLTAGE_SCALE); while (!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} - /* Configure LSE Drive Capability */ - HAL_PWR_EnableBkUpAccess(); - __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); - /* Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI; @@ -181,14 +232,27 @@ uint8_t SetSysClock_PLL_HSI(void) RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLM = 4; // 16 MHz - RCC_OscInitStruct.PLL.PLLN = 34; // 550 MHz (see PLLFRACN) - RCC_OscInitStruct.PLL.PLLP = 1; // 550 MHz - RCC_OscInitStruct.PLL.PLLQ = 5; // 110 MHz + RCC_OscInitStruct.PLL.PLLM = 32; // PLL1 input clock = 2MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLN = 275; // PLL1 internal (VCO) clock = 550 MHz +#else + RCC_OscInitStruct.PLL.PLLN = 200; // PLL1 internal (VCO) clock = 400 MHz +#endif + + RCC_OscInitStruct.PLL.PLLP = 1; // 550/400 MHz + +#if MBED_CONF_TARGET_ENABLE_OVERDRIVE_MODE + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; // PLL1 VCO clock is between 192 and 836 MHz + RCC_OscInitStruct.PLL.PLLQ = 55; // PLL1Q used for FDCAN = 10 MHz +#else + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; // PLL1 VCO clock is between 150 and 420 MHz + RCC_OscInitStruct.PLL.PLLQ = 40; // PLL1Q used for FDCAN = 10 MHz +#endif + RCC_OscInitStruct.PLL.PLLR = 2; // 275 MHz - RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; - RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; - RCC_OscInitStruct.PLL.PLLFRACN = 3072; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1; // PLL1 input clock is between 2 and 4 MHz + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { return 0; // FAIL } @@ -205,7 +269,7 @@ uint8_t SetSysClock_PLL_HSI(void) RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; - if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) { + if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY) != HAL_OK) { return 0; // FAIL } diff --git a/targets/TARGET_STM/TARGET_STM32H7/i2c_device.h b/targets/TARGET_STM/TARGET_STM32H7/i2c_device.h index 16dbfb932c95..953f5a2d3020 100644 --- a/targets/TARGET_STM/TARGET_STM32H7/i2c_device.h +++ b/targets/TARGET_STM/TARGET_STM32H7/i2c_device.h @@ -29,11 +29,32 @@ extern "C" { /* Define IP version */ #define I2C_IP_VERSION_V2 +// Note: Below values are generated using STM32Cube IDE +#define TIMING_VAL_140M_CLK_100KHZ 0x70B1445E // Standard mode with Rise Time = 400ns and Fall Time = 100ns +#define TIMING_VAL_140M_CLK_400KHZ 0x30C11233 // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_140M_CLK_1MHZ 0x00F41B47 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_140M 140000000 // 140 MHz + +#define TIMING_VAL_137M5_CLK_100KHZ 0x70B1445B // Standard mode with Rise Time = 400ns and Fall Time = 100ns +#define TIMING_VAL_137M5_CLK_400KHZ 0x80510815 // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_137M5_CLK_1MHZ 0x00F41A46 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_137M5 137500000 // 137.5 MHz + #define TIMING_VAL_120M_CLK_100KHZ 0x40E15676 // Standard mode with Rise Time = 400ns and Fall Time = 100ns #define TIMING_VAL_120M_CLK_400KHZ 0x20C11434 // Fast mode with Rise Time = 250ns and Fall Time = 100ns #define TIMING_VAL_120M_CLK_1MHZ 0x00C31536 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns #define I2C_PCLK_120M 120000000 // 120 MHz +#define TIMING_VAL_112M5_CLK_100KHZ 0x80813142 // Standard mode with Rise Time = 400ns and Fall Time = 100ns +#define TIMING_VAL_112M5_CLK_400KHZ 0x20D11337 // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_112M5_CLK_1MHZ 0x00C31538 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_112M5 112500000 // 112.5 MHz + +#define TIMING_VAL_100M_CLK_100KHZ 0x50A14159 // Standard mode with Rise Time = 400ns and Fall Time = 100ns +#define TIMING_VAL_100M_CLK_400KHZ 0x20B11130 // Fast mode with Rise Time = 250ns and Fall Time = 100ns +#define TIMING_VAL_100M_CLK_1MHZ 0x00A21232 // Fast mode Plus with Rise Time = 60ns and Fall Time = 100ns +#define I2C_PCLK_100M 100000000 // 100 MHz + #define I2C_IT_ALL (I2C_IT_ERRI|I2C_IT_TCI|I2C_IT_STOPI|I2C_IT_NACKI|I2C_IT_ADDRI|I2C_IT_RXI|I2C_IT_TXI) /* Family specifc settings for clock source */ diff --git a/targets/TARGET_STM/i2c_api.c b/targets/TARGET_STM/i2c_api.c index 266eeaa57725..fecb808d2805 100644 --- a/targets/TARGET_STM/i2c_api.c +++ b/targets/TARGET_STM/i2c_api.c @@ -2169,6 +2169,25 @@ uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, } break; #endif +#if defined (I2C_PCLK_100M) + case I2C_PCLK_100M: + switch (hz) { + case 100000: + tim = TIMING_VAL_100M_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_100M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_100M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif #if defined (I2C_PCLK_110M) case I2C_PCLK_110M: switch (hz) { @@ -2188,6 +2207,25 @@ uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, } break; #endif +#if defined (I2C_PCLK_112M5) + case I2C_PCLK_112M5: + switch (hz) { + case 100000: + tim = TIMING_VAL_112M5_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_112M5_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_112M5_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif #if defined (I2C_PCLK_120M) case I2C_PCLK_120M: switch (hz) { @@ -2207,6 +2245,44 @@ uint32_t i2c_get_timing(I2CName i2c, uint32_t current_timing, int current_hz, } break; #endif +#if defined (I2C_PCLK_137M5) + case I2C_PCLK_137M5: + switch (hz) { + case 100000: + tim = TIMING_VAL_137M5_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_137M5_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_137M5_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif +#if defined (I2C_PCLK_140M) + case I2C_PCLK_140M: + switch (hz) { + case 100000: + tim = TIMING_VAL_140M_CLK_100KHZ; + break; + case 400000: + tim = TIMING_VAL_140M_CLK_400KHZ; + break; + case 1000000: + tim = TIMING_VAL_140M_CLK_1MHZ; + break; + default: + MBED_ASSERT((hz == 100000) || (hz == 400000) || \ + (hz == 1000000)); + break; + } + break; +#endif #if defined (I2C_PCLK_160M) case I2C_PCLK_160M: switch (hz) { diff --git a/targets/targets.json b/targets/targets.json index 3afaf7d3a6b4..b8e7b7973d15 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -3204,6 +3204,15 @@ "i2c_timing_value_algo": { "help": "If value was set to true I2C timing algorithm is enabled. Enabling may leads to performance issue. Keeping this false and changing system clock will trigger assert.)", "value": false + }, + "enable-overdrive-mode": { + "help": "Enable 'overdrive mode' (also known as VOS0) and raise core clock to the maximum value. Only supported when the internal LDO is used for core voltage source. Reduces the temperature range of the chip, see datasheet for details.", + "value": 1 + }, + "hse_value": { + "help": "Frequency in MHz of external oscillator / crystal. Will be used to compute PLL parameters.", + "value": "8000000", + "macro_name": "HSE_VALUE" } }, "components_add": [ @@ -3232,15 +3241,15 @@ "public": false, "core": "Cortex-M7FD", "extra_labels_add": [ - "STM32H723xG" + "STM32H723xG", + "STM32H7_550MHZ" ], "macros_add": [ "MBED_SPLIT_HEAP", "STM32H723xx" ], "overrides": { - "system_power_supply": "PWR_LDO_SUPPLY", - "i2c_timing_value_algo": true + "system_power_supply": "PWR_LDO_SUPPLY" } }, "MCU_STM32H725xE": { @@ -3254,7 +3263,8 @@ "mbed_ram_start": "0x24000000", "mbed_ram_size": "0x50000", "extra_labels_add": [ - "STM32H725xE" + "STM32H725xE", + "STM32H7_550MHZ" ], "macros_add": [ "STM32H725xx" @@ -3274,7 +3284,8 @@ "mbed_ram_start": "0x24000000", "mbed_ram_size": "0x50000", "extra_labels_add": [ - "STM32H735xG" + "STM32H735xG", + "STM32H7_550MHZ" ], "macros_add": [ "STM32H735xx" @@ -3308,11 +3319,6 @@ "help": "Value: PB_5 for the default board configuration, PA_7 in case of solder bridge update (SB33 on/ SB35 off)", "value": "PB_5", "macro_name": "STM32_D11_SPI_ETHERNET_PIN" - }, - "hse_value": { - "help": "HSE default value is 25MHz in HAL", - "value": "8000000", - "macro_name": "HSE_VALUE" } }, "device_has_add": [ @@ -3379,13 +3385,15 @@ ], "public": false, "extra_labels_add": [ - "STM32H745xI" + "STM32H745xI", + "STM32H7_480MHZ" ], "macros_add": [ "STM32H745xx" ], "overrides": { - "system_power_supply": "PWR_DIRECT_SMPS_SUPPLY" + "system_power_supply": "PWR_DIRECT_SMPS_SUPPLY", + "enable-overdrive-mode": 0 } }, "MCU_STM32H745xI_CM4": { @@ -3436,11 +3444,6 @@ "value": "PB_5", "macro_name": "STM32_D11_SPI_ETHERNET_PIN" }, - "hse_value": { - "help": "HSE default value is 25MHz in HAL", - "value": "8000000", - "macro_name": "HSE_VALUE" - }, "usb_speed": { "help": "USE_USB_OTG_FS or USE_USB_OTG_HS or USE_USB_HS_IN_FS", "value": "USE_USB_OTG_FS" @@ -3468,11 +3471,6 @@ "value": "PB_5", "macro_name": "STM32_D11_SPI_ETHERNET_PIN" }, - "hse_value": { - "help": "HSE default value is 25MHz in HAL", - "value": "8000000", - "macro_name": "HSE_VALUE" - }, "usb_speed": { "help": "USE_USB_OTG_FS or USE_USB_OTG_HS or USE_USB_HS_IN_FS", "value": "USE_USB_OTG_FS" @@ -3497,13 +3495,15 @@ ], "public": false, "extra_labels_add": [ - "STM32H747xI" + "STM32H747xI", + "STM32H7_480MHZ" ], "macros_add": [ "STM32H747xx" ], "overrides": { - "system_power_supply": "PWR_DIRECT_SMPS_SUPPLY" + "system_power_supply": "PWR_DIRECT_SMPS_SUPPLY", + "enable-overdrive-mode": 0 } }, "MCU_STM32H747xI_CM7": { @@ -3595,11 +3595,6 @@ "public": false, "inherits": ["MCU_STM32H747xI"], "config": { - "hse_value": { - "help": "HSE default value is 25MHz in HAL", - "value": "25000000", - "macro_name": "HSE_VALUE" - }, "lse_bypass": { "help": "1 to use an oscillator (not a crystal) on 32k LSE", "value": "1" @@ -3638,7 +3633,9 @@ "lse_available": 1, "lpticker_delay_ticks": 0, "network-default-interface-type": "ETHERNET", - "i2c_timing_value_algo": true + "i2c_timing_value_algo": true, + "hse_value": 25000000, + "enable-overdrive-mode": 1 }, "device_name": "STM32H747XIHx" }, @@ -3701,7 +3698,8 @@ "public": false, "core": "Cortex-M7FD", "extra_labels_add": [ - "STM32H753xI" + "STM32H753xI", + "STM32H7_480MHZ" ], "macros_add": [ "STM32H753xx" @@ -3721,25 +3719,21 @@ "mbed_ram_start": "0x24000000", "mbed_ram_size": "0x100000", "extra_labels_add": [ - "STM32H7A3xIQ" + "STM32H7A3xIQ", + "STM32H7_280MHZ" ], "macros_add": [ "STM32H7A3xxQ" ], "overrides": { - "system_power_supply": "PWR_DIRECT_SMPS_SUPPLY" + "system_power_supply": "PWR_DIRECT_SMPS_SUPPLY", + "enable-overdrive-mode": 0 } }, "NUCLEO_H7A3ZI_Q": { "inherits": [ "MCU_STM32H7A3xIQ" ], - "config": { - "hse_value": { - "value": "8000000", - "macro_name": "HSE_VALUE" - } - }, "supported_form_factors": [ "ARDUINO_UNO" ], @@ -3759,13 +3753,15 @@ "mbed_ram_start": "0x24000000", "mbed_ram_size": "0x100000", "extra_labels_add": [ - "STM32H7B3xIQ" + "STM32H7B3xIQ", + "STM32H7_280MHZ" ], "macros_add": [ "STM32H7B3xxQ" ], "overrides": { - "system_power_supply": "PWR_DIRECT_SMPS_SUPPLY" + "system_power_supply": "PWR_DIRECT_SMPS_SUPPLY", + "enable-overdrive-mode": 0 } }, "MCU_STM32L0": {