Skip to content

Commit b5df482

Browse files
authored
Refactor flash frequency functions with HAL support
Refactor flash frequency functions to use ESP-IDF HAL for better maintainability and chip-specific handling.
1 parent 1c01e9c commit b5df482

File tree

1 file changed

+66
-45
lines changed

1 file changed

+66
-45
lines changed

cores/esp32/Esp.cpp

Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ extern "C" {
3636
#include "esp_chip_info.h"
3737
#include "esp_mac.h"
3838
#include "esp_flash.h"
39+
40+
// Include for HPM (High Performance Mode) functions
41+
#if CONFIG_SPI_FLASH_HPM_ON
42+
#include "esp_private/spi_flash_os.h"
43+
#endif
44+
45+
// Include HAL layer for flash clock access
46+
#include "hal/spi_flash_ll.h"
47+
#if !CONFIG_IDF_TARGET_ESP32
48+
#include "hal/spimem_flash_ll.h"
49+
#endif
50+
3951
#ifdef ESP_IDF_VERSION_MAJOR // IDF 4+
4052
#if CONFIG_IDF_TARGET_ESP32 // ESP32/PICO-D4
4153
#include "esp32/rom/spi_flash.h"
@@ -521,71 +533,51 @@ uint64_t EspClass::getEfuseMac(void) {
521533
// Flash Frequency Runtime Detection
522534
// ============================================================================
523535

524-
// Note: DR_REG_SPI0_BASE is defined in soc/soc.h or soc/reg_base.h for each chip
525-
526-
// Register offsets
527-
#define FLASH_CORE_CLK_SEL_OFFSET 0x80
528-
#define FLASH_CLOCK_OFFSET 0x14
536+
// Note: Using ESP-IDF HAL layer functions instead of direct register access
537+
// for better maintainability and chip-specific handling
529538

530539
/**
531-
* @brief Read the source clock frequency from hardware registers
540+
* @brief Read the source clock frequency using ESP-IDF HAL functions
532541
* @return Source clock frequency in MHz (80, 120, 160, or 240)
533542
*/
534543
uint8_t EspClass::getFlashSourceFrequencyMHz(void) {
535544
#if CONFIG_IDF_TARGET_ESP32
536-
// ESP32 classic supports 40 MHz and 80 MHz
537-
// Note: ESP32 uses the PLL clock (80 MHz) as source and divides it
538-
return 80; // Always 80 MHz source, divider determines 40/80 MHz
545+
// ESP32 classic: Use HAL function
546+
return spi_flash_ll_get_source_clock_freq_mhz(0); // host_id = 0 for SPI0
539547
#else
540-
volatile uint32_t* core_clk_reg = (volatile uint32_t*)(DR_REG_SPI0_BASE + FLASH_CORE_CLK_SEL_OFFSET);
541-
uint32_t core_clk_sel = (*core_clk_reg) & 0x3; // Bits 0-1
542-
543-
uint8_t source_freq = 80; // Default
544-
545-
#if CONFIG_IDF_TARGET_ESP32S3
546-
switch (core_clk_sel) {
547-
case 0: source_freq = 80; break;
548-
case 1: source_freq = 120; break;
549-
case 2: source_freq = 160; break;
550-
case 3: source_freq = 240; break;
551-
}
552-
#elif CONFIG_IDF_TARGET_ESP32S2
553-
switch (core_clk_sel) {
554-
case 0: source_freq = 80; break;
555-
case 1: source_freq = 120; break;
556-
case 2: source_freq = 160; break;
557-
}
558-
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || \
559-
CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
560-
switch (core_clk_sel) {
561-
case 0: source_freq = 80; break;
562-
case 1: source_freq = 120; break;
563-
}
564-
#else
565-
switch (core_clk_sel) {
566-
case 0: source_freq = 80; break;
567-
case 1: source_freq = 120; break;
568-
default: source_freq = 80; break;
569-
}
570-
#endif
571-
572-
return source_freq;
548+
// For newer chips (S2, S3, C2, C3, C6, H2): Use spimem HAL function
549+
return spimem_flash_ll_get_source_freq_mhz();
573550
#endif
574551
}
575552

576553
/**
577-
* @brief Read the clock divider from hardware registers
554+
* @brief Read the clock divider from hardware using HAL abstraction
578555
* @return Clock divider value (1 = no division, 2 = divide by 2, etc.)
556+
*
557+
* @note This function still reads hardware registers but uses chip-specific
558+
* base addresses from ESP-IDF HAL layer
579559
*/
580560
uint8_t EspClass::getFlashClockDivider(void) {
581-
volatile uint32_t* clock_reg = (volatile uint32_t*)(DR_REG_SPI0_BASE + FLASH_CLOCK_OFFSET);
561+
// Read CLOCK register using DR_REG_SPI0_BASE from soc/soc.h
562+
volatile uint32_t* clock_reg = (volatile uint32_t*)(DR_REG_SPI0_BASE + 0x14);
582563
uint32_t clock_val = *clock_reg;
583564

584565
// Bit 31: if set, clock is 1:1 (no divider)
585566
if (clock_val & (1 << 31)) {
586567
return 1;
587568
}
588569

570+
// Bits 16-23: clkdiv_pre
571+
// This is consistent across all ESP32 chips
572+
uint8_t clkdiv_pre = (clock_val >> 16) & 0xFF;
573+
return clkdiv_pre + 1;
574+
}
575+
576+
// Bit 31: if set, clock is 1:1 (no divider)
577+
if (clock_val & (1 << 31)) {
578+
return 1;
579+
}
580+
589581
// Bits 16-23: clkdiv_pre
590582
uint8_t clkdiv_pre = (clock_val >> 16) & 0xFF;
591583
return clkdiv_pre + 1;
@@ -607,7 +599,36 @@ uint32_t EspClass::getFlashFrequencyMHz(void) {
607599
/**
608600
* @brief Check if High Performance Mode is enabled
609601
* @return true if flash runs > 80 MHz, false otherwise
602+
*
603+
* @note This function combines hardware register reading with ESP-IDF HPM status
604+
* to provide accurate HPM detection across all scenarios.
610605
*/
611606
bool EspClass::isFlashHighPerformanceModeEnabled(void) {
612-
return getFlashFrequencyMHz() > 80;
607+
uint32_t freq = getFlashFrequencyMHz();
608+
609+
// Primary check: If frequency is > 80 MHz, HPM should be active
610+
if (freq <= 80) {
611+
return false;
612+
}
613+
614+
#if CONFIG_SPI_FLASH_HPM_ON
615+
// Secondary check: Use ESP-IDF HPM functions if available
616+
// spi_flash_hpm_dummy_adjust() returns true if HPM with dummy adjustment is active
617+
// Note: Some flash chips use other HPM methods (command, status register),
618+
// so we also trust the frequency reading
619+
bool hpm_dummy_active = spi_flash_hpm_dummy_adjust();
620+
621+
// If dummy adjust is active, definitely in HPM mode
622+
if (hpm_dummy_active) {
623+
return true;
624+
}
625+
626+
// If frequency > 80 MHz but dummy adjust not reported,
627+
// HPM might be enabled via other method (command/status register)
628+
// Trust the frequency reading in this case
629+
return true;
630+
#else
631+
// If HPM support not compiled in, rely on frequency reading only
632+
return true;
633+
#endif
613634
}

0 commit comments

Comments
 (0)