Merge branch 'bugfix/hpm_dc_default_disabled' into 'master'

spi_flash: fixed issue that enabling HPM-DC by default may cause app unable to restart

See merge request espressif/esp-idf!24380
This commit is contained in:
Michael (XIAO Xufeng)
2023-10-24 15:24:50 +08:00
39 changed files with 492 additions and 267 deletions

View File

@ -587,7 +587,7 @@ mainmenu "Espressif IoT Development Framework Configuration"
Current experimental feature list:
- CONFIG_ESPTOOLPY_FLASHFREQ_120M
- CONFIG_SPIRAM_SPEED_120M
- CONFIG_SPI_FLASH_QUAD_32BIT_ADDR_ENABLE
- CONFIG_ESPTOOLPY_FLASHFREQ_120M && CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_DTR
- CONFIG_SPIRAM_SPEED_120M && CONFIG_SPIRAM_MODE_OCT
- CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH
- CONFIG_MBEDTLS_USE_CRYPTO_ROM_IMPL

View File

@ -66,34 +66,83 @@ menu "Bootloader config"
default 4 if BOOTLOADER_LOG_LEVEL_DEBUG
default 5 if BOOTLOADER_LOG_LEVEL_VERBOSE
config BOOTLOADER_SPI_CUSTOM_WP_PIN
bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)"
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
default y if BOOTLOADER_SPI_WP_PIN != 7 # backwards compatibility, can remove in IDF 5
default n
help
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.
menu "Serial Flash Configurations"
config BOOTLOADER_SPI_CUSTOM_WP_PIN
bool "Use custom SPI Flash WP Pin when flash pins set in eFuse (read help)"
depends on IDF_TARGET_ESP32 && (ESPTOOLPY_FLASHMODE_QIO || ESPTOOLPY_FLASHMODE_QOUT)
default y if BOOTLOADER_SPI_WP_PIN != 7 # backwards compatibility, can remove in IDF 5
default n
help
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
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.
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
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
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.
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
Y and specify the GPIO number connected to the WP.
config BOOTLOADER_SPI_WP_PIN
int "Custom SPI Flash WP Pin"
range 0 33
default 7
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
help
The option "Use custom SPI Flash WP Pin" must be set or this value is ignored
config BOOTLOADER_SPI_WP_PIN
int "Custom SPI Flash WP Pin"
range 0 33
default 7
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
help
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
value to the GPIO number of the SPI flash WP pin.
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.
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_FLASH_NEEDS_32BIT_FEAT
bool
default y if BOOTLOADER_FLASH_32BIT_ADDR && !ESPTOOLPY_OCT_FLASH
help
This is a helper config for 32bits address flash. Invisible for users.
config BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH
bool "Enable cache access to 32-bit-address (over 16MB) range of SPI Flash (READ DOCS FIRST)"
depends on BOOTLOADER_FLASH_NEEDS_32BIT_FEAT && IDF_TARGET_ESP32S3 && IDF_EXPERIMENTAL_FEATURES
default n
help
Enabling this option allows the CPU to access 32-bit-address flash beyond 16M range.
1. This option only valid for 4-line flash. Octal flash doesn't need this.
2. This option is experimental, which means it cant use on all flash chips stable, for more
information, please contact Espressif Business support.
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
bool "VDDSDIO LDO voltage"
@ -428,16 +477,6 @@ menu "Bootloader config"
- "Reserve RTC FAST memory for custom purposes"
- "GPIO triggers factory reset"
config BOOTLOADER_FLASH_XMC_SUPPORT
bool "Enable the support for flash chips of XMC (READ HELP 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.
endmenu # Bootloader

View File

@ -23,3 +23,7 @@ CONFIG_FLASH_ENCRYPTION_UART_BOOTLOADER_ALLOW_CACHE CONFIG_SECURE_FLASH_
# Secure Boot Scheme
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

View File

