@@ -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 */  
534543uint8_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 */  
580560uint8_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 */  
611606bool  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