From 54ca41e60ced11b7931e83e8dd35b4c07c0aac49 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Sun, 5 Oct 2025 20:45:53 +0200 Subject: [PATCH 1/5] getFlashFrequencyMHz --- cores/esp32/chip-debug-report.cpp | 135 ++++++++++++++++++++++++++---- cores/esp32/chip-debug-report.h | 8 ++ 2 files changed, 125 insertions(+), 18 deletions(-) diff --git a/cores/esp32/chip-debug-report.cpp b/cores/esp32/chip-debug-report.cpp index 8592031ee3f..e3378edc65a 100644 --- a/cores/esp32/chip-debug-report.cpp +++ b/cores/esp32/chip-debug-report.cpp @@ -9,6 +9,7 @@ #include "soc/efuse_reg.h" #include "soc/rtc.h" #include "soc/spi_reg.h" +#include "soc/soc.h" #if CONFIG_IDF_TARGET_ESP32S2 #include "esp32s2/rom/spi_flash.h" #endif @@ -16,6 +17,7 @@ #include "Arduino.h" #include "esp32-hal-periman.h" +#include "chip-debug-report.h" #define chip_report_printf log_printf @@ -138,25 +140,19 @@ static void printFlashInfo(void) { chip_report_printf(" Block Size : %8lu B (%6.1f KB)\n", g_rom_flashchip.block_size, b2kb(g_rom_flashchip.block_size)); chip_report_printf(" Sector Size : %8lu B (%6.1f KB)\n", g_rom_flashchip.sector_size, b2kb(g_rom_flashchip.sector_size)); chip_report_printf(" Page Size : %8lu B (%6.1f KB)\n", g_rom_flashchip.page_size, b2kb(g_rom_flashchip.page_size)); - esp_image_header_t fhdr; - esp_flash_read(esp_flash_default_chip, (void *)&fhdr, ESP_FLASH_IMAGE_BASE, sizeof(esp_image_header_t)); - if (fhdr.magic == ESP_IMAGE_HEADER_MAGIC) { - uint32_t f_freq = 0; - switch (fhdr.spi_speed) { -#if CONFIG_IDF_TARGET_ESP32H2 - case 0x0: f_freq = 32; break; - case 0x2: f_freq = 16; break; - case 0xf: f_freq = 64; break; -#else - case 0x0: f_freq = 40; break; - case 0x1: f_freq = 26; break; - case 0x2: f_freq = 20; break; - case 0xf: f_freq = 80; break; -#endif - default: f_freq = fhdr.spi_speed; break; - } - chip_report_printf(" Bus Speed : %lu MHz\n", f_freq); + + // Runtime flash frequency detection from hardware registers + uint32_t actual_freq = getFlashFrequencyMHz(); + uint8_t source_freq = getFlashSourceFrequencyMHz(); + uint8_t divider = getFlashClockDivider(); + + chip_report_printf(" Bus Speed : %lu MHz\n", actual_freq); + chip_report_printf(" Flash Frequency : %lu MHz (source: %u MHz, divider: %u)\n", actual_freq, source_freq, divider); + + if (isFlashHighPerformanceModeEnabled()) { + chip_report_printf(" HPM Mode : Enabled (> 80 MHz)\n"); } + chip_report_printf(" Bus Mode : "); #if CONFIG_ESPTOOLPY_OCT_FLASH chip_report_printf("OPI\n"); @@ -345,3 +341,106 @@ void printAfterSetupInfo(void) { chip_report_printf("============ After Setup End =============\n"); delay(20); //allow the print to finish } + +// ============================================================================ +// Flash Frequency Runtime Detection +// ============================================================================ + +// Define SPI0 base addresses for different chips +#if CONFIG_IDF_TARGET_ESP32S3 + #define FLASH_SPI0_BASE 0x60003000 +#elif CONFIG_IDF_TARGET_ESP32S2 + #define FLASH_SPI0_BASE 0x3f402000 +#elif CONFIG_IDF_TARGET_ESP32C3 + #define FLASH_SPI0_BASE 0x60002000 +#elif CONFIG_IDF_TARGET_ESP32C2 + #define FLASH_SPI0_BASE 0x60002000 +#elif CONFIG_IDF_TARGET_ESP32C6 + #define FLASH_SPI0_BASE 0x60003000 +#elif CONFIG_IDF_TARGET_ESP32H2 + #define FLASH_SPI0_BASE 0x60003000 +#elif CONFIG_IDF_TARGET_ESP32 + #define FLASH_SPI0_BASE 0x3ff42000 +#else + #define FLASH_SPI0_BASE 0x60003000 // Default for new chips +#endif + +// Register offsets +#define FLASH_CORE_CLK_SEL_OFFSET 0x80 +#define FLASH_CLOCK_OFFSET 0x14 + +/** + * @brief Read the source clock frequency from hardware registers + * @return Source clock frequency in MHz (80, 120, 160, or 240) + */ +uint8_t getFlashSourceFrequencyMHz(void) { + volatile uint32_t* core_clk_reg = (volatile uint32_t*)(FLASH_SPI0_BASE + FLASH_CORE_CLK_SEL_OFFSET); + uint32_t core_clk_sel = (*core_clk_reg) & 0x3; // Bits 0-1 + + uint8_t source_freq = 80; // Default + +#if CONFIG_IDF_TARGET_ESP32S3 + switch (core_clk_sel) { + case 0: source_freq = 80; break; + case 1: source_freq = 120; break; + case 2: source_freq = 160; break; + case 3: source_freq = 240; break; + } +#elif CONFIG_IDF_TARGET_ESP32S2 + switch (core_clk_sel) { + case 0: source_freq = 80; break; + case 1: source_freq = 120; break; + case 2: source_freq = 160; break; + } +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || \ + CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 + switch (core_clk_sel) { + case 0: source_freq = 80; break; + case 1: source_freq = 120; break; + } +#elif CONFIG_IDF_TARGET_ESP32 + // ESP32 classic - simplified + source_freq = 80; +#endif + + return source_freq; +} + +/** + * @brief Read the clock divider from hardware registers + * @return Clock divider value (1 = no division, 2 = divide by 2, etc.) + */ +uint8_t getFlashClockDivider(void) { + volatile uint32_t* clock_reg = (volatile uint32_t*)(FLASH_SPI0_BASE + FLASH_CLOCK_OFFSET); + uint32_t clock_val = *clock_reg; + + // Bit 31: if set, clock is 1:1 (no divider) + if (clock_val & (1 << 31)) { + return 1; + } + + // Bits 16-23: clkdiv_pre + uint8_t clkdiv_pre = (clock_val >> 16) & 0xFF; + return clkdiv_pre + 1; +} + +/** + * @brief Get the actual flash frequency in MHz + * @return Flash frequency in MHz + */ +uint32_t getFlashFrequencyMHz(void) { + uint8_t source = getFlashSourceFrequencyMHz(); + uint8_t divider = getFlashClockDivider(); + + if (divider == 0) divider = 1; // Safety check + + return source / divider; +} + +/** + * @brief Check if High Performance Mode is enabled + * @return true if flash runs > 80 MHz, false otherwise + */ +bool isFlashHighPerformanceModeEnabled(void) { + return getFlashFrequencyMHz() > 80; +} diff --git a/cores/esp32/chip-debug-report.h b/cores/esp32/chip-debug-report.h index 5c2c8498722..b052e5618e8 100644 --- a/cores/esp32/chip-debug-report.h +++ b/cores/esp32/chip-debug-report.h @@ -5,5 +5,13 @@ */ #pragma once +#include + void printBeforeSetupInfo(void); void printAfterSetupInfo(void); + +// Flash frequency runtime detection +uint32_t getFlashFrequencyMHz(void); +uint8_t getFlashSourceFrequencyMHz(void); +uint8_t getFlashClockDivider(void); +bool isFlashHighPerformanceModeEnabled(void); From a74b0f106d5aed59a92f5072dcc6e11a339b524e Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 5 Oct 2025 20:54:26 +0200 Subject: [PATCH 2/5] Refactor source frequency logic for ESP32 Updated source frequency handling for ESP32 and ESP32S3 targets. --- cores/esp32/chip-debug-report.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/cores/esp32/chip-debug-report.cpp b/cores/esp32/chip-debug-report.cpp index e3378edc65a..778d3b5a613 100644 --- a/cores/esp32/chip-debug-report.cpp +++ b/cores/esp32/chip-debug-report.cpp @@ -379,7 +379,11 @@ uint8_t getFlashSourceFrequencyMHz(void) { uint8_t source_freq = 80; // Default -#if CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32 + // ESP32 classic supports 40 MHz and 80 MHz + // Note: ESP32 uses the PLL clock (80 MHz) as source and divides it + source_freq = 80; // Always 80 MHz source, divider determines 40/80 MHz +#elif CONFIG_IDF_TARGET_ESP32S3 switch (core_clk_sel) { case 0: source_freq = 80; break; case 1: source_freq = 120; break; @@ -398,9 +402,6 @@ uint8_t getFlashSourceFrequencyMHz(void) { case 0: source_freq = 80; break; case 1: source_freq = 120; break; } -#elif CONFIG_IDF_TARGET_ESP32 - // ESP32 classic - simplified - source_freq = 80; #endif return source_freq; From 089f808b0019ec90366727f0fbb4bb93a9a98e0f Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 5 Oct 2025 21:00:00 +0200 Subject: [PATCH 3/5] fix compile for esp32 --- cores/esp32/chip-debug-report.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cores/esp32/chip-debug-report.cpp b/cores/esp32/chip-debug-report.cpp index 778d3b5a613..993db5e7d82 100644 --- a/cores/esp32/chip-debug-report.cpp +++ b/cores/esp32/chip-debug-report.cpp @@ -374,16 +374,17 @@ void printAfterSetupInfo(void) { * @return Source clock frequency in MHz (80, 120, 160, or 240) */ uint8_t getFlashSourceFrequencyMHz(void) { +#if CONFIG_IDF_TARGET_ESP32 + // ESP32 classic supports 40 MHz and 80 MHz + // Note: ESP32 uses the PLL clock (80 MHz) as source and divides it + return 80; // Always 80 MHz source, divider determines 40/80 MHz +#else volatile uint32_t* core_clk_reg = (volatile uint32_t*)(FLASH_SPI0_BASE + FLASH_CORE_CLK_SEL_OFFSET); uint32_t core_clk_sel = (*core_clk_reg) & 0x3; // Bits 0-1 uint8_t source_freq = 80; // Default -#if CONFIG_IDF_TARGET_ESP32 - // ESP32 classic supports 40 MHz and 80 MHz - // Note: ESP32 uses the PLL clock (80 MHz) as source and divides it - source_freq = 80; // Always 80 MHz source, divider determines 40/80 MHz -#elif CONFIG_IDF_TARGET_ESP32S3 +#if CONFIG_IDF_TARGET_ESP32S3 switch (core_clk_sel) { case 0: source_freq = 80; break; case 1: source_freq = 120; break; @@ -405,6 +406,7 @@ uint8_t getFlashSourceFrequencyMHz(void) { #endif return source_freq; +#endif } /** From ddbc73971f141883bec40e97f4b7997b1adabbaa Mon Sep 17 00:00:00 2001 From: Jason2866 <24528715+Jason2866@users.noreply.github.com> Date: Sun, 5 Oct 2025 21:04:55 +0200 Subject: [PATCH 4/5] Add default case for core clock selection --- cores/esp32/chip-debug-report.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cores/esp32/chip-debug-report.cpp b/cores/esp32/chip-debug-report.cpp index 993db5e7d82..99616d7bbc5 100644 --- a/cores/esp32/chip-debug-report.cpp +++ b/cores/esp32/chip-debug-report.cpp @@ -403,6 +403,12 @@ uint8_t getFlashSourceFrequencyMHz(void) { case 0: source_freq = 80; break; case 1: source_freq = 120; break; } +#else + switch (core_clk_sel) { + case 0: source_freq = 80; break; + case 1: source_freq = 120; break; + default: source_freq = 80; break; + } #endif return source_freq; From e1d7cfb7d4e3e19a7705bae774840c3b055281db Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Mon, 6 Oct 2025 00:21:04 +0200 Subject: [PATCH 5/5] move in Esp.cpp --- cores/esp32/Esp.cpp | 112 ++++++++++++++++++++++++++++ cores/esp32/Esp.h | 6 ++ cores/esp32/chip-debug-report.cpp | 120 +----------------------------- cores/esp32/chip-debug-report.h | 8 -- 4 files changed, 122 insertions(+), 124 deletions(-) diff --git a/cores/esp32/Esp.cpp b/cores/esp32/Esp.cpp index 061404977f9..be7b18290d1 100644 --- a/cores/esp32/Esp.cpp +++ b/cores/esp32/Esp.cpp @@ -516,3 +516,115 @@ uint64_t EspClass::getEfuseMac(void) { esp_efuse_mac_get_default((uint8_t *)(&_chipmacid)); return _chipmacid; } + +// ============================================================================ +// Flash Frequency Runtime Detection +// ============================================================================ + +// Define SPI0 base addresses for different chips +#if CONFIG_IDF_TARGET_ESP32S3 + #define FLASH_SPI0_BASE 0x60003000 +#elif CONFIG_IDF_TARGET_ESP32S2 + #define FLASH_SPI0_BASE 0x3f402000 +#elif CONFIG_IDF_TARGET_ESP32C3 + #define FLASH_SPI0_BASE 0x60002000 +#elif CONFIG_IDF_TARGET_ESP32C2 + #define FLASH_SPI0_BASE 0x60002000 +#elif CONFIG_IDF_TARGET_ESP32C6 + #define FLASH_SPI0_BASE 0x60003000 +#elif CONFIG_IDF_TARGET_ESP32H2 + #define FLASH_SPI0_BASE 0x60003000 +#elif CONFIG_IDF_TARGET_ESP32 + #define FLASH_SPI0_BASE 0x3ff42000 +#else + #define FLASH_SPI0_BASE 0x60003000 // Default for new chips +#endif + +// Register offsets +#define FLASH_CORE_CLK_SEL_OFFSET 0x80 +#define FLASH_CLOCK_OFFSET 0x14 + +/** + * @brief Read the source clock frequency from hardware registers + * @return Source clock frequency in MHz (80, 120, 160, or 240) + */ +uint8_t EspClass::getFlashSourceFrequencyMHz(void) { +#if CONFIG_IDF_TARGET_ESP32 + // ESP32 classic supports 40 MHz and 80 MHz + // Note: ESP32 uses the PLL clock (80 MHz) as source and divides it + return 80; // Always 80 MHz source, divider determines 40/80 MHz +#else + volatile uint32_t* core_clk_reg = (volatile uint32_t*)(FLASH_SPI0_BASE + FLASH_CORE_CLK_SEL_OFFSET); + uint32_t core_clk_sel = (*core_clk_reg) & 0x3; // Bits 0-1 + + uint8_t source_freq = 80; // Default + +#if CONFIG_IDF_TARGET_ESP32S3 + switch (core_clk_sel) { + case 0: source_freq = 80; break; + case 1: source_freq = 120; break; + case 2: source_freq = 160; break; + case 3: source_freq = 240; break; + } +#elif CONFIG_IDF_TARGET_ESP32S2 + switch (core_clk_sel) { + case 0: source_freq = 80; break; + case 1: source_freq = 120; break; + case 2: source_freq = 160; break; + } +#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || \ + CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 + switch (core_clk_sel) { + case 0: source_freq = 80; break; + case 1: source_freq = 120; break; + } +#else + switch (core_clk_sel) { + case 0: source_freq = 80; break; + case 1: source_freq = 120; break; + default: source_freq = 80; break; + } +#endif + + return source_freq; +#endif +} + +/** + * @brief Read the clock divider from hardware registers + * @return Clock divider value (1 = no division, 2 = divide by 2, etc.) + */ +uint8_t EspClass::getFlashClockDivider(void) { + volatile uint32_t* clock_reg = (volatile uint32_t*)(FLASH_SPI0_BASE + FLASH_CLOCK_OFFSET); + uint32_t clock_val = *clock_reg; + + // Bit 31: if set, clock is 1:1 (no divider) + if (clock_val & (1 << 31)) { + return 1; + } + + // Bits 16-23: clkdiv_pre + uint8_t clkdiv_pre = (clock_val >> 16) & 0xFF; + return clkdiv_pre + 1; +} + +/** + * @brief Get the actual flash frequency in MHz + * @return Flash frequency in MHz + */ +uint32_t EspClass::getFlashFrequencyMHz(void) { + uint8_t source = getFlashSourceFrequencyMHz(); + uint8_t divider = getFlashClockDivider(); + + if (divider == 0) divider = 1; // Safety check + + return source / divider; +} + +/** + * @brief Check if High Performance Mode is enabled + * @return true if flash runs > 80 MHz, false otherwise + */ +bool EspClass::isFlashHighPerformanceModeEnabled(void) { + return getFlashFrequencyMHz() > 80; +} diff --git a/cores/esp32/Esp.h b/cores/esp32/Esp.h index 0b496c91c1b..1f0b8490885 100644 --- a/cores/esp32/Esp.h +++ b/cores/esp32/Esp.h @@ -92,6 +92,12 @@ class EspClass { uint32_t getFlashChipSpeed(); FlashMode_t getFlashChipMode(); + // Flash frequency runtime detection + uint32_t getFlashFrequencyMHz(); + uint8_t getFlashSourceFrequencyMHz(); + uint8_t getFlashClockDivider(); + bool isFlashHighPerformanceModeEnabled(); + uint32_t magicFlashChipSize(uint8_t flashByte); uint32_t magicFlashChipSpeed(uint8_t flashByte); FlashMode_t magicFlashChipMode(uint8_t flashByte); diff --git a/cores/esp32/chip-debug-report.cpp b/cores/esp32/chip-debug-report.cpp index 99616d7bbc5..09a27571574 100644 --- a/cores/esp32/chip-debug-report.cpp +++ b/cores/esp32/chip-debug-report.cpp @@ -142,14 +142,14 @@ static void printFlashInfo(void) { chip_report_printf(" Page Size : %8lu B (%6.1f KB)\n", g_rom_flashchip.page_size, b2kb(g_rom_flashchip.page_size)); // Runtime flash frequency detection from hardware registers - uint32_t actual_freq = getFlashFrequencyMHz(); - uint8_t source_freq = getFlashSourceFrequencyMHz(); - uint8_t divider = getFlashClockDivider(); + uint32_t actual_freq = ESP.getFlashFrequencyMHz(); + uint8_t source_freq = ESP.getFlashSourceFrequencyMHz(); + uint8_t divider = ESP.getFlashClockDivider(); chip_report_printf(" Bus Speed : %lu MHz\n", actual_freq); chip_report_printf(" Flash Frequency : %lu MHz (source: %u MHz, divider: %u)\n", actual_freq, source_freq, divider); - if (isFlashHighPerformanceModeEnabled()) { + if (ESP.isFlashHighPerformanceModeEnabled()) { chip_report_printf(" HPM Mode : Enabled (> 80 MHz)\n"); } @@ -341,115 +341,3 @@ void printAfterSetupInfo(void) { chip_report_printf("============ After Setup End =============\n"); delay(20); //allow the print to finish } - -// ============================================================================ -// Flash Frequency Runtime Detection -// ============================================================================ - -// Define SPI0 base addresses for different chips -#if CONFIG_IDF_TARGET_ESP32S3 - #define FLASH_SPI0_BASE 0x60003000 -#elif CONFIG_IDF_TARGET_ESP32S2 - #define FLASH_SPI0_BASE 0x3f402000 -#elif CONFIG_IDF_TARGET_ESP32C3 - #define FLASH_SPI0_BASE 0x60002000 -#elif CONFIG_IDF_TARGET_ESP32C2 - #define FLASH_SPI0_BASE 0x60002000 -#elif CONFIG_IDF_TARGET_ESP32C6 - #define FLASH_SPI0_BASE 0x60003000 -#elif CONFIG_IDF_TARGET_ESP32H2 - #define FLASH_SPI0_BASE 0x60003000 -#elif CONFIG_IDF_TARGET_ESP32 - #define FLASH_SPI0_BASE 0x3ff42000 -#else - #define FLASH_SPI0_BASE 0x60003000 // Default for new chips -#endif - -// Register offsets -#define FLASH_CORE_CLK_SEL_OFFSET 0x80 -#define FLASH_CLOCK_OFFSET 0x14 - -/** - * @brief Read the source clock frequency from hardware registers - * @return Source clock frequency in MHz (80, 120, 160, or 240) - */ -uint8_t getFlashSourceFrequencyMHz(void) { -#if CONFIG_IDF_TARGET_ESP32 - // ESP32 classic supports 40 MHz and 80 MHz - // Note: ESP32 uses the PLL clock (80 MHz) as source and divides it - return 80; // Always 80 MHz source, divider determines 40/80 MHz -#else - volatile uint32_t* core_clk_reg = (volatile uint32_t*)(FLASH_SPI0_BASE + FLASH_CORE_CLK_SEL_OFFSET); - uint32_t core_clk_sel = (*core_clk_reg) & 0x3; // Bits 0-1 - - uint8_t source_freq = 80; // Default - -#if CONFIG_IDF_TARGET_ESP32S3 - switch (core_clk_sel) { - case 0: source_freq = 80; break; - case 1: source_freq = 120; break; - case 2: source_freq = 160; break; - case 3: source_freq = 240; break; - } -#elif CONFIG_IDF_TARGET_ESP32S2 - switch (core_clk_sel) { - case 0: source_freq = 80; break; - case 1: source_freq = 120; break; - case 2: source_freq = 160; break; - } -#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || \ - CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 - switch (core_clk_sel) { - case 0: source_freq = 80; break; - case 1: source_freq = 120; break; - } -#else - switch (core_clk_sel) { - case 0: source_freq = 80; break; - case 1: source_freq = 120; break; - default: source_freq = 80; break; - } -#endif - - return source_freq; -#endif -} - -/** - * @brief Read the clock divider from hardware registers - * @return Clock divider value (1 = no division, 2 = divide by 2, etc.) - */ -uint8_t getFlashClockDivider(void) { - volatile uint32_t* clock_reg = (volatile uint32_t*)(FLASH_SPI0_BASE + FLASH_CLOCK_OFFSET); - uint32_t clock_val = *clock_reg; - - // Bit 31: if set, clock is 1:1 (no divider) - if (clock_val & (1 << 31)) { - return 1; - } - - // Bits 16-23: clkdiv_pre - uint8_t clkdiv_pre = (clock_val >> 16) & 0xFF; - return clkdiv_pre + 1; -} - -/** - * @brief Get the actual flash frequency in MHz - * @return Flash frequency in MHz - */ -uint32_t getFlashFrequencyMHz(void) { - uint8_t source = getFlashSourceFrequencyMHz(); - uint8_t divider = getFlashClockDivider(); - - if (divider == 0) divider = 1; // Safety check - - return source / divider; -} - -/** - * @brief Check if High Performance Mode is enabled - * @return true if flash runs > 80 MHz, false otherwise - */ -bool isFlashHighPerformanceModeEnabled(void) { - return getFlashFrequencyMHz() > 80; -} diff --git a/cores/esp32/chip-debug-report.h b/cores/esp32/chip-debug-report.h index b052e5618e8..5c2c8498722 100644 --- a/cores/esp32/chip-debug-report.h +++ b/cores/esp32/chip-debug-report.h @@ -5,13 +5,5 @@ */ #pragma once -#include - void printBeforeSetupInfo(void); void printAfterSetupInfo(void); - -// Flash frequency runtime detection -uint32_t getFlashFrequencyMHz(void); -uint8_t getFlashSourceFrequencyMHz(void); -uint8_t getFlashClockDivider(void); -bool isFlashHighPerformanceModeEnabled(void);