@ -109,7 +109,7 @@ extern const bootloader_qio_info_t __attribute__((weak)) bootloader_flash_qe_sup
*/
esp_err_t __attribute__((weak)) bootloader_flash_unlock(void);
#if CONFIG_SPI_FLASH_QUAD_32BIT_ADDR_ENABLE || CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH || CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
/**
* @brief Enable 32bits address flash(larger than 16MB) can map to cache.
*

View File

@ -429,7 +429,7 @@ esp_err_t bootloader_flash_erase_range(uint32_t start_addr, uint32_t size)
return spi_to_esp_err(rc);
}
#if CONFIG_SPI_FLASH_QUAD_32BIT_ADDR_ENABLE || CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH || CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
void bootloader_flash_32bits_address_map_enable(esp_rom_spiflash_read_mode_t flash_mode)
{
esp_rom_opiflash_spi0rd_t cache_rd = {};

View File

@ -275,7 +275,7 @@ esp_err_t bootloader_init_spi_flash(void)
}
#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.
bootloader_spi_flash_reset();
#endif
@ -288,7 +288,7 @@ esp_err_t bootloader_init_spi_flash(void)
bootloader_enable_qio_mode();
}
#endif
#if CONFIG_SPI_FLASH_QUAD_32BIT_ADDR_ENABLE || CONFIG_SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE
#if CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_QUAD_FLASH || CONFIG_BOOTLOADER_CACHE_32BIT_ADDR_OCTAL_FLASH
bootloader_flash_32bits_address_map_enable(bootloader_flash_get_spi_mode());
#endif
print_flash_info(&bootloader_image_hdr);

View File

@ -106,8 +106,8 @@ static uint32_t spi_timing_config_get_dummy(void)
abort();
}
#if CONFIG_SPI_FLASH_HPM_ENABLE
if (spi_flash_hpm_dummy_adjust()) { // HPM is enabled
#if CONFIG_SPI_FLASH_HPM_DC_ON
if (spi_flash_hpm_dummy_adjust()) { // HPM-DC is enabled
const spi_flash_hpm_dummy_conf_t *hpm_dummy = spi_flash_hpm_get_dummy();
switch (mode) {
case MSPI_TIMING_LL_FLASH_QIO_MODE:
@ -127,7 +127,7 @@ static uint32_t spi_timing_config_get_dummy(void)
}
} else
#endif
{ // HPM is not enabled
{ // HPM-DC is not enabled
switch (mode) {
case MSPI_TIMING_LL_FLASH_QIO_MODE:
return SPI1_R_QIO_DUMMY_CYCLELEN;

View File

@ -3,5 +3,7 @@
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y

View File

@ -3,7 +3,9 @@
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_SPEED_120M=y

View File

@ -3,7 +3,9 @@
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_SPEED_40M=y

View File

@ -7,5 +7,7 @@ CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y

View File

@ -3,5 +3,7 @@
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y

View File

@ -5,6 +5,9 @@ CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
CONFIG_ESPTOOLPY_OCT_FLASH=y
CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT=n
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_SPIRAM=n

View File

@ -1,4 +1,6 @@
# Legacy, F4R4, Flash 120M SDR, PSRAM disable
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y

View File

@ -1,6 +1,8 @@
# Legacy, F4R4, Flash 120M SDR, PSRAM 120M SDR
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_SPEED_120M=y

View File

@ -1,6 +1,8 @@
# Legacy, F4R4, Flash 120M SDR, PSRAM 40M SDR
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_SPIRAM=y
CONFIG_SPIRAM_SPEED_40M=y

View File

@ -4,5 +4,7 @@ CONFIG_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y
CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y

View File

@ -1,4 +1,6 @@
# Legacy, F4R8, Flash 120M SDR, PSRAM disable
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y

View File

@ -2,6 +2,8 @@
CONFIG_ESPTOOLPY_OCT_FLASH=y
CONFIG_ESPTOOLPY_FLASH_SAMPLE_MODE_STR=y
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_SPIRAM=n

View File

@ -83,7 +83,7 @@ menu "SPI RAM config"
config SPIRAM_SPEED_120M
depends on SPIRAM_MODE_QUAD || IDF_EXPERIMENTAL_FEATURES
bool "120MHz clock speed"
bool "120MHz clock speed (READ DOCS FIRST)"
help
- Quad PSRAM 120 MHz is stable.

View File

@ -27,8 +27,10 @@ menu "Serial flasher config"
mode to "OPI" and the sample mode will be STR.
2. If the flash chip is a Quad one, even if "OPI" is selected in `ESPTOOLPY_FLASHMODE`, our code will
automatically change the mode to "DIO".
3. Please do not rely on this option when you are pretty sure that you are using Octal flash,
please enable `ESPTOOLPY_OCT_FLASH` option, then you can choose `DTR` sample mode
3. This option is mainly to improve the out-of-box experience of developers. It doesn't guarantee
the feature-complete. Some code still rely on `ESPTOOLPY_OCT_FLASH`. Please do not rely on this option
when you are pretty sure that you are using Octal flash.
In this case, please enable `ESPTOOLPY_OCT_FLASH` option, then you can choose `DTR` sample mode
in `ESPTOOLPY_FLASH_SAMPLE_MODE`. Otherwise, only `STR` mode is available.
4. Enabling this feature reduces available internal RAM size (around 900 bytes).
If your IRAM space is insufficient and you're aware of your flash type,
@ -92,11 +94,12 @@ menu "Serial flasher config"
default ESPTOOLPY_FLASHFREQ_80M if ESPTOOLPY_FLASHFREQ_80M_DEFAULT
default ESPTOOLPY_FLASHFREQ_60M if IDF_TARGET_ESP32C2
config ESPTOOLPY_FLASHFREQ_120M
bool "120 MHz"
select SPI_FLASH_HPM_ENABLE
bool "120 MHz (READ DOCS FIRST)"
depends on SOC_MEMSPI_SRC_FREQ_120M && \
(SPI_FLASH_HPM_ON || ESPTOOLPY_OCT_FLASH) && \
(ESPTOOLPY_FLASH_SAMPLE_MODE_STR || IDF_EXPERIMENTAL_FEATURES)
help
- Optional feature for QSPI Flash. Read docs and enable `CONFIG_SPI_FLASH_HPM_ENA` first!
- Flash 120 MHz SDR mode is stable.
- Flash 120 MHz DDR mode is an experimental feature, it works when
the temperature is stable.

View File

@ -15,7 +15,7 @@ set(ESPMKUF2 ${python} "${idf_path}/tools/mkuf2.py" write --chip ${chip_model})
set(ESPTOOLPY_CHIP "${chip_model}")
if(NOT CONFIG_APP_BUILD_TYPE_RAM AND CONFIG_APP_BUILD_GENERATE_BINARIES)
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
# because on some flash chips, 120M will modify the status register,
# which will make ROM won't work.

View File

@ -887,10 +887,6 @@ config SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE
bool
default y
config SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
bool
default y
config SOC_SPI_MEM_SUPPORT_AUTO_RESUME
bool
default y

View File

@ -415,7 +415,7 @@
/*-------------------------- SPI MEM CAPS ---------------------------------------*/
#define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE (1)
#define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1)
//#define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1) //TODO: IDF-7518
#define SOC_SPI_MEM_SUPPORT_AUTO_RESUME (1)
#define SOC_SPI_MEM_SUPPORT_IDLE_INTR (1)
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)

