diff --git a/src/main/interface/settings.c b/src/main/interface/settings.c index 7c6941b5d..660f00902 100644 --- a/src/main/interface/settings.c +++ b/src/main/interface/settings.c @@ -287,6 +287,8 @@ static const char * const lookupOverclock[] = { "192MHZ", "216MHZ", "240MHZ" #elif defined(STM32F411xE) "108MHZ", "120MHZ" +#elif defined(STM32F7) + "240MHZ" #endif }; #endif diff --git a/src/main/platform.h b/src/main/platform.h index 9f2fdc819..f28bae79c 100644 --- a/src/main/platform.h +++ b/src/main/platform.h @@ -24,6 +24,7 @@ #if defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F722xx) #include "stm32f7xx.h" #include "stm32f7xx_hal.h" +#include "system_stm32f7xx.h" #include "stm32f7xx_ll_spi.h" #include "stm32f7xx_ll_gpio.h" diff --git a/src/main/target/common_fc_pre.h b/src/main/target/common_fc_pre.h index e23053565..ad1078704 100644 --- a/src/main/target/common_fc_pre.h +++ b/src/main/target/common_fc_pre.h @@ -67,6 +67,7 @@ #define I2C3_OVERCLOCK true #define I2C4_OVERCLOCK true #define USE_GYRO_DATA_ANALYSE +#define USE_OVERCLOCK #endif #if defined(STM32F4) || defined(STM32F7) diff --git a/src/main/target/system_stm32f7xx.c b/src/main/target/system_stm32f7xx.c index f44ef6232..0154865c9 100644 --- a/src/main/target/system_stm32f7xx.c +++ b/src/main/target/system_stm32f7xx.c @@ -64,6 +64,8 @@ */ #include "stm32f7xx.h" +#include "system_stm32f7xx.h" +#include "platform.h" #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)8000000) /*!< Default value of the External oscillator in Hz */ @@ -135,7 +137,9 @@ is no need to call the 2 first functions listed above, since SystemCoreClock variable is updated automatically. */ - uint32_t SystemCoreClock = (PLL_N / PLL_P) * 1000000; + uint32_t SystemCoreClock; + uint32_t pll_p = PLL_P, pll_n = PLL_N, pll_q = PLL_Q; + const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; @@ -178,9 +182,9 @@ RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = PLL_M; - RCC_OscInitStruct.PLL.PLLN = PLL_N; - RCC_OscInitStruct.PLL.PLLP = PLL_P; - RCC_OscInitStruct.PLL.PLLQ = PLL_Q; + RCC_OscInitStruct.PLL.PLLN = pll_n; + RCC_OscInitStruct.PLL.PLLP = pll_p; + RCC_OscInitStruct.PLL.PLLQ = pll_q; #endif ret = HAL_RCC_OscConfig(&RCC_OscInitStruct); @@ -244,6 +248,60 @@ SystemCoreClockUpdate(); } +typedef struct pllConfig_s { + uint16_t n; + uint16_t p; + uint16_t q; +} pllConfig_t; + +static const pllConfig_t overclockLevels[] = { + { PLL_N, PLL_P, PLL_Q }, // default + { 480, RCC_PLLP_DIV2, 10 }, // 240 MHz +}; + +// 8 bytes of memory located at the very end of RAM, expected to be unoccupied +#define REQUEST_OVERCLOCK (*(__IO uint32_t *) (BKPSRAM_BASE + 8)) +#define CURRENT_OVERCLOCK_LEVEL (*(__IO uint32_t *) (BKPSRAM_BASE + 12)) +#define REQUEST_OVERCLOCK_MAGIC_COOKIE 0xBABEFACE + +void SystemInitOC(void) { + __PWR_CLK_ENABLE(); + __BKPSRAM_CLK_ENABLE(); + HAL_PWR_EnableBkUpAccess(); + + if (REQUEST_OVERCLOCK_MAGIC_COOKIE == REQUEST_OVERCLOCK) { + const uint32_t overclockLevel = CURRENT_OVERCLOCK_LEVEL; + + /* PLL setting for overclocking */ + if (overclockLevel < ARRAYLEN(overclockLevels)) { + const pllConfig_t * const pll = overclockLevels + overclockLevel; + + pll_n = pll->n; + pll_p = pll->p; + pll_q = pll->q; + } + + REQUEST_OVERCLOCK = 0; + } +} + +void OverclockRebootIfNecessary(uint32_t overclockLevel) +{ + if (overclockLevel >= ARRAYLEN(overclockLevels)) { + return; + } + + const pllConfig_t * const pll = overclockLevels + overclockLevel; + + // Reboot to adjust overclock frequency + if (SystemCoreClock != (pll->n / pll->p) * 1000000) { + REQUEST_OVERCLOCK = REQUEST_OVERCLOCK_MAGIC_COOKIE; + CURRENT_OVERCLOCK_LEVEL = overclockLevel; + __disable_irq(); + NVIC_SystemReset(); + } +} + /** * @} */ @@ -261,6 +319,10 @@ */ void SystemInit(void) { + SystemInitOC(); + + SystemCoreClock = (pll_n / pll_p) * 1000000; + /* FPU settings ------------------------------------------------------------*/ #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ @@ -301,10 +363,10 @@ void SystemInit(void) SCB_EnableDCache(); } - /* Configure the system clock to 216 MHz */ + /* Configure the system clock to specified frequency */ SystemClock_Config(); - if (SystemCoreClock != (PLL_N / PLL_P) * 1000000) { + if (SystemCoreClock != (pll_n / pll_p) * 1000000) { // There is a mismatch between the configured clock and the expected clock in portable.h while (1); } diff --git a/src/main/target/system_stm32f7xx.h b/src/main/target/system_stm32f7xx.h index 695246fc3..73bfb8b0d 100644 --- a/src/main/target/system_stm32f7xx.h +++ b/src/main/target/system_stm32f7xx.h @@ -25,21 +25,23 @@ ****************************************************************************** */ -#ifndef __SYSTEM_STM32F7XX_H -#define __SYSTEM_STM32F7XX_H +#ifndef __TARGET_SYSTEM_STM32F7XX_H +#define __TARGET_SYSTEM_STM32F7XX_H #ifdef __cplusplus extern "C" { #endif extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ +extern void SystemInitOC(void); extern void SystemInit(void); extern void SystemClock_Config(void); +extern void OverclockRebootIfNecessary(uint32_t overclockLevel); #ifdef __cplusplus } #endif -#endif /*__SYSTEM_STM32F7XX_H */ +#endif /*__TARGET_SYSTEM_STM32F7XX_H */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/