diff --git a/firmware/console/eficonsole.cpp b/firmware/console/eficonsole.cpp index 76e838cae6..8d48a16257 100644 --- a/firmware/console/eficonsole.cpp +++ b/firmware/console/eficonsole.cpp @@ -43,8 +43,9 @@ static void sayHello(void) { efiPrintf(PROTOCOL_HELLO_PREFIX " COMPILER=%s", __VERSION__); #ifdef ENABLE_AUTO_DETECT_HSE + extern float hseFrequencyMhz; extern uint8_t autoDetectedPllMValue; - efiPrintf(PROTOCOL_HELLO_PREFIX " autoDetectedPllMValue=%d", autoDetectedPllMValue); + efiPrintf(PROTOCOL_HELLO_PREFIX " detected HSE clock %.2f MHz, PLLM = %d", hseFrequencyMhz, autoDetectedPllMValue); #endif /* ENABLE_AUTO_DETECT_HSE */ #if defined(STM32F4) || defined(STM32F7) diff --git a/firmware/hw_layer/ports/stm32/mcuconf_common_f4_f7.h b/firmware/hw_layer/ports/stm32/mcuconf_common_f4_f7.h index 08ac5adde2..c7039a90ae 100644 --- a/firmware/hw_layer/ports/stm32/mcuconf_common_f4_f7.h +++ b/firmware/hw_layer/ports/stm32/mcuconf_common_f4_f7.h @@ -324,11 +324,9 @@ */ #define STM32_WDG_USE_IWDG FALSE -// We auto detect the value of HSE, so set the default PLLM value to the maximum, -// so we don't accidentially overclock to processor before we know how fast HSE is -#define STM32_PLLM_VALUE 25 - -// This also means we have to pretend (for now) we have a 25MHz HSE fitted +// Pretend we have a 25MHz external crystal. This value isn't actually used since we +// configure the PLL to start on the HSI oscillator, then compute HSE's speed at runtime +// and reconfigure the PLL appropriately. #define STM32_HSECLK 25000000 // After boot, we will detect the real frequency, and adjust the PLL M value to suit diff --git a/firmware/hw_layer/ports/stm32/osc_detector.cpp b/firmware/hw_layer/ports/stm32/osc_detector.cpp index d8d22ade39..3104a78f6f 100644 --- a/firmware/hw_layer/ports/stm32/osc_detector.cpp +++ b/firmware/hw_layer/ports/stm32/osc_detector.cpp @@ -19,6 +19,7 @@ #ifdef ENABLE_AUTO_DETECT_HSE +float hseFrequencyMhz; uint8_t autoDetectedPllMValue; static void useHsi() { @@ -50,17 +51,15 @@ static uint32_t getAverageLsiCounts() { // Burn one count getOneCapture(); - uint32_t lastCapture = getOneCapture(); - uint32_t sum = 0; + uint32_t firstCapture = getOneCapture(); + uint32_t lastCapture; for (size_t i = 0; i < 20; i++) { - auto capture = getOneCapture(); - sum += (capture - lastCapture); - lastCapture = capture; + lastCapture = getOneCapture(); } - return sum; + return lastCapture - firstCapture; } // This only works if you're using the PLL as the configured clock source! @@ -78,11 +77,13 @@ static void reprogramPll(uint8_t pllM) { // Stop the PLL RCC->CR &= ~RCC_CR_PLLON; - // Mask out the old PLLM val - RCC->PLLCFGR &= ~RCC_PLLCFGR_PLLM_Msk; + // Mask out the old PLLM and PLLSRC + RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLM_Msk | RCC_PLLCFGR_PLLSRC_Msk); // Stick in the new PLLM value RCC->PLLCFGR |= (pllM << RCC_PLLCFGR_PLLM_Pos) & RCC_PLLCFGR_PLLM_Msk; + // Set PLLSRC to HSE + RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSE; // Reenable PLL, wait for lock RCC->CR |= RCC_CR_PLLON; @@ -122,8 +123,9 @@ extern "C" void __late_init() { RCC->APB1ENR &= ~RCC_APB1ENR_TIM5EN; // The external clocks's frequency is the ratio of the measured LSI speed, times HSI's speed (16MHz) - float hseFrequencyMhz = 16.0f * hseCounts / hsiCounts; + constexpr float hsiMhz = STM32_HSICLK * 1e-6; + hseFrequencyMhz = hsiMhz * hseCounts / hsiCounts; autoDetectedPllMValue = efiRound(hseFrequencyMhz, 1); reprogramPll(autoDetectedPllMValue); diff --git a/firmware/hw_layer/ports/stm32/stm32f4/cfg/mcuconf.h b/firmware/hw_layer/ports/stm32/stm32f4/cfg/mcuconf.h index 4b2729953c..00233b8b25 100644 --- a/firmware/hw_layer/ports/stm32/stm32f4/cfg/mcuconf.h +++ b/firmware/hw_layer/ports/stm32/stm32f4/cfg/mcuconf.h @@ -51,8 +51,8 @@ #define STM32_CLOCK48_REQUIRED TRUE #define STM32_SW STM32_SW_PLL -#define STM32_PLLSRC STM32_PLLSRC_HSE - +#define STM32_PLLSRC STM32_PLLSRC_HSI +#define STM32_PLLM_VALUE 16 #define STM32_PLLN_VALUE 336 #define STM32_PLLP_VALUE 2 #define STM32_PLLQ_VALUE 7 diff --git a/firmware/hw_layer/ports/stm32/stm32f7/cfg/mcuconf.h b/firmware/hw_layer/ports/stm32/stm32f7/cfg/mcuconf.h index 1c2b440fb8..a6f5495519 100644 --- a/firmware/hw_layer/ports/stm32/stm32f7/cfg/mcuconf.h +++ b/firmware/hw_layer/ports/stm32/stm32f7/cfg/mcuconf.h @@ -72,7 +72,8 @@ #define STM32_LSE_ENABLED FALSE #define STM32_CLOCK48_REQUIRED TRUE #define STM32_SW STM32_SW_PLL -#define STM32_PLLSRC STM32_PLLSRC_HSE +#define STM32_PLLSRC STM32_PLLSRC_HSI +#define STM32_PLLM_VALUE 16 #define STM32_PLLN_VALUE 432 #define STM32_PLLP_VALUE 2 #define STM32_PLLQ_VALUE 9