View File

@ -15,7 +15,7 @@ else()
list(APPEND srcs "${target}/spi_flash_oct_flash_init.c")
endif()
if(CONFIG_IDF_TARGET_ESP32S3)
if(CONFIG_SPI_FLASH_HPM_ON)
list(APPEND srcs
"spi_flash_hpm_enable.c")
endif()

View File

@ -1,3 +1,116 @@
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_SUSPEND_QVL_SUPPORTED
bool
default y if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C2
default n
help
This is a helper config. Invisible for users.
config SPI_FLASH_AUTO_SUSPEND
bool "Auto suspend long erase/write operations (READ DOCS FIRST)"
default n
depends on SPI_FLASH_SUSPEND_QVL_SUPPORTED && !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"
depends on !APP_BUILD_TYPE_PURE_RAM_APP
@ -147,30 +260,6 @@ menu "SPI Flash driver"
help
Defines how many ticks will be before returning to continue a erasing.
config SPI_FLASH_SUSPEND_QVL_SUPPORTED
# Internally usage
bool
default y if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C2
default n
config SPI_FLASH_AUTO_SUSPEND
bool "Auto suspend long erase/write operations (READ DOCS FIRST)"
default n
depends on SPI_FLASH_SUSPEND_QVL_SUPPORTED && !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.
config SPI_FLASH_WRITE_CHUNK_SIZE
int "Flash write chunk size"
default 8192
@ -207,28 +296,6 @@ menu "SPI Flash driver"
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"
visible if !SPI_FLASH_OVERRIDE_CHIP_DRIVER_LIST
@ -315,33 +382,4 @@ menu "SPI Flash driver"
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.
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_QUAD_32BIT_ADDR_ENABLE
bool "Enable 32-bit-address (over 16MB) SPI Flash access"
depends on SPI_FLASH_32BIT_ADDRESS && !ESPTOOLPY_OCT_FLASH && IDF_TARGET_ESP32S3 && IDF_EXPERIMENTAL_FEATURES
default n
help
Enabling this option allows the CPU to access 32-bit-address flash beyond 16M range.
1. This option only valid for 4-line flash. Octal flash doesn't need this.
2. This option is experimental, which means it can't use on all flash chips stable, for more
information, please contact Espressif Business support.
config SPI_FLASH_OCTAL_32BIT_ADDR_ENABLE
bool
default y if ESPTOOLPY_OCT_FLASH && SPI_FLASH_32BIT_ADDRESS
default n
endmenu

