Skip to content
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
54ca41e
getFlashFrequencyMHz
Jason2866 Oct 5, 2025
a74b0f1
Refactor source frequency logic for ESP32
Jason2866 Oct 5, 2025
089f808
fix compile for esp32
Jason2866 Oct 5, 2025
ddbc739
Add default case for core clock selection
Jason2866 Oct 5, 2025
e1d7cfb
move in Esp.cpp
Jason2866 Oct 5, 2025
1c01e9c
Refactor flash clock register base address usage
Jason2866 Oct 6, 2025
b5df482
Refactor flash frequency functions with HAL support
Jason2866 Oct 6, 2025
b64562d
Update Esp.cpp
Jason2866 Oct 6, 2025
fa6c42a
Remove isFlashHighPerformanceModeEnabled function
Jason2866 Oct 6, 2025
d5386b9
Remove HPM Mode check from debug report
Jason2866 Oct 6, 2025
59c3ee7
Improve getFlashClockDivider documentation and logic
Jason2866 Oct 6, 2025
a9f3ba8
Refactor getFlashClockDivider for ESP32 target
Jason2866 Oct 6, 2025
72c641a
Add includes for ESP32P4 and ESP32C5 targets
Jason2866 Oct 6, 2025
832de97
Update includes for ESP32 target configurations
Jason2866 Oct 6, 2025
65015d5
Refactor includes for ESP32 chip compatibility
Jason2866 Oct 6, 2025
2390a54
Refactor flash chip mode handling for ESP32 variants
Jason2866 Oct 6, 2025
de103cd
Update getFlashChipMode for ESP32C5 target support
Jason2866 Oct 6, 2025
7e9dfef
Refactor getFlashClockDivider comments for clarity
Jason2866 Oct 6, 2025
bb19d7d
Update clock handling for ESP32-C5
Jason2866 Oct 6, 2025
4fcd51a
Merge branch 'espressif:master' into master
Jason2866 Oct 7, 2025
934cafd
SPI1 not SPI0
Jason2866 Oct 7, 2025
5d22dfc
c5 fix
Jason2866 Oct 7, 2025
eb8203a
update comments
Jason2866 Oct 7, 2025
3d1180d
ci(pre-commit): Apply automatic fixes
pre-commit-ci-lite[bot] Oct 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 76 additions & 8 deletions cores/esp32/Esp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,22 @@ extern "C" {
#include "esp_chip_info.h"
#include "esp_mac.h"
#include "esp_flash.h"

// Include HAL layer for flash clock access
#include "hal/spi_flash_ll.h"
#if CONFIG_IDF_TARGET_ESP32
#include "soc/spi_struct.h"
#else
// All modern chips (S2, S3, C2, C3, C5, C6, H2, P4) use spimem
#include "hal/spimem_flash_ll.h"
// Try to include the newer c_struct header first, fall back to regular struct
#if __has_include("soc/spi_mem_c_struct.h")
#include "soc/spi_mem_c_struct.h"
#else
#include "soc/spi_mem_struct.h"
#endif
#endif

#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
#include "esp32/rom/spi_flash.h"
Expand Down Expand Up @@ -348,17 +364,13 @@ uint32_t EspClass::getFlashChipSpeed(void) {
return magicFlashChipSpeed(fhdr.spi_speed);
}

// FIXME for P4
#if !defined(CONFIG_IDF_TARGET_ESP32P4)
FlashMode_t EspClass::getFlashChipMode(void) {
#if CONFIG_IDF_TARGET_ESP32S2
#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5
uint32_t spi_ctrl = REG_READ(PERIPHS_SPI_FLASH_CTRL);
#else
#if CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6
#elif CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6
uint32_t spi_ctrl = REG_READ(DR_REG_SPI0_BASE + 0x8);
#else
uint32_t spi_ctrl = REG_READ(SPI_CTRL_REG(0));
#endif
#endif
/* Not all of the following constants are already defined in older versions of spi_reg.h, so do it manually for now*/
if (spi_ctrl & BIT(24)) { //SPI_FREAD_QIO
Expand All @@ -374,9 +386,7 @@ FlashMode_t EspClass::getFlashChipMode(void) {
} else {
return (FM_SLOW_READ);
}
return (FM_DOUT);
}
#endif // if !defined(CONFIG_IDF_TARGET_ESP32P4)

uint32_t EspClass::magicFlashChipSize(uint8_t flashByte) {
/*
Expand Down Expand Up @@ -516,3 +526,61 @@ uint64_t EspClass::getEfuseMac(void) {
esp_efuse_mac_get_default((uint8_t *)(&_chipmacid));
return _chipmacid;
}

// ============================================================================
// Flash Frequency Runtime Detection
// ============================================================================

/**
* @brief Read the source clock frequency using ESP-IDF HAL functions
* @return Source clock frequency in MHz (80, 120, 160, or 240)
*/
uint8_t EspClass::getFlashSourceFrequencyMHz(void) {
#if CONFIG_IDF_TARGET_ESP32
// ESP32: Use HAL function
return spi_flash_ll_get_source_clock_freq_mhz(0); // host_id = 0 for SPI0
#else
// All modern MCUs: Use spimem HAL function
return spimem_flash_ll_get_source_freq_mhz();
#endif
}

/**
* @brief Read the clock divider from hardware using HAL structures
* Based on ESP-IDF HAL implementation:
* - ESP32: Uses SPI1.clock (typedef in spi_flash_ll.h)
* - All newer MCUs: Use SPIMEM1.clock (typedef in spimem_flash_ll.h)
* @return Clock divider value (1 = no division, 2 = divide by 2, etc.)
*/
uint8_t EspClass::getFlashClockDivider(void) {
#if CONFIG_IDF_TARGET_ESP32
// ESP32: Flash uses SPI1
// See: line 52: esp-idf/components/hal/esp32/include/hal/spi_flash_ll.h
if (SPI1.clock.clk_equ_sysclk) {
return 1; // 1:1 clock
}
return SPI1.clock.clkcnt_n + 1;
#else
// All newer MCUs: Flash uses SPIMEM1
// See: esp-idf/components/hal/esp32*/include/hal/spimem_flash_ll.h
// Example S3: line 38: typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
// Example C5: lines 97-99: esp-idf/components/soc/esp32c5/mp/include/soc/spi_mem_struct.h
if (SPIMEM1.clock.clk_equ_sysclk) {
return 1; // 1:1 clock
}
return SPIMEM1.clock.clkcnt_n + 1;
#endif
}

/**
* @brief Get the actual flash frequency in MHz
* @return Flash frequency in MHz (80, 120, 160, or 240)
*/
uint32_t EspClass::getFlashFrequencyMHz(void) {
uint8_t source = getFlashSourceFrequencyMHz();
uint8_t divider = getFlashClockDivider();

if (divider == 0) divider = 1; // Safety check

return source / divider;
}
5 changes: 5 additions & 0 deletions cores/esp32/Esp.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,11 @@ class EspClass {
uint32_t getFlashChipSpeed();
FlashMode_t getFlashChipMode();

// Flash frequency runtime detection
uint32_t getFlashFrequencyMHz();
uint8_t getFlashSourceFrequencyMHz();
uint8_t getFlashClockDivider();

uint32_t magicFlashChipSize(uint8_t flashByte);
uint32_t magicFlashChipSpeed(uint8_t flashByte);
FlashMode_t magicFlashChipMode(uint8_t flashByte);
Expand Down
30 changes: 11 additions & 19 deletions cores/esp32/chip-debug-report.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@
#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
#include "esp_bit_defs.h"

#include "Arduino.h"
#include "esp32-hal-periman.h"
#include "chip-debug-report.h"

#define chip_report_printf log_printf

Expand Down Expand Up @@ -138,25 +140,15 @@ 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 = 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);

chip_report_printf(" Bus Mode : ");
#if CONFIG_ESPTOOLPY_OCT_FLASH
chip_report_printf("OPI\n");
Expand Down
Loading