mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
spi_flash: fixed issue that enabling HPM-DC by default may cause app unable to restart
This commit is contained in:
parent
ae0beef801
commit
c32a56fe3b
@ -62,34 +62,67 @@ menu "Bootloader config"
|
|||||||
default 4 if BOOTLOADER_LOG_LEVEL_DEBUG
|
default 4 if BOOTLOADER_LOG_LEVEL_DEBUG
|
||||||
default 5 if BOOTLOADER_LOG_LEVEL_VERBOSE
|
default 5 if BOOTLOADER_LOG_LEVEL_VERBOSE
|
||||||
|
|
||||||
config BOOTLOADER_SPI_CUSTOM_WP_PIN
|
menu "Serial Flash Configurations"
|
||||||
bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)"
|
config BOOTLOADER_SPI_CUSTOM_WP_PIN
|
||||||
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
|
bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)"
|
||||||
default y if BOOTLOADER_SPI_WP_PIN != 7 # backwards compatibility, can remove in IDF 5
|
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
|
||||||
default n
|
default y if BOOTLOADER_SPI_WP_PIN != 7 # backwards compatibility, can remove in IDF 5
|
||||||
help
|
default n
|
||||||
This setting is only used if the SPI flash pins have been overridden by setting the eFuses
|
help
|
||||||
SPI_PAD_CONFIG_xxx, and the SPI flash mode is QIO or QOUT.
|
This setting is only used if the SPI flash pins have been overridden by setting the eFuses
|
||||||
|
SPI_PAD_CONFIG_xxx, and the SPI flash mode is QIO or QOUT.
|
||||||
|
|
||||||
When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka
|
When this is the case, the eFuse config only defines 3 of the 4 Quad I/O data pins. The WP pin (aka
|
||||||
ESP32 pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. The same pin is also used
|
ESP32 pin "SD_DATA_3" or SPI flash pin "IO2") is not specified in eFuse. The same pin is also used
|
||||||
for external SPIRAM if it is enabled.
|
for external SPIRAM if it is enabled.
|
||||||
|
|
||||||
If this config item is set to N (default), the correct WP pin will be automatically used for any
|
If this config item is set to N (default), the correct WP pin will be automatically used for any
|
||||||
Espressif chip or module with integrated flash. If a custom setting is needed, set this config item to
|
Espressif chip or module with integrated flash. If a custom setting is needed, set this config item to
|
||||||
Y and specify the GPIO number connected to the WP.
|
Y and specify the GPIO number connected to the WP.
|
||||||
|
|
||||||
config BOOTLOADER_SPI_WP_PIN
|
config BOOTLOADER_SPI_WP_PIN
|
||||||
int "Custom SPI Flash WP Pin"
|
int "Custom SPI Flash WP Pin"
|
||||||
range 0 33
|
range 0 33
|
||||||
default 7
|
default 7
|
||||||
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
|
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
|
||||||
#depends on BOOTLOADER_SPI_CUSTOM_WP_PIN # backwards compatibility, can uncomment in IDF 5
|
#depends on BOOTLOADER_SPI_CUSTOM_WP_PIN # backwards compatibility, can uncomment in IDF 5
|
||||||
help
|
help
|
||||||
The option "Use custom SPI Flash WP Pin" must be set or this value is ignored
|
The option "Use custom SPI Flash WP Pin" must be set or this value is ignored
|
||||||
|
|
||||||
If burning a customized set of SPI flash pins in eFuse and using QIO or QOUT mode for flash, set this
|
If burning a customized set of SPI flash pins in eFuse and using QIO or QOUT mode for flash, set this
|
||||||
value to the GPIO number of the SPI flash WP pin.
|
value to the GPIO number of the SPI flash WP pin.
|
||||||
|
|
||||||
|
config BOOTLOADER_FLASH_DC_AWARE
|
||||||
|
bool "Allow app adjust Dummy Cycle bits in SPI Flash for higher frequency (READ HELP FIRST)"
|
||||||
|
help
|
||||||
|
This will force 2nd bootloader to be loaded by DOUT mode, and will restore Dummy Cycle setting by
|
||||||
|
resetting the Flash
|
||||||
|
|
||||||
|
config BOOTLOADER_FLASH_XMC_SUPPORT
|
||||||
|
bool "Enable the support for flash chips of XMC (READ DOCS FIRST)"
|
||||||
|
default y
|
||||||
|
depends on !IDF_ENV_BRINGUP
|
||||||
|
help
|
||||||
|
Perform the startup flow recommended by XMC. Please consult XMC for the details of this flow.
|
||||||
|
XMC chips will be forbidden to be used, when this option is disabled.
|
||||||
|
|
||||||
|
DON'T DISABLE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.
|
||||||
|
|
||||||
|
comment "Features below require specific hardware (READ DOCS FIRST!)"
|
||||||
|
|
||||||
|
config BOOTLOADER_FLASH_32BIT_ADDR
|
||||||
|
bool
|
||||||
|
default y if ESPTOOLPY_FLASHSIZE_32MB || ESPTOOLPY_FLASHSIZE_64MB || ESPTOOLPY_FLASHSIZE_128MB
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
This is a helper config for 32bits address flash. Invisible for users.
|
||||||
|
|
||||||
|
config BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
|
||||||
|
bool
|
||||||
|
default y if ESPTOOLPY_OCT_FLASH && SPI_FLASH_32BIT_ADDRESS
|
||||||
|
default n
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
choice BOOTLOADER_VDDSDIO_BOOST
|
choice BOOTLOADER_VDDSDIO_BOOST
|
||||||
bool "VDDSDIO LDO voltage"
|
bool "VDDSDIO LDO voltage"
|
||||||
@ -411,14 +444,6 @@ menu "Bootloader config"
|
|||||||
in this area of memory, you can increase it. It must be a multiple of 4 bytes.
|
in this area of memory, you can increase it. It must be a multiple of 4 bytes.
|
||||||
This area (rtc_retain_mem_t) is reserved and has access from the bootloader and an application.
|
This area (rtc_retain_mem_t) is reserved and has access from the bootloader and an application.
|
||||||
|
|
||||||
config BOOTLOADER_FLASH_XMC_SUPPORT
|
|
||||||
bool "Enable the support for flash chips of XMC (READ HELP FIRST)"
|
|
||||||
default y
|
|
||||||
help
|
|
||||||
Perform the startup flow recommended by XMC. Please consult XMC for the details of this flow.
|
|
||||||
XMC chips will be forbidden to be used, when this option is disabled.
|
|
||||||
|
|
||||||
DON'T DISABLE THIS UNLESS YOU KNOW WHAT YOU ARE DOING.
|
|
||||||
|
|
||||||
endmenu # Bootloader
|
endmenu # Bootloader
|
||||||
|
|
||||||
|
@ -23,3 +23,7 @@ CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE CONFIG_SECURE_FLASH_
|
|||||||
|
|
||||||
# Secure Boot Scheme
|
# Secure Boot Scheme
|
||||||
CONFIG_SECURE_BOOT_ENABLED CONFIG_SECURE_BOOT_V1_ENABLED
|
CONFIG_SECURE_BOOT_ENABLED CONFIG_SECURE_BOOT_V1_ENABLED
|
||||||
|
|
||||||
|
CONFIG_SPI_FLASH_32BIT_ADDR_ENABLE CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH
|
||||||
|
CONFIG_SPI_FLASH_QUAD_32BIT_ADDR_ENABLE CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH
|
||||||
|
CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
|
||||||
|
@ -210,7 +210,7 @@ static esp_err_t bootloader_init_spi_flash(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SPI_FLASH_HPM_ENABLE
|
#if CONFIG_BOOTLOADER_FLASH_DC_AWARE
|
||||||
// Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot.
|
// Reset flash, clear volatile bits DC[0:1]. Make it work under default mode to boot.
|
||||||
bootloader_spi_flash_reset();
|
bootloader_spi_flash_reset();
|
||||||
#endif
|
#endif
|
||||||
|
@ -79,7 +79,7 @@ menu "SPI RAM config"
|
|||||||
|
|
||||||
config SPIRAM_SPEED_120M
|
config SPIRAM_SPEED_120M
|
||||||
depends on SPIRAM_MODE_QUAD
|
depends on SPIRAM_MODE_QUAD
|
||||||
bool "120MHz clock speed"
|
bool "120MHz clock speed (READ DOCS FIRST)"
|
||||||
config SPIRAM_SPEED_80M
|
config SPIRAM_SPEED_80M
|
||||||
bool "80MHz clock speed"
|
bool "80MHz clock speed"
|
||||||
config SPIRAM_SPEED_40M
|
config SPIRAM_SPEED_40M
|
||||||
|
@ -73,9 +73,12 @@ menu "Serial flasher config"
|
|||||||
default ESPTOOLPY_FLASHFREQ_60M if IDF_TARGET_ESP32C2
|
default ESPTOOLPY_FLASHFREQ_60M if IDF_TARGET_ESP32C2
|
||||||
default ESPTOOLPY_FLASHFREQ_48M if IDF_TARGET_ESP32H2
|
default ESPTOOLPY_FLASHFREQ_48M if IDF_TARGET_ESP32H2
|
||||||
config ESPTOOLPY_FLASHFREQ_120M
|
config ESPTOOLPY_FLASHFREQ_120M
|
||||||
bool "120 MHz"
|
bool "120 MHz (READ DOCS FIRST)"
|
||||||
select SPI_FLASH_HPM_ENABLE
|
depends on SOC_MEMSPI_SRC_FREQ_120M && ESPTOOLPY_FLASH_SAMPLE_MODE_STR && \
|
||||||
depends on SOC_MEMSPI_SRC_FREQ_120M && ESPTOOLPY_FLASH_SAMPLE_MODE_STR
|
(SPI_FLASH_HPM_ON || ESPTOOLPY_OCT_FLASH)
|
||||||
|
help
|
||||||
|
- Optional feature for QSPI Flash. Read docs and enable `CONFIG_SPI_FLASH_HPM_ENA` first!
|
||||||
|
|
||||||
config ESPTOOLPY_FLASHFREQ_80M
|
config ESPTOOLPY_FLASHFREQ_80M
|
||||||
bool "80 MHz"
|
bool "80 MHz"
|
||||||
depends on SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
|
depends on SOC_MEMSPI_SRC_FREQ_80M_SUPPORTED
|
||||||
|
@ -20,7 +20,7 @@ set(ESPSECUREPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espsecure.py")
|
|||||||
set(ESPEFUSEPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espefuse.py")
|
set(ESPEFUSEPY ${python} "${CMAKE_CURRENT_LIST_DIR}/esptool/espefuse.py")
|
||||||
set(ESPMONITOR ${python} "${idf_path}/tools/idf_monitor.py")
|
set(ESPMONITOR ${python} "${idf_path}/tools/idf_monitor.py")
|
||||||
|
|
||||||
if(CONFIG_SPI_FLASH_HPM_ENABLE)
|
if(CONFIG_BOOTLOADER_FLASH_DC_AWARE)
|
||||||
# When set flash frequency to 120M, must keep 1st bootloader work under ``DOUT`` mode
|
# When set flash frequency to 120M, must keep 1st bootloader work under ``DOUT`` mode
|
||||||
# because on some flash chips, 120M will modify the status register,
|
# because on some flash chips, 120M will modify the status register,
|
||||||
# which will make ROM won't work.
|
# which will make ROM won't work.
|
||||||
|
@ -24,6 +24,11 @@ else()
|
|||||||
list(APPEND srcs
|
list(APPEND srcs
|
||||||
"esp32s3/spi_timing_config.c"
|
"esp32s3/spi_timing_config.c"
|
||||||
"spi_flash_timing_tuning.c"
|
"spi_flash_timing_tuning.c"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_SPI_FLASH_HPM_ON)
|
||||||
|
list(APPEND srcs
|
||||||
"spi_flash_hpm_enable.c")
|
"spi_flash_hpm_enable.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -1,3 +1,109 @@
|
|||||||
|
menu "Main Flash configuration"
|
||||||
|
depends on !APP_BUILD_TYPE_PURE_RAM_APP
|
||||||
|
|
||||||
|
menu "SPI Flash behavior when brownout"
|
||||||
|
|
||||||
|
config SPI_FLASH_BROWNOUT_RESET_XMC
|
||||||
|
bool "Enable sending reset when brownout for XMC flash chips"
|
||||||
|
default y
|
||||||
|
select SPI_FLASH_BROWNOUT_RESET
|
||||||
|
help
|
||||||
|
When this option is selected, the patch will be enabled for XMC.
|
||||||
|
Follow the recommended flow by XMC for better stability.
|
||||||
|
|
||||||
|
DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING.
|
||||||
|
|
||||||
|
config SPI_FLASH_BROWNOUT_RESET
|
||||||
|
bool
|
||||||
|
default y
|
||||||
|
select ESP_SYSTEM_BROWNOUT_INTR
|
||||||
|
help
|
||||||
|
When brownout happens during flash erase/write operations,
|
||||||
|
send reset command to stop the flash operations to improve stability.
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
|
||||||
|
menu "Optional and Experimental Features (READ DOCS FIRST)"
|
||||||
|
|
||||||
|
comment "Features here require specific hardware (READ DOCS FIRST!)"
|
||||||
|
|
||||||
|
config SPI_FLASH_UNDER_HIGH_FREQ
|
||||||
|
bool
|
||||||
|
default y if ESPTOOLPY_FLASHFREQ_120M
|
||||||
|
help
|
||||||
|
This is a helper config for HPM. Invisible for users.
|
||||||
|
|
||||||
|
choice SPI_FLASH_HPM
|
||||||
|
prompt "High Performance Mode (READ DOCS FIRST, > 80MHz)"
|
||||||
|
# Currently, only esp32s3 allows high performance mode.
|
||||||
|
depends on IDF_TARGET_ESP32S3 && !ESPTOOLPY_OCT_FLASH
|
||||||
|
default SPI_FLASH_HPM_AUTO
|
||||||
|
help
|
||||||
|
Whether the High Performance Mode of Flash is enabled. As an optional feature, user needs to manually
|
||||||
|
enable this option as a confirmation. To be back-compatible with earlier IDF versionn, this option is
|
||||||
|
automatically enabled with warning when Flash running > 80Mhz.
|
||||||
|
|
||||||
|
config SPI_FLASH_HPM_ENA
|
||||||
|
# Not using name of SPI_FLASH_HPM_ENABLE because it was used as an invisible option and we don't want
|
||||||
|
# to inherit the value of that one
|
||||||
|
bool "Enable"
|
||||||
|
config SPI_FLASH_HPM_AUTO
|
||||||
|
bool "Auto (Not recommended)"
|
||||||
|
config SPI_FLASH_HPM_DIS
|
||||||
|
bool "Disabled"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config SPI_FLASH_HPM_ON
|
||||||
|
bool
|
||||||
|
# For ESP32-S3, it's enabled by default. For later chips it should be disabled by default
|
||||||
|
default y if IDF_TARGET_ESP32S3 && ((SPI_FLASH_HPM_ENA || SPI_FLASH_HPM_AUTO)) || \
|
||||||
|
(!IDF_TARGET_ESP32S3 && SPI_FLASH_HPM_ENA)
|
||||||
|
help
|
||||||
|
This option is invisible, and will be selected automatically
|
||||||
|
when ``ESPTOOLPY_FLASHFREQ_120M`` is selected.
|
||||||
|
|
||||||
|
choice SPI_FLASH_HPM_DC
|
||||||
|
prompt "Support HPM using DC (READ DOCS FIRST)"
|
||||||
|
depends on SPI_FLASH_HPM_ON
|
||||||
|
default SPI_FLASH_HPM_DC_AUTO
|
||||||
|
help
|
||||||
|
This feature needs your bootloader to be compiled DC-aware (BOOTLOADER_FLASH_DC_AWARE=y). Otherwise the
|
||||||
|
chip will not be able to boot after a reset.
|
||||||
|
|
||||||
|
config SPI_FLASH_HPM_DC_AUTO
|
||||||
|
bool "Auto (Enable when bootloader support enabled (BOOTLOADER_FLASH_DC_AWARE))"
|
||||||
|
config SPI_FLASH_HPM_DC_DISABLE
|
||||||
|
bool "Disable (READ DOCS FIRST)"
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config SPI_FLASH_HPM_DC_ON
|
||||||
|
bool
|
||||||
|
default y if SPI_FLASH_HPM_DC_AUTO && BOOTLOADER_FLASH_DC_AWARE
|
||||||
|
help
|
||||||
|
This is a helper config for HPM. Whether HPM-DC is enabled is also determined by bootloader.
|
||||||
|
Invisible for users.
|
||||||
|
|
||||||
|
config SPI_FLASH_AUTO_SUSPEND
|
||||||
|
bool "Auto suspend long erase/write operations (READ DOCS FIRST)"
|
||||||
|
default n
|
||||||
|
depends on IDF_TARGET_ESP32C3 && !SPI_FLASH_ROM_IMPL
|
||||||
|
help
|
||||||
|
This option is disabled by default because it is supported only
|
||||||
|
for specific flash chips and for specific Espressif chips.
|
||||||
|
To evaluate if you can use this feature refer to
|
||||||
|
`Optional Features for Flash` > `Auto Suspend & Resume` of the `ESP-IDF Programming Guide`.
|
||||||
|
|
||||||
|
CAUTION: If you want to OTA to an app with this feature turned on, please make
|
||||||
|
sure the bootloader has the support for it. (later than IDF v4.3)
|
||||||
|
|
||||||
|
If you are using an official Espressif module, please contact Espressif Business support
|
||||||
|
to check if the module has the flash that support this feature installed.
|
||||||
|
Also refer to `Concurrency Constraints for Flash on SPI1` > `Flash Auto Suspend Feature`
|
||||||
|
before enabling this option.
|
||||||
|
|
||||||
|
endmenu
|
||||||
|
endmenu
|
||||||
|
|
||||||
menu "SPI Flash driver"
|
menu "SPI Flash driver"
|
||||||
|
|
||||||
config SPI_FLASH_VERIFY_WRITE
|
config SPI_FLASH_VERIFY_WRITE
|
||||||
@ -148,20 +254,6 @@ menu "SPI Flash driver"
|
|||||||
help
|
help
|
||||||
Defines how many ticks will be before returning to continue a erasing.
|
Defines how many ticks will be before returning to continue a erasing.
|
||||||
|
|
||||||
config SPI_FLASH_AUTO_SUSPEND
|
|
||||||
bool "Auto suspend long erase/write operations (READ DOCS FIRST)"
|
|
||||||
default n
|
|
||||||
depends on IDF_TARGET_ESP32C3 && !SPI_FLASH_ROM_IMPL
|
|
||||||
help
|
|
||||||
This option is default n before ESP32-C3, because it needs bootloader support.
|
|
||||||
|
|
||||||
CAUTION: If you want to OTA to an app with this feature turned on, please make
|
|
||||||
sure the bootloader has the support for it. (later than IDF v4.3)
|
|
||||||
|
|
||||||
Auto-suspend feature only supported by XMC chip.
|
|
||||||
If you are using an official module, please contact Espressif Business support.
|
|
||||||
Also reading auto suspend part in `SPI Flash API` document before you enable this function.
|
|
||||||
|
|
||||||
config SPI_FLASH_WRITE_CHUNK_SIZE
|
config SPI_FLASH_WRITE_CHUNK_SIZE
|
||||||
int "Flash write chunk size"
|
int "Flash write chunk size"
|
||||||
default 8192
|
default 8192
|
||||||
@ -198,28 +290,6 @@ menu "SPI Flash driver"
|
|||||||
|
|
||||||
See example: custom_chip_driver under examples/storage for more details.
|
See example: custom_chip_driver under examples/storage for more details.
|
||||||
|
|
||||||
menu "SPI Flash behavior when brownout"
|
|
||||||
|
|
||||||
config SPI_FLASH_BROWNOUT_RESET_XMC
|
|
||||||
bool "Enable sending reset when brownout for XMC flash chips"
|
|
||||||
default y
|
|
||||||
select SPI_FLASH_BROWNOUT_RESET
|
|
||||||
help
|
|
||||||
When this option is selected, the patch will be enabled for XMC.
|
|
||||||
Follow the recommended flow by XMC for better stability.
|
|
||||||
|
|
||||||
DO NOT DISABLE UNLESS YOU KNOW WHAT YOU ARE DOING.
|
|
||||||
|
|
||||||
config SPI_FLASH_BROWNOUT_RESET
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
select ESP_SYSTEM_BROWNOUT_INTR
|
|
||||||
help
|
|
||||||
When brownout happens during flash erase/write operations,
|
|
||||||
send reset command to stop the flash operations to improve stability.
|
|
||||||
|
|
||||||
endmenu
|
|
||||||
|
|
||||||
menu "Auto-detect flash chips"
|
menu "Auto-detect flash chips"
|
||||||
visible if !SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST
|
visible if !SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST
|
||||||
|
|
||||||
@ -300,22 +370,4 @@ menu "SPI Flash driver"
|
|||||||
application is not using flash encryption feature and is in need of some additional
|
application is not using flash encryption feature and is in need of some additional
|
||||||
memory from IRAM region (~1KB) then this config can be disabled.
|
memory from IRAM region (~1KB) then this config can be disabled.
|
||||||
|
|
||||||
config SPI_FLASH_HPM_ENABLE
|
|
||||||
bool
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
This option is invisible, and will be selected automatically
|
|
||||||
when ``ESPTOOLPY_FLASHFREQ_120M`` is selected.
|
|
||||||
|
|
||||||
config SPI_FLASH_32BIT_ADDRESS
|
|
||||||
bool
|
|
||||||
default y if ESPTOOLPY_FLASHSIZE_32MB || ESPTOOLPY_FLASHSIZE_64MB || ESPTOOLPY_FLASHSIZE_128MB
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
This is a helper config for 32bits address flash. Invisible for users.
|
|
||||||
|
|
||||||
config SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE
|
|
||||||
bool
|
|
||||||
default y if ESPTOOLPY_OCT_FLASH && SPI_FLASH_32BIT_ADDRESS
|
|
||||||
default n
|
|
||||||
endmenu
|
endmenu
|
||||||
|
@ -145,8 +145,8 @@ static uint32_t spi_timing_config_get_dummy(void)
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_SPI_FLASH_HPM_ENABLE
|
#if CONFIG_SPI_FLASH_HPM_DC_ON
|
||||||
if (spi_flash_hpm_dummy_adjust()) { // HPM is enabled
|
if (spi_flash_hpm_dummy_adjust()) { // HPM-DC is enabled
|
||||||
const spi_flash_hpm_dummy_conf_t *hpm_dummy = spi_flash_hpm_get_dummy();
|
const spi_flash_hpm_dummy_conf_t *hpm_dummy = spi_flash_hpm_get_dummy();
|
||||||
switch (ctrl_reg & MULTI_LINE_MASK_QUAD_FLASH) {
|
switch (ctrl_reg & MULTI_LINE_MASK_QUAD_FLASH) {
|
||||||
case SPI_FLASH_QIO_MODE:
|
case SPI_FLASH_QIO_MODE:
|
||||||
@ -166,7 +166,7 @@ static uint32_t spi_timing_config_get_dummy(void)
|
|||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{ // HPM is not enabled
|
{ // HPM-DC is not enabled
|
||||||
switch (ctrl_reg & MULTI_LINE_MASK_QUAD_FLASH) {
|
switch (ctrl_reg & MULTI_LINE_MASK_QUAD_FLASH) {
|
||||||
case SPI_FLASH_QIO_MODE:
|
case SPI_FLASH_QIO_MODE:
|
||||||
return SPI1_R_QIO_DUMMY_CYCLELEN;
|
return SPI1_R_QIO_DUMMY_CYCLELEN;
|
||||||
|
@ -383,7 +383,7 @@ esp_err_t esp_flash_init_default_chip(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_SPI_FLASH_HPM_ENABLE
|
#if CONFIG_SPI_FLASH_HPM_DC_ON
|
||||||
if (spi_flash_hpm_dummy_adjust()) {
|
if (spi_flash_hpm_dummy_adjust()) {
|
||||||
default_chip.hpm_dummy_ena = 1;
|
default_chip.hpm_dummy_ena = 1;
|
||||||
}
|
}
|
||||||
|
@ -167,12 +167,10 @@ esp_err_t IRAM_ATTR spi_flash_init_chip_state(void)
|
|||||||
#if CONFIG_ESPTOOLPY_OCT_FLASH
|
#if CONFIG_ESPTOOLPY_OCT_FLASH
|
||||||
return esp_opiflash_init(rom_spiflash_legacy_data->chip.device_id);
|
return esp_opiflash_init(rom_spiflash_legacy_data->chip.device_id);
|
||||||
#else
|
#else
|
||||||
#if CONFIG_IDF_TARGET_ESP32S3
|
#if CONFIG_SPI_FLASH_HPM_ON
|
||||||
// Currently, only esp32s3 allows high performance mode.
|
|
||||||
return spi_flash_enable_high_performance_mode();
|
return spi_flash_enable_high_performance_mode();
|
||||||
#else
|
#endif // CONFIG_SPI_FLASH_HPM_ON
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
#endif // CONFIG_IDF_TARGET_ESP32S3
|
|
||||||
#endif // CONFIG_ESPTOOLPY_OCT_FLASH
|
#endif // CONFIG_ESPTOOLPY_OCT_FLASH
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +169,8 @@ esp_err_t esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size);
|
|||||||
esp_err_t esp_flash_get_physical_size(esp_flash_t *chip, uint32_t *flash_size);
|
esp_err_t esp_flash_get_physical_size(esp_flash_t *chip, uint32_t *flash_size);
|
||||||
|
|
||||||
/** @brief Read flash unique ID via the common "RDUID" SPI flash command.
|
/** @brief Read flash unique ID via the common "RDUID" SPI flash command.
|
||||||
|
*
|
||||||
|
* @note This is an optional feature, which is not supported on all flash chips. READ PROGRAMMING GUIDE FIRST!
|
||||||
*
|
*
|
||||||
* @param chip Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init().
|
* @param chip Pointer to identify flash chip. Must have been successfully initialised via esp_flash_init().
|
||||||
* @param[out] out_id Pointer to receive unique ID value.
|
* @param[out] out_id Pointer to receive unique ID value.
|
||||||
|
@ -153,9 +153,14 @@ void spi_flash_set_erasing_flag(bool status);
|
|||||||
*/
|
*/
|
||||||
bool spi_flash_brownout_need_reset(void);
|
bool spi_flash_brownout_need_reset(void);
|
||||||
|
|
||||||
|
#if CONFIG_SPI_FLASH_HPM_ON
|
||||||
/**
|
/**
|
||||||
* @brief Enable SPI flash high performance mode.
|
* @brief Enable SPI flash high performance mode.
|
||||||
*
|
*
|
||||||
|
* @note 1. When `CONFIG_SPI_FLASH_HPM_ON` is True, caller can always call this function without taking whether the used
|
||||||
|
* frequency falls into the HPM range into consideration.
|
||||||
|
* 2. However, caller shouldn't attempt to call this function on Octal flash.
|
||||||
|
*
|
||||||
* @return ESP_OK if success.
|
* @return ESP_OK if success.
|
||||||
*/
|
*/
|
||||||
esp_err_t spi_flash_enable_high_performance_mode(void);
|
esp_err_t spi_flash_enable_high_performance_mode(void);
|
||||||
@ -175,6 +180,7 @@ const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void);
|
|||||||
* @return true Yes, and work under HPM with adjusting dummy. Otherwise, false.
|
* @return true Yes, and work under HPM with adjusting dummy. Otherwise, false.
|
||||||
*/
|
*/
|
||||||
bool spi_flash_hpm_dummy_adjust(void);
|
bool spi_flash_hpm_dummy_adjust(void);
|
||||||
|
#endif //CONFIG_SPI_FLASH_HPM_ON
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FLASH_WRAP_MODE_8B = 0,
|
FLASH_WRAP_MODE_8B = 0,
|
||||||
|
@ -15,6 +15,8 @@ entries:
|
|||||||
spi_flash_timing_tuning (noflash)
|
spi_flash_timing_tuning (noflash)
|
||||||
spi_timing_config (noflash)
|
spi_timing_config (noflash)
|
||||||
spi_flash_chip_mxic_opi (noflash)
|
spi_flash_chip_mxic_opi (noflash)
|
||||||
|
|
||||||
|
if SPI_FLASH_HPM_ON = y:
|
||||||
spi_flash_hpm_enable (noflash)
|
spi_flash_hpm_enable (noflash)
|
||||||
|
|
||||||
if IDF_TARGET_ESP32S3 = y && ESPTOOLPY_OCT_FLASH = y:
|
if IDF_TARGET_ESP32S3 = y && ESPTOOLPY_OCT_FLASH = y:
|
||||||
|
@ -28,14 +28,22 @@
|
|||||||
* 3. Some flash chips adjust dummy cycles.
|
* 3. Some flash chips adjust dummy cycles.
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#if CONFIG_ESPTOOLPY_FLASHFREQ_120M
|
/*
|
||||||
#define FLASH_FREQUENCY 120
|
* Note: This file should only be compiled when HPM_ON, which is only available when !CONFIG_ESPTOOLPY_OCT_FLASH.
|
||||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_80M
|
* However when HPM_ON, there are still some cases this file is not actually used:
|
||||||
#define FLASH_FREQUENCY 80
|
*
|
||||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_40M
|
* - !CONFIG_SPI_FLASH_UNDER_HIGH_FREQ:
|
||||||
#define FLASH_FREQUENCY 40
|
* It mean that the flash not running under frequency requires HPM. spi_flash_enable_high_performance_mode() still
|
||||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_20M
|
* called because caller shouldn't take care of the frequency.
|
||||||
#define FLASH_FREQUENCY 20
|
*/
|
||||||
|
|
||||||
|
void spi_flash_hpm_get_dummy_generic(spi_flash_hpm_dummy_conf_t *dummy_conf);
|
||||||
|
|
||||||
|
#if CONFIG_SPI_FLASH_UNDER_HIGH_FREQ
|
||||||
|
|
||||||
|
#if CONFIG_SPI_FLASH_HPM_AUTO
|
||||||
|
// This only happens on S3, where HPM_AUTO leads to HPM_ON
|
||||||
|
#warning High Performance Mode (QSPI Flash > 80MHz) is optional feature that depends on flash model. Read Docs First!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const static char *HPM_TAG = "flash HPM";
|
const static char *HPM_TAG = "flash HPM";
|
||||||
@ -117,6 +125,7 @@ static esp_err_t spi_flash_high_performance_check_hpf_bit_5(void)
|
|||||||
|
|
||||||
//-----------------For flash chips which enter HPM via adjust dummy-----------------------//
|
//-----------------For flash chips which enter HPM via adjust dummy-----------------------//
|
||||||
|
|
||||||
|
#if CONFIG_SPI_FLASH_HPM_DC_ON
|
||||||
/**
|
/**
|
||||||
* @brief Probe the chip whether adjust dummy to enable HPM mode. Take XMC as an example:
|
* @brief Probe the chip whether adjust dummy to enable HPM mode. Take XMC as an example:
|
||||||
* Adjust dummy bits to enable HPM mode of the flash. If XMC works under 80MHz, the dummy bits
|
* Adjust dummy bits to enable HPM mode of the flash. If XMC works under 80MHz, the dummy bits
|
||||||
@ -198,6 +207,14 @@ static void spi_flash_hpm_get_dummy_xmc(spi_flash_hpm_dummy_conf_t *dummy_conf)
|
|||||||
dummy_conf->qout_dummy = SPI_FLASH_QOUT_DUMMY_BITLEN;
|
dummy_conf->qout_dummy = SPI_FLASH_QOUT_DUMMY_BITLEN;
|
||||||
dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN;
|
dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN;
|
||||||
}
|
}
|
||||||
|
#elif !CONFIG_SPI_FLASH_HPM_DC_DISABLE
|
||||||
|
|
||||||
|
//This is because bootloader doesn't support this
|
||||||
|
#warning HPM-DC, which helps to run some flash > 80MHz by adjusting dummy cycles, is no longer enabled by default.
|
||||||
|
#warning To enable this feature, your bootloader needs to have the support for it (by explicitly selecting BOOTLOADER_FLASH_DC_AWARE).
|
||||||
|
#warning If your bootloader does not support it, select SPI_FLASH_HPM_DC_DISABLE to suppress the warning. READ DOCS FIRST!
|
||||||
|
|
||||||
|
#endif //CONFIG_SPI_FLASH_HPM_DC_ON
|
||||||
|
|
||||||
//-----------------For flash chips which enter HPM via write status register-----------------------//
|
//-----------------For flash chips which enter HPM via write status register-----------------------//
|
||||||
|
|
||||||
@ -247,6 +264,126 @@ static void spi_flash_turn_high_performance_write_hpf_bit_5(void)
|
|||||||
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
esp_rom_spiflash_wait_idle(&g_rom_flashchip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const spi_flash_hpm_info_t __attribute__((weak)) spi_flash_hpm_enable_list[] = {
|
||||||
|
/* vendor, chip_id, freq_threshold, temperature threshold, operation for setting high performance, reading HPF status, get dummy */
|
||||||
|
{ "command", spi_flash_hpm_probe_chip_with_cmd, spi_flash_hpm_chip_hpm_requirement_check_with_cmd, spi_flash_enable_high_performance_send_cmd, spi_flash_high_performance_check_hpf_bit_5, spi_flash_hpm_get_dummy_generic },
|
||||||
|
#if CONFIG_SPI_FLASH_HPM_DC_ON
|
||||||
|
{ "dummy", spi_flash_hpm_probe_chip_with_dummy, spi_flash_hpm_chip_hpm_requirement_check_with_dummy, spi_flash_turn_high_performance_reconfig_dummy, spi_flash_high_performance_check_dummy_sr, spi_flash_hpm_get_dummy_xmc},
|
||||||
|
#endif //CONFIG_SPI_FLASH_HPM_DC_ON
|
||||||
|
{ "write sr3-bit5", spi_flash_hpm_probe_chip_with_write_hpf_bit_5, spi_flash_hpm_chip_require_check_hpf_bit_5, spi_flash_turn_high_performance_write_hpf_bit_5, spi_flash_high_performance_check_hpf_bit_5, spi_flash_hpm_get_dummy_generic},
|
||||||
|
// default: do nothing, but keep the dummy get function. The first item with NULL as its probe will be the fallback.
|
||||||
|
{ "NULL", NULL, NULL, NULL, NULL, spi_flash_hpm_get_dummy_generic},
|
||||||
|
};
|
||||||
|
|
||||||
|
static const spi_flash_hpm_info_t *chip_hpm = NULL;
|
||||||
|
|
||||||
|
#if CONFIG_SPI_FLASH_HPM_DC_ON
|
||||||
|
static bool s_hpm_dummy_changed = false;
|
||||||
|
static spi_flash_hpm_dummy_conf_t s_dummy_conf;
|
||||||
|
|
||||||
|
const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void)
|
||||||
|
{
|
||||||
|
chip_hpm->flash_get_dummy(&s_dummy_conf);
|
||||||
|
return &s_dummy_conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool spi_flash_hpm_dummy_adjust(void)
|
||||||
|
{
|
||||||
|
return s_hpm_dummy_changed;
|
||||||
|
}
|
||||||
|
#endif //CONFIG_SPI_FLASH_HPM_DC_ON
|
||||||
|
|
||||||
|
#if CONFIG_ESPTOOLPY_FLASHFREQ_120M
|
||||||
|
#define FLASH_FREQUENCY 120
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_err_t spi_flash_enable_high_performance_mode(void)
|
||||||
|
{
|
||||||
|
uint32_t flash_chip_id = g_rom_flashchip.device_id;
|
||||||
|
uint32_t flash_freq = FLASH_FREQUENCY;
|
||||||
|
spi_flash_requirement_t hpm_requirement_check;
|
||||||
|
// voltage and temperature has not been implemented, just leave an interface here. Complete in the future.
|
||||||
|
int voltage = 0;
|
||||||
|
int temperature = 0;
|
||||||
|
|
||||||
|
#if CONFIG_SPI_FLASH_HPM_AUTO
|
||||||
|
ESP_EARLY_LOGW(HPM_TAG, "HPM mode is optional feature that depends on flash model. Read Docs First!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_SPI_FLASH_HPM_DC_DISABLE
|
||||||
|
// case 1: force disabled
|
||||||
|
ESP_EARLY_LOGI(HPM_TAG, "w/o HPM-DC support");
|
||||||
|
#elif CONFIG_SPI_FLASH_HPM_DC_ON
|
||||||
|
// case 2: auto, and actually enabled
|
||||||
|
ESP_EARLY_LOGI(HPM_TAG, "with HPM-DC support");
|
||||||
|
#else
|
||||||
|
// case 3: auto, but disabled (not supported by bootloader)
|
||||||
|
ESP_EARLY_LOGW(HPM_TAG, "HPM mode with DC adjustment is disabled. Some flash models may not be supported. Read Docs First!");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const spi_flash_hpm_info_t *chip = spi_flash_hpm_enable_list;
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
while (chip->probe) {
|
||||||
|
ret = chip->probe(flash_chip_id);
|
||||||
|
if (ret == ESP_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
chip++;
|
||||||
|
}
|
||||||
|
chip_hpm = chip;
|
||||||
|
|
||||||
|
/* When > 80 MHz, flash chips usually need special HPM support to run normally. The support is chip-specific. When
|
||||||
|
* the chip is not in the known flash list, nothing will be done and there will be an warning.
|
||||||
|
* When <= 80 MHz, it's assumed that all flash chips can run without chip-specific HPM support. This function will not be called and there will be no warning.
|
||||||
|
*/
|
||||||
|
if (ret != ESP_OK) {
|
||||||
|
ESP_EARLY_LOGW(HPM_TAG, "High performance mode of this flash model hasn't been supported.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
hpm_requirement_check = chip_hpm->chip_hpm_requirement_check(flash_chip_id, flash_freq, voltage, temperature);
|
||||||
|
if ((hpm_requirement_check == SPI_FLASH_HPM_CMD_NEEDED) || (hpm_requirement_check == SPI_FLASH_HPM_DUMMY_NEEDED) || (hpm_requirement_check == SPI_FLASH_HPM_WRITE_SR_NEEDED)) {
|
||||||
|
ESP_EARLY_LOGI(HPM_TAG, "Enabling flash high speed mode by %s", chip_hpm->method);
|
||||||
|
chip_hpm->flash_hpm_enable();
|
||||||
|
ESP_EARLY_LOGD(HPM_TAG, "Checking whether HPM has been executed");
|
||||||
|
|
||||||
|
if (chip_hpm->flash_hpf_check() != ESP_OK) {
|
||||||
|
ESP_EARLY_LOGE(HPM_TAG, "Flash high performance mode hasn't been executed successfully");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
#if CONFIG_SPI_FLASH_HPM_DC_ON
|
||||||
|
s_hpm_dummy_changed = (hpm_requirement_check == SPI_FLASH_HPM_DUMMY_NEEDED) ? true : false;
|
||||||
|
#else
|
||||||
|
assert(hpm_requirement_check != SPI_FLASH_HPM_DUMMY_NEEDED);
|
||||||
|
#endif
|
||||||
|
} else if (hpm_requirement_check == SPI_FLASH_HPM_BEYOND_LIMIT) {
|
||||||
|
ESP_EARLY_LOGE(HPM_TAG, "Flash does not have the ability to raise to that frequency");
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
//!CONFIG_SPI_FLASH_UNDER_HIGH_FREQ
|
||||||
|
|
||||||
|
static spi_flash_hpm_dummy_conf_t s_dummy_conf;
|
||||||
|
|
||||||
|
esp_err_t spi_flash_enable_high_performance_mode(void)
|
||||||
|
{
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void)
|
||||||
|
{
|
||||||
|
spi_flash_hpm_get_dummy_generic(&s_dummy_conf);
|
||||||
|
return &s_dummy_conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool spi_flash_hpm_dummy_adjust(void)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif //CONFIG_SPI_FLASH_UNDER_HIGH_FREQ
|
||||||
|
|
||||||
//-----------------------generic functions-------------------------------------//
|
//-----------------------generic functions-------------------------------------//
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -261,72 +398,3 @@ void __attribute__((weak)) spi_flash_hpm_get_dummy_generic(spi_flash_hpm_dummy_c
|
|||||||
dummy_conf->qout_dummy = SPI_FLASH_QOUT_DUMMY_BITLEN;
|
dummy_conf->qout_dummy = SPI_FLASH_QOUT_DUMMY_BITLEN;
|
||||||
dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN;
|
dummy_conf->fastrd_dummy = SPI_FLASH_FASTRD_DUMMY_BITLEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
const spi_flash_hpm_info_t __attribute__((weak)) spi_flash_hpm_enable_list[] = {
|
|
||||||
/* vendor, chip_id, freq_threshold, temperature threshold, operation for setting high performance, reading HPF status, get dummy */
|
|
||||||
{ "command", spi_flash_hpm_probe_chip_with_cmd, spi_flash_hpm_chip_hpm_requirement_check_with_cmd, spi_flash_enable_high_performance_send_cmd, spi_flash_high_performance_check_hpf_bit_5, spi_flash_hpm_get_dummy_generic },
|
|
||||||
{ "dummy", spi_flash_hpm_probe_chip_with_dummy, spi_flash_hpm_chip_hpm_requirement_check_with_dummy, spi_flash_turn_high_performance_reconfig_dummy, spi_flash_high_performance_check_dummy_sr, spi_flash_hpm_get_dummy_xmc},
|
|
||||||
{ "write sr3-bit5", spi_flash_hpm_probe_chip_with_write_hpf_bit_5, spi_flash_hpm_chip_require_check_hpf_bit_5, spi_flash_turn_high_performance_write_hpf_bit_5, spi_flash_high_performance_check_hpf_bit_5, spi_flash_hpm_get_dummy_generic},
|
|
||||||
// default: do nothing, but keep the dummy get function. The first item with NULL as its probe will be the fallback.
|
|
||||||
{ "NULL", NULL, NULL, NULL, NULL, spi_flash_hpm_get_dummy_generic},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const spi_flash_hpm_info_t *chip_hpm = NULL;
|
|
||||||
static spi_flash_hpm_dummy_conf_t dummy_conf;
|
|
||||||
static bool hpm_dummy_changed = false;
|
|
||||||
|
|
||||||
esp_err_t spi_flash_enable_high_performance_mode(void)
|
|
||||||
{
|
|
||||||
uint32_t flash_chip_id = g_rom_flashchip.device_id;
|
|
||||||
uint32_t flash_freq = FLASH_FREQUENCY;
|
|
||||||
spi_flash_requirement_t hpm_requirement_check;
|
|
||||||
// voltage and temperature has not been implemented, just leave an interface here. Complete in the future.
|
|
||||||
int voltage = 0;
|
|
||||||
int temperature = 0;
|
|
||||||
|
|
||||||
const spi_flash_hpm_info_t *chip = spi_flash_hpm_enable_list;
|
|
||||||
esp_err_t ret = ESP_OK;
|
|
||||||
while (chip->probe) {
|
|
||||||
ret = chip->probe(flash_chip_id);
|
|
||||||
if (ret == ESP_OK) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
chip++;
|
|
||||||
}
|
|
||||||
chip_hpm = chip;
|
|
||||||
|
|
||||||
if (ret != ESP_OK) {
|
|
||||||
#if (FLASH_FREQUENCY == 120)
|
|
||||||
ESP_EARLY_LOGW(HPM_TAG, "Flash high performance mode hasn't been supported");
|
|
||||||
#endif
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
hpm_requirement_check = chip_hpm->chip_hpm_requirement_check(flash_chip_id, flash_freq, voltage, temperature);
|
|
||||||
if ((hpm_requirement_check == SPI_FLASH_HPM_CMD_NEEDED) || (hpm_requirement_check == SPI_FLASH_HPM_DUMMY_NEEDED) || (hpm_requirement_check == SPI_FLASH_HPM_WRITE_SR_NEEDED)) {
|
|
||||||
ESP_EARLY_LOGI(HPM_TAG, "Enabling flash high speed mode by %s", chip_hpm->method);
|
|
||||||
chip_hpm->flash_hpm_enable();
|
|
||||||
ESP_EARLY_LOGD(HPM_TAG, "Checking whether HPM has been executed");
|
|
||||||
|
|
||||||
if (chip_hpm->flash_hpf_check() != ESP_OK) {
|
|
||||||
ESP_EARLY_LOGE(HPM_TAG, "Flash high performance mode hasn't been executed successfully");
|
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
|
||||||
hpm_dummy_changed = (hpm_requirement_check == SPI_FLASH_HPM_DUMMY_NEEDED) ? true : false;
|
|
||||||
} else if (hpm_requirement_check == SPI_FLASH_HPM_BEYOND_LIMIT) {
|
|
||||||
ESP_EARLY_LOGE(HPM_TAG, "Flash does not have the ability to raise to that frequency");
|
|
||||||
return ESP_FAIL;
|
|
||||||
}
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void)
|
|
||||||
{
|
|
||||||
chip_hpm->flash_get_dummy(&dummy_conf);
|
|
||||||
return &dummy_conf;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool spi_flash_hpm_dummy_adjust(void)
|
|
||||||
{
|
|
||||||
return hpm_dummy_changed;
|
|
||||||
}
|
|
||||||
|
@ -15,7 +15,7 @@ Some features are not supported on all ESP chips and Flash chips. You can check
|
|||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
- The features listed above needs to be supported by both esp chips and flash chips.
|
When Flash optional features listed in this page are used, aside from the capability of ESP chips, and ESP-IDF verison you are using, you will also need to make sure these features are supported by flash chips used.
|
||||||
|
|
||||||
- If you are using an official Espressif modules/SiP. Some of the modules/SiPs always support the feature, in this case you can see these features listed in the datasheet. Otherwise please contact `Espressif's business team <https://www.espressif.com/en/contact-us/sales-questions>`_ to know if we can supply such products for you.
|
- If you are using an official Espressif modules/SiP. Some of the modules/SiPs always support the feature, in this case you can see these features listed in the datasheet. Otherwise please contact `Espressif's business team <https://www.espressif.com/en/contact-us/sales-questions>`_ to know if we can supply such products for you.
|
||||||
|
|
||||||
@ -66,22 +66,66 @@ High performance mode
|
|||||||
|
|
||||||
This section is provided for Dual mode (DOUT/DIO) and Quad mode (QIO/QOUT) flash chips. Octal flash used on ESP-chips support High performance mode by default so far, you can refer to the octal flash support list below.
|
This section is provided for Dual mode (DOUT/DIO) and Quad mode (QIO/QOUT) flash chips. Octal flash used on ESP-chips support High performance mode by default so far, you can refer to the octal flash support list below.
|
||||||
|
|
||||||
High performance mode (HPM) means that the SPI1 and flash chip works under high frequency. Usually, when the operating frequency of the flash is greater than 80MHz, it is considered that the flash works under HPM. As far as we acknowledged, flash chips have more than two different coping strategies when flash work under HPM. For some flash chips, HPM is controlled by high performance flag (HPF) in status register and for some flash chips, HPM is controlled by dummy cycle bit.
|
High performance mode (HPM) means that the SPI1 and flash chip works under high frequency. Usually, when the operating frequency of the flash is greater than 80 MHz, it is considered that the flash works under HPM.
|
||||||
|
|
||||||
For following conditions, IDF start code deals with HPM internally.
|
As far as we acknowledged, there are more than three strategies for High Performance Mode (HPM) in typical SPI flash parts. For some flash chips, HPM is controlled by dummy cycle bit in the registers, while for other chips, it can be controlled by other bits (like HPM bit) in the register, or some special command. The difference in strategies requires the driver to explicitly add support for each chip.
|
||||||
|
|
||||||
|
.. attention::
|
||||||
|
|
||||||
|
It is hard to create several strategies to cover all situations, so all flash chips using HPM need to be supported explicitly. Therefore, if you try to use a flash not listed in :ref:`hpm_dc_support_list`, it might cause some error. So, when you try to use the flash chip beyond supported list, please test properly.
|
||||||
|
|
||||||
|
Moreover, when the `Dummy Cycle adjustment` strategy is adopted by the flash chip, the flash remains in a state in which DC is different from the default value after a software reset. The sub mode of HPM that adjusts the dummy cycle to run at higher frequency in the application is called `HPM-DC`. `HPM-DC` feature needs a feature `DC Aware` to be enabled in the bootloader. Otherwise different DC value will forbid the 2nd bootloader from being boot up after reset.
|
||||||
|
|
||||||
|
To enable High Performance Mode:
|
||||||
|
|
||||||
|
1. De-select :ref:`CONFIG_ESPTOOLPY_OCT_FLASH`. HPM is not used for Octal flash, enabling related options may bypass HPM functions.
|
||||||
|
|
||||||
|
2. Enable ``CONFIG_SPI_FLASH_HPM_ENA`` option.
|
||||||
|
|
||||||
|
3. Switch Flash frequency to HPM ones. For example, ``CONFIG_ESPTOOLPY_FLASHFREQ_120M``.
|
||||||
|
|
||||||
|
4. Make sure the config option for `HPM-DC` feature (under ``CONFIG_SPI_FLASH_HPM_DC`` choices) is selected correctly according to whether the bootloader supports `DC Aware`.
|
||||||
|
|
||||||
|
- If bootloader supports `DC Aware`, select ``CONFIG_SPI_FLASH_HPM_DC_AUTO``. This allows the usage of flash chips that adopted `Dummy Cycle adjustment` strategy.
|
||||||
|
|
||||||
|
- If bootloader doesn't support `DC Aware`, select ``CONFIG_SPI_FLASH_HPM_DC_DISABLE``. It avoid consequences caused by running HPM-DC with non-DC-aware bootloaders. But please avoid using flash chips that adopts `Dummy Cycle adjustment` strategy if ``CONFIG_SPI_FLASH_HPM_DC_DISABLE`` is selected. See list of flash models that adpot DC strategy below.
|
||||||
|
|
||||||
|
Check whether the bootloader supports `DC Aware` in the following way:
|
||||||
|
|
||||||
|
- If you are starting a new project, it's suggested to enable `DC Aware` by selecting :ref:`CONFIG_BOOTLOADER_FLASH_DC_AWARE` option in the bootloader menu. Please note that, you won't be able to modify this option via OTA, because the support is in the bootloader.
|
||||||
|
|
||||||
|
- If you are working on an existing project and want to update `HPM-DC` config option in the app via OTA, check the sdkconfig file used to build your bootloader: (Upgrading ESP-IDF version may make this file different from the one used by bootloader to build.)
|
||||||
|
|
||||||
|
- For latest version (ESP-IDF v4.4.7+, v5.0.7+, v5.2 and above), if :ref:`CONFIG_BOOTLOADER_FLASH_DC_AWARE` is selected, the bootloader supports `DC Aware`.
|
||||||
|
|
||||||
|
- For versions in this range: (v4.4.4-v4.4.6, v5.0-v5.0.6, and v5.1+), if ``CONFIG_ESPTOOLPY_FLASHFREQ_120M`` is selected, the bootloader supports `DC Aware`. In this case, enable :ref:`CONFIG_BOOTLOADER_FLASH_DC_AWARE` to confirm this (though it will not affect bootloader in devices in the field).
|
||||||
|
|
||||||
|
- For versions below v4.4.4, the bootloader doesn't support `DC Aware`.
|
||||||
|
|
||||||
ESP Chips List:
|
ESP Chips List:
|
||||||
|
|
||||||
1. ESP32S3
|
1. ESP32S3
|
||||||
|
|
||||||
Flash Chips (name & ID) List:
|
(The SW support for other chips haven't been done yet)
|
||||||
|
|
||||||
|
.. _hpm_dc_support_list:
|
||||||
|
|
||||||
|
Quad Flash HPM support list
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Flash chips that don't need HPM-DC:
|
||||||
|
|
||||||
1. GD25Q64C (ID: 0xC84017)
|
1. GD25Q64C (ID: 0xC84017)
|
||||||
2. GD25Q32C (ID: 0xC84016)
|
2. GD25Q32C (ID: 0xC84016)
|
||||||
|
3. ZB25VQ32B (ID: 0x5E4016)
|
||||||
|
4. GD25LQ255E (ID: 0xC86019)
|
||||||
|
|
||||||
.. attention::
|
Following flash chips also have HPM feature, but requires the bootloader to support `DC Aware`:
|
||||||
|
|
||||||
It is hard to create several strategies to cover all situations, so all flash chips using HPM need to be supported explicitly. Therefore, if you try to use a flash not listed as supported under high performance mode, it might cause some error. So, when you try to use the flash chip beyond supported list, please test properly.
|
1. GD25Q64E (ID: 0xC84017)
|
||||||
|
2. GD25Q128E (ID: 0xC84018)
|
||||||
|
3. XM25QH64C (ID: 0x204017)
|
||||||
|
4. XM25QH128C (ID: 0x204018)
|
||||||
|
|
||||||
OPI flash support
|
OPI flash support
|
||||||
-----------------
|
-----------------
|
||||||
@ -115,3 +159,7 @@ Flash Chips List:
|
|||||||
|
|
||||||
1. W25Q256
|
1. W25Q256
|
||||||
2. GD25Q256
|
2. GD25Q256
|
||||||
|
|
||||||
|
.. important::
|
||||||
|
|
||||||
|
Over 16 MBytes space on flash mentioned above can be only used for ``data saving``, like file system. If your data/instructions over 16 MBytes spaces need to be mapped to MMU (so as to be accessed by the CPU), please upgrade to ESP-IDF v5.2 and read the latest docs.
|
@ -3,5 +3,7 @@
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
CONFIG_SPI_FLASH_HPM_ENA=y
|
||||||
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
||||||
|
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
CONFIG_SPI_FLASH_HPM_ENA=y
|
||||||
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
||||||
|
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
CONFIG_SPIRAM=y
|
CONFIG_SPIRAM=y
|
||||||
CONFIG_SPIRAM_SPEED_120M=y
|
CONFIG_SPIRAM_SPEED_120M=y
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
CONFIG_SPI_FLASH_HPM_ENA=y
|
||||||
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
||||||
|
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
CONFIG_SPIRAM=y
|
CONFIG_SPIRAM=y
|
||||||
CONFIG_SPIRAM_SPEED_40M=y
|
CONFIG_SPIRAM_SPEED_40M=y
|
||||||
|
@ -7,5 +7,7 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
CONFIG_SPI_FLASH_HPM_ENA=y
|
||||||
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
||||||
|
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
|
@ -3,5 +3,7 @@
|
|||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
CONFIG_SPI_FLASH_HPM_ENA=y
|
||||||
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
|
||||||
|
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
|
||||||
|
Loading…
Reference in New Issue
Block a user