View File

@ -334,6 +334,8 @@ esp_err_t esp_flash_init_default_chip(void)
#endif
#if CONFIG_ESPTOOLPY_OCT_FLASH
// Default value. When `CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT` selected, if the selected mode not consistent with
// hardware, will be overwritten in s_esp_flash_choose_correct_mode.
cfg.octal_mode_en = 1;
cfg.default_io_mode = DEFAULT_FLASH_MODE;
#endif
@ -385,7 +387,7 @@ esp_err_t esp_flash_init_default_chip(void)
}
#endif
#if CONFIG_SPI_FLASH_HPM_ENABLE
#if CONFIG_SPI_FLASH_HPM_DC_ON
if (spi_flash_hpm_dummy_adjust()) {
default_chip.hpm_dummy_ena = 1;
}

View File

@ -161,16 +161,12 @@ esp_err_t IRAM_ATTR spi_flash_init_chip_state(void)
#if SOC_SPI_MEM_SUPPORT_OPI_MODE
if (bootloader_flash_is_octal_mode_enabled()) {
return esp_opiflash_init(rom_spiflash_legacy_data->chip.device_id);
} else
#endif
{
#if CONFIG_IDF_TARGET_ESP32S3
// Currently, only esp32s3 allows high performance mode.
return spi_flash_enable_high_performance_mode();
#else
return ESP_OK;
#endif // CONFIG_IDF_TARGET_ESP32S3
}
#endif
#if CONFIG_SPI_FLASH_HPM_ON
return spi_flash_enable_high_performance_mode();
#endif // CONFIG_SPI_FLASH_HPM_ON
return ESP_OK;
}
void IRAM_ATTR spi_flash_set_rom_required_regs(void)

View File

@ -171,6 +171,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);
/** @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[out] out_id Pointer to receive unique ID value.

View File

@ -114,9 +114,15 @@ void spi_flash_set_erasing_flag(bool status);
*/
bool spi_flash_brownout_need_reset(void);
#if CONFIG_SPI_FLASH_HPM_ON
/**
* @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. `CONFIG_SPI_FLASH_HPM_ON` may be
* True when `CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT && !CONFIG_ESPTOOLPY_OCT_FLASH`
*
* @return ESP_OK if success.
*/
esp_err_t spi_flash_enable_high_performance_mode(void);
@ -136,6 +142,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.
*/
bool spi_flash_hpm_dummy_adjust(void);
#endif //CONFIG_SPI_FLASH_HPM_ON
#if SOC_SPI_MEM_SUPPORT_WRAP
/**

View File

@ -15,6 +15,8 @@ entries:
if IDF_TARGET_ESP32S3 = y:
spi_flash_chip_mxic_opi (noflash)
if SPI_FLASH_HPM_ON = y:
spi_flash_hpm_enable (noflash)
if ESPTOOLPY_OCT_FLASH = y || ESPTOOLPY_FLASH_MODE_AUTO_DETECT = y:

View File

@ -5,4 +5,3 @@ CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS CONFIG_SPI_FLASH_DANGERO
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS CONFIG_SPI_FLASH_DANGEROUS_WRITE_ABORTS
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_FAILS CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS
CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED
CONFIG_SPI_FLASH_32BIT_ADDR_ENABLE CONFIG_SPI_FLASH_QUAD_32BIT_ADDR_ENABLE

View File

@ -29,14 +29,28 @@
* 4. Some flash chips do nothing.
******************************************************************************/
#if CONFIG_ESPTOOLPY_FLASHFREQ_120M
#define FLASH_FREQUENCY 120
#elif CONFIG_ESPTOOLPY_FLASHFREQ_80M
#define FLASH_FREQUENCY 80
#elif CONFIG_ESPTOOLPY_FLASHFREQ_40M
#define FLASH_FREQUENCY 40
#elif CONFIG_ESPTOOLPY_FLASHFREQ_20M
#define FLASH_FREQUENCY 20
/*
* Note: This file should only be compiled when HPM_ON, which is only available when !CONFIG_ESPTOOLPY_OCT_FLASH.
* However when HPM_ON, there are still some cases this file is not actually used:
*
* - !CONFIG_SPI_FLASH_UNDER_HIGH_FREQ:
* It mean that the flash not running under frequency requires HPM. spi_flash_enable_high_performance_mode() still
* called because caller shouldn't take care of the frequency.
*
* - bootloader_flash_is_octal_mode_enabled() == true:
* This is possible when `CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT` selected
*
* Octal Flash for now all support 120M. No need to enable HPM. The file is compiled, but will not actually run
* into spi_flash_enable_high_performance_mode().
*/
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
const static char *HPM_TAG = "flash HPM";
@ -120,6 +134,7 @@ static esp_err_t spi_flash_high_performance_check_hpf_bit_5(void)
//-----------------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:
* Adjust dummy bits to enable HPM mode of the flash. If XMC works under 80MHz, the dummy bits
@ -203,6 +218,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->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-----------------------//
@ -284,6 +307,127 @@ static spi_flash_requirement_t spi_flash_hpm_chip_hpm_requirement_check_with_doi
return chip_cap;
}
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_hpm_requirement_check_with_write_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},
{ "noting-to-do", spi_flash_hpm_probe_chip_with_doing_nothing, spi_flash_hpm_chip_hpm_requirement_check_with_doing_nothing, NULL, NULL, 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-------------------------------------//
/**
@ -298,73 +442,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->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_hpm_requirement_check_with_write_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},
{ "noting-to-do", spi_flash_hpm_probe_chip_with_doing_nothing, spi_flash_hpm_chip_hpm_requirement_check_with_doing_nothing, NULL, NULL, 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;
}

View File

@ -74,7 +74,7 @@ There are some features that are not supported by all flash chips, or not suppor
- Flash unique ID - means that flash supports its unique 64-bit ID.
.. only:: esp32c3
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
- Suspend & Resume - means that flash can accept suspend/resume command during its writing/erasing. The {IDF_TARGET_NAME} may keep the cache on when the flash is being written/erased and suspend it to read its contents randomly.
@ -169,7 +169,7 @@ Differences between :cpp:func:`spi_flash_mmap` and :cpp:func:`esp_partition_mmap
Note that since memory mapping happens in pages, it may be possible to read data outside of the partition provided to ``esp_partition_mmap``, regardless of the partition boundary.
.. note::
mmap is supported by cache, so it can only be used on main flash.
SPI Flash Implementation

View File

@ -11,7 +11,7 @@ The SPI0/1 bus is shared between the instruction & data cache (for firmware exec
On {IDF_TARGET_NAME}, these caches must be disabled while reading/writing/erasing.
.. only:: esp32c3
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
On {IDF_TARGET_NAME}, the config option :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND` (enabled by default) allows the cache to read flash concurrently with SPI1 operations. See :ref:`auto-suspend` for more details.
@ -78,7 +78,7 @@ Non-IRAM-Safe Interrupt Handlers
If the ``ESP_INTR_FLAG_IRAM`` flag is not set when registering, the interrupt handler will not get executed when the caches are disabled. Once the caches are restored, the non-IRAM-safe interrupts will be re-enabled. After this moment, the interrupt handler will run normally again. This means that as long as caches are disabled, users will not see the corresponding hardware event happening.
.. only:: esp32c3 or esp32c2 or esp32s3
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
.. include:: auto_suspend.inc

View File

@ -15,7 +15,7 @@ Some features are not supported on all ESP chips and Flash chips. You can check
.. 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.
@ -30,35 +30,31 @@ Some features are not supported on all ESP chips and Flash chips. You can check
Auto Suspend & Resume
---------------------
The support list is as follows.
This feature is only supported on ESP32-S3, ESP32-C2, ESP32-C3, ESP32-C6, ESP32-H2 for now.
ESP Chips List:
The support for ESP32-P4 may be added in the future.
1. ESP32C3
2. ESP32C2
3. ESP32S3
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
Flash Chips List:
List of Flash chips that support this feature:
1. XM25QxxC series.
2. GD25QxxE series.
.. only:: esp32c3 or esp32c2 or esp32s3
1. XM25QxxC series.
2. GD25QxxE series.
.. attention::
There are multiple limitations about the auto-suspend feature, please do read :ref:`auto-suspend` for more information before you enable this feature.
Flash Unique ID
---------------
This feature is supported on all Espressif chips.
Unique ID is not flash id, which means flash has 64-Bit unique ID for each device. The instruction to read the unique ID (4Bh) accesses a factory-set read-only 64-bit number that is unique to each flash device. This ID number helps you to recognize each single device. Not all flash vendors support this feature. If you try to read the unique ID on a chip which does not have this feature, the behavior is not determined. The support list is as follows.
ESP Chips Lists:
ALL
Flash Chips List:
List of Flash chips that support this feature:
1. ISSI
2. GD
@ -73,33 +69,78 @@ Flash Chips List:
High Performance Mode
---------------------
.. note::
This featuer is only supported on ESP32-S3 for now.
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.
The support for ESP32-S2, ESP32-C3, ESP32-C6, ESP32-H2, ESP32-P4 may be added in the future.
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. 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.
.. only:: esp32s3
For following conditions, ESP-IDF start code deals with HPM internally.
.. note::
ESP Chips List:
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.
1. ESP32S3
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.
Flash Chips (name & ID) List:
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.
1. GD25Q64C (ID: 0xC84017)
2. GD25Q32C (ID: 0xC84016)
.. attention::
.. 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.
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.
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` and :ref:`CONFIG_ESPTOOLPY_FLASH_MODE_AUTO_DETECT`. 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 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+, v5.0+, 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`.
.. _hpm_dc_support_list:
Quad Flash HPM support list
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Flash chips that don't need HPM-DC:
1. GD25Q64C (ID: 0xC84017)
2. GD25Q32C (ID: 0xC84016)
3. ZB25VQ32B (ID: 0x5E4016)
4. GD25LQ255E (ID: 0xC86019)
Following flash chips also have HPM feature, but requires the bootloader to support `DC Aware`:
1. GD25Q64E (ID: 0xC84017)
2. GD25Q128E (ID: 0xC84018)
3. XM25QH64C (ID: 0x204017)
4. XM25QH128C (ID: 0x204018)
.. _oct-flash-doc:
OPI flash Support
-----------------
This feature is only supporetd on ESP32-S3 for now.
OPI flash means that the flash chip supports octal peripheral interface, which has octal I/O pins. Different octal flash has different configurations and different commands. Hence, it is necessary to carefully check the support list.
.. only:: esp32s3
@ -108,13 +149,10 @@ OPI flash means that the flash chip supports octal peripheral interface, which h
To know how to configure menuconfig for a board with different Flash and PSRAM, please refer to the :ref:`SPI Flash and External SPI RAM Configuration <flash-psram-configuration>`
ESP Chips List:
List of Flash chips that support this feature:
1. ESP32S3
Flash Chips List:
1. MX25UM25645G
1. MX25UM25645G
2. MX25UM12345G
.. _32-bit-flash-doc:
@ -122,21 +160,19 @@ Flash Chips List:
32-bit Address Flash Chips
--------------------------
This feature is supported on all Espressif chips (with various restrictions to application).
Most NOR flash chips used by Espressif chips use 24-bits address, which can cover 16 MBytes memory. However, for larger memory (usually equal to or larger than 16 MBytes), flash uses a 32-bits address to address larger memory. Regretfully, 32-bits address chips have vendor-specific commands, so we need to support the chips one by one.
ESP Chips List:
ALL ESP Chips support this.
Flash Chips List:
List of Flash chips that support this feature:
1. W25Q256
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 enable the config ``IDF_EXPERIMENTAL_FEATURES`` and ``CONFIG_SPI_FLASH_32BIT_ADDRESS`` and read the limitations following:
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 enable the config ``IDF_EXPERIMENTAL_FEATURES`` and ``BOOTLOADER_CACHE_32BIT_ADDR_FLASH`` and read the limitations following:
1. This option only valid for 4-line flash. Octal flash does not need this.
2. Only MMU on ESP chip that supports mapping to a range over 16 MB memory supports this config. (Only ESP32S3 supports this up to now)
1. This feature is valid only for 4-line flash. Octal flash supports 32-bit-addr by default
2. This feature needs the MMU on ESP chip to be able to map to >= 16 MB physical address on the Flash. (Only ESP32S3 supports this up to now)
3. This option is experimental, which means it can not use on all flash chips stable, for more information, please contact Espressif Business support.

View File

@ -74,7 +74,7 @@ flash 可选的功能
- flash 的私有 ID (unique ID) - 表示 flash 支持它自己的 64-bit 独有 ID。
.. only:: esp32c3
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
- 暂停与恢复 - 表示 flash 可以在读/写的过程中接受暂停/恢复的命令。{IDF_TARGET_NAME} 可以在 flash 正在写/擦除的过程中保持 cache 开启,并能随机读取 flash 中的内容。

View File

@ -11,7 +11,7 @@ SPI1 flash 并发约束
在 {IDF_TARGET_NAME} 上flash 读取/写入/擦除时,必须禁用 cache。
.. only:: esp32c3
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
在 {IDF_TARGET_NAME} 上,默认启用的配置选项 :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND` 允许 flash/PSRAM 的 cache 访问和 SPI1 的操作并发执行。请参阅 :ref:`auto-suspend`,查看详细信息。
@ -78,7 +78,7 @@ IRAM 安全中断处理程序
如果在注册时没有设置 ``ESP_INTR_FLAG_IRAM`` 标志,当禁用 cache 时,将不会执行中断处理程序。一旦 cache 恢复,非 IRAM 安全的中断将重新启用,中断处理程序随即再次正常运行。这意味着,只要禁用了 cache就不会发生相应的硬件事件。
.. only:: esp32c3 or esp32c2 or esp32s3
.. only:: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
.. include:: auto_suspend.inc

View File

@ -1,7 +1,9 @@
# Any of a set of configurations that will trigger timing tuning
CONFIG_IDF_TARGET="esp32s3"
CONFIG_SPI_FLASH_HPM_ENA=y
CONFIG_ESPTOOLPY_FLASHFREQ_120M=y
CONFIG_BOOTLOADER_FLASH_DC_AWARE=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_COMPILER_OPTIMIZATION_SIZE=y