diff --git a/components/esp_hal_mspi/esp32/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32/include/hal/spi_flash_ll.h index 27f6e82ab33..7e06d9c0b29 100644 --- a/components/esp_hal_mspi/esp32/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32/include/hal/spi_flash_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -126,6 +126,26 @@ static inline void spi_flash_ll_set_write_protect(spi_dev_t *dev, bool wp) } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spi_flash_ll_enter_dpd(spi_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spi_flash_ll_exit_dpd(spi_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spi_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32c2/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32c2/include/hal/spi_flash_ll.h index cd5838d8cfa..ae862d09860 100644 --- a/components/esp_hal_mspi/esp32c2/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32c2/include/hal/spi_flash_ll.h @@ -73,6 +73,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32c2/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32c2/include/hal/spimem_flash_ll.h index 8140fa42058..2916e288ad8 100644 --- a/components/esp_hal_mspi/esp32c2/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32c2/include/hal/spimem_flash_ll.h @@ -315,6 +315,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32c3/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32c3/include/hal/spi_flash_ll.h index cd5838d8cfa..ae862d09860 100644 --- a/components/esp_hal_mspi/esp32c3/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32c3/include/hal/spi_flash_ll.h @@ -73,6 +73,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32c3/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32c3/include/hal/spimem_flash_ll.h index 1fd64092e15..e18d5323988 100644 --- a/components/esp_hal_mspi/esp32c3/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32c3/include/hal/spimem_flash_ll.h @@ -317,6 +317,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32c5/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32c5/include/hal/spi_flash_ll.h index a51dd6adf88..27bbb9e7467 100644 --- a/components/esp_hal_mspi/esp32c5/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32c5/include/hal/spi_flash_ll.h @@ -78,6 +78,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32c5/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32c5/include/hal/spimem_flash_ll.h index afbb8ec4728..09609913ec8 100644 --- a/components/esp_hal_mspi/esp32c5/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32c5/include/hal/spimem_flash_ll.h @@ -338,6 +338,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32c6/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32c6/include/hal/spi_flash_ll.h index 21ba8889b3b..c87ccd1a332 100644 --- a/components/esp_hal_mspi/esp32c6/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32c6/include/hal/spi_flash_ll.h @@ -75,6 +75,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32c6/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32c6/include/hal/spimem_flash_ll.h index 69d24750521..dbe784fd8fd 100644 --- a/components/esp_hal_mspi/esp32c6/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32c6/include/hal/spimem_flash_ll.h @@ -318,6 +318,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32c61/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32c61/include/hal/spi_flash_ll.h index b97956ca116..2120509d04f 100644 --- a/components/esp_hal_mspi/esp32c61/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32c61/include/hal/spi_flash_ll.h @@ -77,6 +77,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32c61/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32c61/include/hal/spimem_flash_ll.h index 892e08ca968..6462f381a41 100644 --- a/components/esp_hal_mspi/esp32c61/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32c61/include/hal/spimem_flash_ll.h @@ -332,6 +332,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32h2/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32h2/include/hal/spi_flash_ll.h index 0b7a6bb7b5a..309405573c3 100644 --- a/components/esp_hal_mspi/esp32h2/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32h2/include/hal/spi_flash_ll.h @@ -75,6 +75,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32h2/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32h2/include/hal/spimem_flash_ll.h index ac41f18087d..493324b3502 100644 --- a/components/esp_hal_mspi/esp32h2/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32h2/include/hal/spimem_flash_ll.h @@ -319,6 +319,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32h21/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32h21/include/hal/spi_flash_ll.h index 7abb40387ff..ef812b4ac0f 100644 --- a/components/esp_hal_mspi/esp32h21/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32h21/include/hal/spi_flash_ll.h @@ -71,6 +71,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32h21/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32h21/include/hal/spimem_flash_ll.h index be05c189cd1..72d33c43f22 100644 --- a/components/esp_hal_mspi/esp32h21/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32h21/include/hal/spimem_flash_ll.h @@ -321,6 +321,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32h4/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32h4/include/hal/spi_flash_ll.h index 68ce940eba9..84a826471d4 100644 --- a/components/esp_hal_mspi/esp32h4/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32h4/include/hal/spi_flash_ll.h @@ -77,6 +77,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32h4/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32h4/include/hal/spimem_flash_ll.h index e1e7c416fde..2fd565004c5 100644 --- a/components/esp_hal_mspi/esp32h4/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32h4/include/hal/spimem_flash_ll.h @@ -319,6 +319,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32p4/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/spi_flash_ll.h index 05a3f2bde45..5bf319bf673 100644 --- a/components/esp_hal_mspi/esp32p4/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32p4/include/hal/spi_flash_ll.h @@ -76,6 +76,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32p4/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32p4/include/hal/spimem_flash_ll.h index eba6f06368f..46b3186e483 100644 --- a/components/esp_hal_mspi/esp32p4/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32p4/include/hal/spimem_flash_ll.h @@ -344,6 +344,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32s2/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32s2/include/hal/spi_flash_ll.h index 88861dd812e..d05b0b445bf 100644 --- a/components/esp_hal_mspi/esp32s2/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32s2/include/hal/spi_flash_ll.h @@ -76,6 +76,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32s2/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32s2/include/hal/spimem_flash_ll.h index 80ef0ecc1ee..70d343a6016 100644 --- a/components/esp_hal_mspi/esp32s2/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32s2/include/hal/spimem_flash_ll.h @@ -258,6 +258,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32s3/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32s3/include/hal/spi_flash_ll.h index 99d96cacf59..80b2fe6fe22 100644 --- a/components/esp_hal_mspi/esp32s3/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32s3/include/hal/spi_flash_ll.h @@ -74,6 +74,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32s3/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32s3/include/hal/spimem_flash_ll.h index 1f7eccfb0be..c071fd9413c 100644 --- a/components/esp_hal_mspi/esp32s3/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32s3/include/hal/spimem_flash_ll.h @@ -320,6 +320,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/esp32s31/include/hal/spi_flash_ll.h b/components/esp_hal_mspi/esp32s31/include/hal/spi_flash_ll.h index c3125be500a..35f2e1969bb 100644 --- a/components/esp_hal_mspi/esp32s31/include/hal/spi_flash_ll.h +++ b/components/esp_hal_mspi/esp32s31/include/hal/spi_flash_ll.h @@ -76,6 +76,8 @@ typedef union { #define spi_flash_ll_erase_sector(dev) spimem_flash_ll_erase_sector((spi_mem_dev_t*)dev) #define spi_flash_ll_erase_block(dev) spimem_flash_ll_erase_block((spi_mem_dev_t*)dev) #define spi_flash_ll_set_write_protect(dev, wp) spimem_flash_ll_set_write_protect((spi_mem_dev_t*)dev, wp) +#define spi_flash_ll_enter_dpd(dev) spimem_flash_ll_enter_dpd((spi_mem_dev_t*)dev) +#define spi_flash_ll_exit_dpd(dev) spimem_flash_ll_exit_dpd((spi_mem_dev_t*)dev) #define spi_flash_ll_get_buffer_data(dev, buffer, read_len) spimem_flash_ll_get_buffer_data((spi_mem_dev_t*)dev, buffer, read_len) #define spi_flash_ll_set_buffer_data(dev, buffer, len) spimem_flash_ll_set_buffer_data((spi_mem_dev_t*)dev, buffer, len) #define spi_flash_ll_program_page(dev, buffer, len) spimem_flash_ll_program_page((spi_mem_dev_t*)dev, buffer, len) diff --git a/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h b/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h index 9d4fefb9b44..dad35b66844 100644 --- a/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h +++ b/components/esp_hal_mspi/esp32s31/include/hal/spimem_flash_ll.h @@ -329,6 +329,26 @@ static inline void spimem_flash_ll_set_write_protect(spi_mem_dev_t *dev, bool wp } } +/** + * Drive Flash into power down mode + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_enter_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_dp = 1; +} + +/** + * Releases Flash from the power-down state + * + * @param dev Beginning address of the peripheral registers. + */ +static inline void spimem_flash_ll_exit_dpd(spi_mem_dev_t *dev) +{ + dev->cmd.flash_res = 1; +} + /** * Get the read data from the buffer after ``spimem_flash_ll_read`` is done. * diff --git a/components/esp_hal_mspi/include/hal/spi_flash_hal.h b/components/esp_hal_mspi/include/hal/spi_flash_hal.h index c3c78978777..6b0ffd94b07 100644 --- a/components/esp_hal_mspi/include/hal/spi_flash_hal.h +++ b/components/esp_hal_mspi/include/hal/spi_flash_hal.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2010-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2010-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -192,6 +192,22 @@ esp_err_t spi_flash_hal_read(spi_flash_host_inst_t *host, void *buffer, uint32_t */ esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp); +/** + * @brief Send the deep power down (b9h) command to the flash chip. + * + * @param host The driver context. + * @return always return ESP_OK. + */ +esp_err_t spi_flash_hal_enter_dpd_mode(spi_flash_host_inst_t *host); + +/** + * @brief Send the release from deep power down (abh) command to the flash chip. + * + * @param host The driver context. + * @return always return ESP_OK. + */ +esp_err_t spi_flash_hal_exit_dpd_mode(spi_flash_host_inst_t *host); + /** * Check whether the SPI host is idle and can perform other operations. * diff --git a/components/esp_hal_mspi/spi_flash_hal_iram.c b/components/esp_hal_mspi/spi_flash_hal_iram.c index 919644e3813..4dcb77e0f8c 100644 --- a/components/esp_hal_mspi/spi_flash_hal_iram.c +++ b/components/esp_hal_mspi/spi_flash_hal_iram.c @@ -88,6 +88,22 @@ esp_err_t spi_flash_hal_set_write_protect(spi_flash_host_inst_t *host, bool wp) return ESP_OK; } +esp_err_t spi_flash_hal_enter_dpd_mode(spi_flash_host_inst_t *host) +{ + spi_dev_t *dev = get_spi_dev(host); + spi_flash_ll_enter_dpd(dev); + host->driver->poll_cmd_done(host); + return ESP_OK; +} + +esp_err_t spi_flash_hal_exit_dpd_mode(spi_flash_host_inst_t *host) +{ + spi_dev_t *dev = get_spi_dev(host); + spi_flash_ll_exit_dpd(dev); + host->driver->poll_cmd_done(host); + return ESP_OK; +} + #else static inline spi_dev_t *get_spi_dev(spi_flash_host_inst_t *host) diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 2d4cf55755c..dd4ade3c703 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -214,6 +214,52 @@ menu "Hardware Settings" NOTE: Enabling these callbacks may change sleep duration calculations based on time spent in callback and hence it is highly recommended to keep them as short as possible. + + config ESP_SLEEP_SET_FLASH_DPD + bool "Set SPI flash to deep power-down mode in light sleep" + depends on (!APP_BUILD_TYPE_PURE_RAM_APP && !ESP_SLEEP_POWER_DOWN_FLASH && !SPI_FLASH_ROM_IMPL) + default y if (IDF_TARGET_ESP32H4 || IDF_TARGET_ESP32H21) + default y if (IDF_TARGET_ESP32P4 && ESP32P4_SELECTS_REV_LESS_V3) + default n + help + Deep Power-Down mode is a power mode supported by most SPI Flash, SPI Flash has better power + consumption performance in this mode comparing to standby mode (hold CS). + Enabling this option will set the SPI Flash to deep power down mode during lightsleep to save power, + which will reduce the sleep current by about 10uA. And you can also use this option to reduce power + consumption when using PSRAM + + NOTE: We have conducted sufficient testing on ESP32H21, ESP32H4 and ESP32P4(less v3). If you plan to + use a customized flash chip, or if you are working with other ESP32-series chips, please make sure to + check the corresponding flash datasheet or consult us directly. This is to ensure that using the B9h + command to enter Deep Power-Down mode and ABh to exit Deep Power-Down mode will not introduce any + potential issues. + + config ESP_SLEEP_SPI_FLASH_ENTER_DPD_MODE_DELAY + int "SPI Flash enter deep power-down time delay (in us)" + depends on ESP_SLEEP_SET_FLASH_DPD + default 25 + range 0 100 + help + When used to set the SPI Flash to enter the Deep Power-Down mode, the command is issued by driving + CS pin low, shifting the instruction code "B9H" and driving CS high, enter Deep Power-Down mode will + take the time duration of tDP before the supply current is reduced and Deep Power-down mode is + entered. The CS pin must keep high during the tDP time duration, adjust the value of this option to + configure the value of tDP, different types of flash require different tDP values, usually no more + than 20us, please refer to the datasheet of the used Flash to configure this option. + + config ESP_SLEEP_SPI_FLASH_EXIT_DPD_MODE_DELAY + int "SPI Flash exit from deep power-down time delay (in us)" + depends on ESP_SLEEP_SET_FLASH_DPD + default 40 + range 0 100 + help + When used to exit the SPI Flash from the Deep Power-Down mode, the command is issued by driving the + CS pin low, shifting the instruction code "ABH" and driving CS high, release from Deep Power-Down will + take the time duration of tRES1 before the SPI FLASH will resume normal operation and other command are + accepted. The CS pin must keep high during the tRES1 time duration, adjust the value of this option + to configure the value of tRES1, different types of flash require different tRES1 values, usually no + more than 35us, please refer to the datasheet of the used Flash to configure this option. + endmenu menu "RTC Clock Config" diff --git a/components/esp_hw_support/include/esp_private/esp_pmu.h b/components/esp_hw_support/include/esp_private/esp_pmu.h index b12b24c99c8..8bb1423f8fd 100644 --- a/components/esp_hw_support/include/esp_private/esp_pmu.h +++ b/components/esp_hw_support/include/esp_private/esp_pmu.h @@ -47,6 +47,7 @@ typedef enum { #define RTC_SLEEP_PD_MODEM PMU_SLEEP_PD_MODEM //!< Power down modem(include wifi, ble and 15.4) //These flags are not power domains, but will affect some sleep parameters +#define RTC_SLEEP_FLASH_DPD BIT(24) #define RTC_SLEEP_LP_PERIPH_USE_RC_FAST BIT(25) #define RTC_SLEEP_POWER_BY_VBAT BIT(26) #define RTC_SLEEP_DIG_USE_8M BIT(27) diff --git a/components/esp_hw_support/port/esp32/include/soc/rtc.h b/components/esp_hw_support/port/esp32/include/soc/rtc.h index 86f0dce4a67..214ee3de5f6 100644 --- a/components/esp_hw_support/port/esp32/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32/include/soc/rtc.h @@ -530,6 +530,7 @@ typedef struct rtc_sleep_config_s { #define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) #define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature #define RTC_SLEEP_XTAL_AS_RTC_FAST BIT(19) +#define RTC_SLEEP_FLASH_DPD BIT(20) /** * Default initializer for rtc_sleep_config_t * diff --git a/components/esp_hw_support/port/esp32c2/include/soc/rtc.h b/components/esp_hw_support/port/esp32c2/include/soc/rtc.h index 5310d7799ac..443625bdbe8 100644 --- a/components/esp_hw_support/port/esp32c2/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c2/include/soc/rtc.h @@ -567,6 +567,7 @@ typedef struct { #define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) #define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature #define RTC_SLEEP_XTAL_AS_RTC_FAST BIT(19) +#define RTC_SLEEP_FLASH_DPD BIT(20) /** * Default initializer for rtc_sleep_config_t diff --git a/components/esp_hw_support/port/esp32c3/include/soc/rtc.h b/components/esp_hw_support/port/esp32c3/include/soc/rtc.h index 99aa575fd3f..bd25c529060 100644 --- a/components/esp_hw_support/port/esp32c3/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32c3/include/soc/rtc.h @@ -615,6 +615,7 @@ typedef struct { #define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) #define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature #define RTC_SLEEP_XTAL_AS_RTC_FAST BIT(19) +#define RTC_SLEEP_FLASH_DPD BIT(20) /** * Default initializer for rtc_sleep_config_t diff --git a/components/esp_hw_support/port/esp32p4/pmu_init.c b/components/esp_hw_support/port/esp32p4/pmu_init.c index 2910f22dd30..53d6fcd3152 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_init.c +++ b/components/esp_hw_support/port/esp32p4/pmu_init.c @@ -91,7 +91,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_pa pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep); pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_mem_xpd); pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_logic_xpd); - if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100) && (mode == PMU_MODE_HP_SLEEP)) { + if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 300) && (mode == PMU_MODE_HP_SLEEP)) { pmu_ll_hp_enable_sleep_flash_ldo_channel(ctx->hal->dev, anlg->regulator0.xpd_0p1a); } pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, mode, anlg->regulator0.slp_logic_dbias); diff --git a/components/esp_hw_support/port/esp32p4/pmu_sleep.c b/components/esp_hw_support/port/esp32p4/pmu_sleep.c index 7f2a2c012b8..096b2a3239b 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32p4/pmu_sleep.c @@ -176,7 +176,11 @@ const pmu_sleep_config_t* pmu_sleep_config_default( config->digital = digital_default; pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(sleep_flags); - analog_default.hp_sys.analog.xpd_0p1a = 0; + if (sleep_flags & PMU_SLEEP_PD_VDDSDIO) { + analog_default.hp_sys.analog.xpd_0p1a = 0; + } else { + analog_default.hp_sys.analog.xpd_0p1a = 1; + } config->analog = analog_default; if (sleep_flags & RTC_SLEEP_POWER_BY_VBAT) { @@ -296,7 +300,7 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_xpd); pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_xpd); pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd); - if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100)) { + if (ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 300)) { pmu_ll_hp_enable_sleep_flash_ldo_channel(ctx->hal->dev, analog->hp_sys.analog.xpd_0p1a); } pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_dbias); diff --git a/components/esp_hw_support/port/esp32s2/include/soc/rtc.h b/components/esp_hw_support/port/esp32s2/include/soc/rtc.h index f610b6ec34d..8c74e62ab57 100644 --- a/components/esp_hw_support/port/esp32s2/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32s2/include/soc/rtc.h @@ -640,6 +640,7 @@ typedef struct { #define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) #define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature #define RTC_SLEEP_XTAL_AS_RTC_FAST BIT(19) +#define RTC_SLEEP_FLASH_DPD BIT(20) /** * Default initializer for rtc_sleep_config_t diff --git a/components/esp_hw_support/port/esp32s3/include/soc/rtc.h b/components/esp_hw_support/port/esp32s3/include/soc/rtc.h index 2adf7d49255..99646a1ba3f 100644 --- a/components/esp_hw_support/port/esp32s3/include/soc/rtc.h +++ b/components/esp_hw_support/port/esp32s3/include/soc/rtc.h @@ -626,6 +626,7 @@ typedef struct { #define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) #define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature #define RTC_SLEEP_XTAL_AS_RTC_FAST BIT(19) +#define RTC_SLEEP_FLASH_DPD BIT(20) /** * Default initializer for rtc_sleep_config_t diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 7a8398d6284..d1a9146de4f 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -26,6 +26,7 @@ #include "esp_private/sleep_retention.h" #include "esp_private/io_mux.h" #include "esp_private/critical_section.h" +#include "esp_private/spi_flash_os.h" #include "esp_log.h" #include "esp_newlib.h" #include "esp_timer.h" @@ -911,6 +912,14 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint esp_sleep_isolate_digital_gpio(); #endif +#if CONFIG_IDF_TARGET_ESP32P4 && CONFIG_ESP_SLEEP_SET_FLASH_DPD + if ((sleep_flags & RTC_SLEEP_FLASH_DPD) && (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 300))) { + /* Switch Flash from standby mode to deep powerdown mode */ + /* During bootloader phase following wakeup from deepsleep, flash will exit dpd mode */ + spi_flash_enable_deep_power_down_mode(true); + } +#endif + #if ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB && SOC_DEEP_SLEEP_SUPPORTED #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY esp_set_deep_sleep_wake_stub_default_entry(); @@ -943,21 +952,28 @@ static esp_err_t FORCE_IRAM_ATTR esp_sleep_start_safe(uint32_t sleep_flags, uint suspend_timers(sleep_flags); /* Cache Suspend 1: will wait cache idle in cache suspend */ suspend_cache(); - /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode. - In order to avoid the leakage of the SPI cs pin, hold it here */ - + if (!(sleep_flags & RTC_SLEEP_PD_VDDSDIO)) { +#if CONFIG_ESP_SLEEP_SET_FLASH_DPD + if (sleep_flags & RTC_SLEEP_FLASH_DPD) { + /* Switch Flash from standby mode to deep powerdown mode */ + spi_flash_enable_deep_power_down_mode(true); + } +#endif #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP - if(!(sleep_flags & RTC_SLEEP_PD_VDDSDIO) && (sleep_flags & PMU_SLEEP_PD_TOP)) { + /* On esp32c6, only the lp_aon pad hold function can only hold the GPIO state in the active mode. + In order to avoid the leakage of the SPI cs pin, hold it here */ + if(sleep_flags & PMU_SLEEP_PD_TOP) { #if CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND - /* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */ - gpio_ll_hold_en(&GPIO, MSPI_IOMUX_PIN_NUM_CS0); + /* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */ + gpio_ll_hold_en(&GPIO, MSPI_IOMUX_PIN_NUM_CS0); #endif #if CONFIG_ESP_SLEEP_PSRAM_LEAKAGE_WORKAROUND && CONFIG_SPIRAM - /* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */ - gpio_ll_hold_en(&GPIO, MSPI_IOMUX_PIN_NUM_CS1); + /* Cache suspend also means SPI bus IDLE, then we can hold SPI CS pin safely */ + gpio_ll_hold_en(&GPIO, MSPI_IOMUX_PIN_NUM_CS1); +#endif + } #endif } -#endif #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP if (sleep_flags & PMU_SLEEP_PD_TOP) { @@ -1408,6 +1424,13 @@ static SLEEP_FN_ATTR esp_err_t esp_light_sleep_inner(uint32_t sleep_flags, uint3 #endif // Wait for the flash chip to start up esp_rom_delay_us(flash_enable_time_us); + } else { +#if CONFIG_ESP_SLEEP_SET_FLASH_DPD + if (sleep_flags & RTC_SLEEP_FLASH_DPD) { + //Release Flash out from deep powerdown mode + spi_flash_enable_deep_power_down_mode(false); + } +#endif } #if CONFIG_ESP_SLEEP_CACHE_SAFE_ASSERTION @@ -1592,6 +1615,23 @@ esp_err_t esp_light_sleep_start(void) s_config.sleep_time_adjustment -= flash_enable_time_us; } } + } else if (!(sleep_flags & RTC_SLEEP_PD_VDDSDIO)) { +#if CONFIG_ESP_SLEEP_SET_FLASH_DPD + const uint32_t flash_enable_dpd_us = spi_flash_dpd_get_enter_duration() + spi_flash_dpd_get_exit_duration(); + if (s_config.sleep_duration > flash_enable_dpd_us) { + if (s_config.sleep_time_overhead_out < flash_enable_dpd_us) { + s_config.sleep_time_adjustment += flash_enable_dpd_us; + } + } else { + /** + * Minimum sleep time is not enough, then reject flash enter deep power-down mode + */ + sleep_flags &= ~RTC_SLEEP_FLASH_DPD; + if (s_config.sleep_time_overhead_out > flash_enable_dpd_us) { + s_config.sleep_time_adjustment -= flash_enable_dpd_us; + } + } +#endif } periph_inform_out_light_sleep_overhead(s_config.sleep_time_adjustment - sleep_time_overhead_in); @@ -2757,11 +2797,6 @@ static SLEEP_FN_ATTR uint32_t get_power_down_flags(void) if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option == ESP_PD_OPTION_AUTO) { #ifndef CONFIG_ESP_SLEEP_POWER_DOWN_FLASH s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option = ESP_PD_OPTION_ON; -#endif -#if CONFIG_IDF_TARGET_ESP32P4 - if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100)) { - s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option = ESP_PD_OPTION_ON; - } #endif } #endif @@ -2850,8 +2885,15 @@ static SLEEP_FN_ATTR uint32_t get_power_down_flags(void) } #endif +#if CONFIG_ESP_SLEEP_SET_FLASH_DPD + if (!(pd_flags & RTC_SLEEP_PD_VDDSDIO)) { + // Flash power domain will disable DPD mode. + pd_flags |= RTC_SLEEP_FLASH_DPD; + } +#endif + #if CONFIG_IDF_TARGET_ESP32P4 - if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 100)) { + if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 300)) { if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { ESP_LOGE(TAG, "ESP32P4 chips lower than v1.0 are not allowed to power down the Flash"); } @@ -2934,6 +2976,11 @@ static SLEEP_FN_ATTR uint32_t get_sleep_flags(uint32_t sleep_flags, bool deepsle if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) { sleep_flags &= ~RTC_SLEEP_PD_RTC_PERIPH; } + /* The LDO VO1 channel that powers the Flash on esp32p4( +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_log.h" +#include "esp_attr.h" +#include "spi_flash_chip_generic.h" +#include "hal/spi_flash_hal.h" + +/******************************************************************************* + * Flash deep power-down mode. + * DPD: Deep power-down mode. + * TDP: CS high to deep power-down mode duration. + * TRES1: CS high to standby mode without ID read duration. + * + * Different flash chips might have different deep power-down strategy. + * 1. Most flash chips send B9H to enter DPD and send ABH to exist DPD. + * 2. Some flash chips send ABH followed by 3-dummy bytes to get device ID. + * 3. Some flash chips send B9H to enter PD(power-down) → send 79H to enter UDPD(ultra-deep power-down mode); send FFH to exit UDPD → send ABH to exit PD (ABH). + * 4. Some flash chips do nothing. + ******************************************************************************/ + +__attribute__((unused)) const static char *DPD_TAG = "flash DPD"; + +#ifdef CONFIG_ESP_SLEEP_SPI_FLASH_ENTER_DPD_MODE_DELAY +#define SPI_FLASH_TDP_SAFE_VAL_US CONFIG_ESP_SLEEP_SPI_FLASH_ENTER_DPD_MODE_DELAY +#else +#define SPI_FLASH_TDP_SAFE_VAL_US (25) +#endif + +#ifdef CONFIG_ESP_SLEEP_SPI_FLASH_EXIT_DPD_MODE_DELAY +#define SPI_FLASH_TRES1_SAFE_VAL_US CONFIG_ESP_SLEEP_SPI_FLASH_EXIT_DPD_MODE_DELAY +#else +#define SPI_FLASH_TRES1_SAFE_VAL_US (40) +#endif + +/* + * Note: This file should only be compiled when DPD_ON, which is only available when (!APP_BUILD_TYPE_PURE_RAM_APP && !ESP_SLEEP_POWER_DOWN_FLASH). + * However when DPD_ON, there are still some cases this file is not actually used: + * TODO: PM-623 + */ + +uint32_t spi_flash_dpd_get_enter_duration(void) +{ +#ifndef CONFIG_ESP_SLEEP_SPI_FLASH_ENTER_DPD_MODE_DELAY + ESP_EARLY_LOGW(DPD_TAG, "No DPD enter delay value defined. Using default safe delay value. Verify with your flash datasheet."); +#endif + return SPI_FLASH_TDP_SAFE_VAL_US; +} + +uint32_t spi_flash_dpd_get_exit_duration(void) +{ +#ifndef CONFIG_ESP_SLEEP_SPI_FLASH_EXIT_DPD_MODE_DELAY + ESP_EARLY_LOGW(DPD_TAG, "No DPD exit delay value defined. Using default safe delay value. Verify with your flash datasheet."); +#endif + return SPI_FLASH_TRES1_SAFE_VAL_US; +} + +static esp_err_t spi_flash_enter_dpd(void) +{ + esp_err_t ret = spi_flash_hal_enter_dpd_mode(esp_flash_default_chip->host); + esp_rom_delay_us(spi_flash_dpd_get_enter_duration()); + + return ret; +} + +static esp_err_t spi_flash_exit_dpd(void) +{ + esp_err_t ret = spi_flash_hal_exit_dpd_mode(esp_flash_default_chip->host); + esp_rom_delay_us(spi_flash_dpd_get_exit_duration()); + + return ret; +} + +esp_err_t spi_flash_enable_deep_power_down_mode(bool enable) +{ + esp_err_t ret = ESP_OK; + + if (enable) { + ret = spi_flash_enter_dpd(); + } else { + ret = spi_flash_exit_dpd(); + } + + return ret; +} diff --git a/docs/en/api-guides/low-power-mode/low-power-mode-soc.rst b/docs/en/api-guides/low-power-mode/low-power-mode-soc.rst index 1fe6927c3e2..97f9f4300a5 100644 --- a/docs/en/api-guides/low-power-mode/low-power-mode-soc.rst +++ b/docs/en/api-guides/low-power-mode/low-power-mode-soc.rst @@ -385,6 +385,9 @@ Recommended Configuration * - Power down flash in light sleep (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) - OFF + * - Set flash into deep power-down mode in light sleep (:ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`) + - OFF + * - ``max_freq_mhz`` - The maximum CPU frequency supported by {IDF_TARGET_NAME} @@ -442,6 +445,9 @@ Recommended Configuration * - Power down flash in light sleep (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) - OFF + * - Set flash into deep power-down mode in light sleep (:ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`) + - OFF + * - ``max_freq_mhz`` - The maximum CPU frequency supported by {IDF_TARGET_NAME} @@ -496,6 +502,9 @@ Recommended Configuration * - Power down flash in light sleep (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) - OFF + * - Set flash into deep power-down mode in light sleep (:ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`) + - OFF + * - ``max_freq_mhz`` - The maximum CPU frequency supported by {IDF_TARGET_NAME} @@ -589,6 +598,9 @@ Recommended Configuration * - Power down flash in light sleep (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) - OFF + * - Set flash into deep power-down mode in light sleep (:ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`) + - OFF + * - ``max_freq_mhz`` - 120 diff --git a/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst b/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst index ef8b0f42a88..30e0223d35c 100644 --- a/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst +++ b/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst @@ -24,6 +24,7 @@ Feature Supported by ESP-IDF but Not in Chip-ROM - :ref:`CONFIG_SPI_FLASH_DANGEROUS_WRITE`, enabling this option checks for flash programming to certain protected regions like bootloader, partition table or application itself. - :ref:`CONFIG_SPI_FLASH_ENABLE_COUNTERS`, enabling this option to collect performance data for ESP-IDF SPI flash driver APIs. - :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND`, enabling this option to automatically suspend or resume a long flash operation when short flash operation happens. Note that this feature is an optional feature, please do read :ref:`auto-suspend-intro` for more limitations. + - :ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`, enabling this option allows the flash to enter deep power-down (DPD) mode during sleep for lower power consumption. Note that this feature is an optional feature, please do read :ref:`deep-power-down-mode` for more limitations. :ESP_ROM_HAS_SPI_FLASH_MMAP and SOC_SPIRAM_XIP_SUPPORTED and not esp32s3: - :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM`, enabling this option allows you to use external PSRAM as instruction cache and read-only data cache. Some functions in the ROM don't support this usage, and an ESP-IDF version of these functions is provided. :esp32s3: - :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` and :ref:`CONFIG_SPIRAM_RODATA`, enabling these options allows you to use external PSRAM as instruction cache and read-only data cache. Some functions in the ROM don't support this usage, and an ESP-IDF version of these functions is provided. diff --git a/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst b/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst index cb1c63d0bda..247cff269c3 100644 --- a/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst +++ b/docs/en/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst @@ -11,6 +11,8 @@ Some features are not supported on all ESP chips and flash chips. You can check - :ref:`high-performance-mode` +- :ref:`deep-power-down-mode` + - :ref:`32-bit-flash-doc` - :ref:`oct-flash-doc` @@ -137,6 +139,18 @@ The support for ESP32-S2, ESP32-C3, ESP32-C6, ESP32-H2, and ESP32-P4 may be adde 3. XM25QH64C (ID: 0x204017) 4. XM25QH128C (ID: 0x204018) +.. _deep-power-down-mode: + +SPI Flash Deep Power-Down Mode +------------------------------- + +Currently, only ESP32-H21, ESP32-H4 and ESP32-P4(version less v3) support this feature. + +This feature is not yet supported on other ESP32 series chips. If you have this requirement, you may submit a request to Espressif Systems officially. + +Deep Power-Down (DPD) mode is a power-saving mode supported by most SPI flash chips. Compared to the standby mode (where the chip select signal remains asserted), SPI flash consumes significantly less power in DPD mode—typically reducing current by 10 µA or more. + +If you plan to use a customized SPI flash model, or if you use other ESP32-series chips, please make sure to consult the corresponding SPI flash datasheet or contact Espressif directly. .. _32-bit-flash-doc: diff --git a/docs/en/api-reference/system/sleep_modes.rst b/docs/en/api-reference/system/sleep_modes.rst index 613b0041af1..67c2f3f3c4e 100644 --- a/docs/en/api-reference/system/sleep_modes.rst +++ b/docs/en/api-reference/system/sleep_modes.rst @@ -434,6 +434,17 @@ However, for those who have fully understood the risk and are still willing to p - ESP-IDF does not provide any mechanism that can power down the flash in all conditions when Light-sleep. - :cpp:func:`esp_deep_sleep_start` function forces power down flash regardless of user configuration. +Flash Entering Deep Power-Down Mode +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +In addition to reducing power consumption by completely powering off the flash, you can further lower flash power usage during sleep by enabling the Kconfig option :ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`. Compared with fully cutting off the flash power, this feature avoids the extra delay caused by re-powering the flash when the chip wakes up from sleep, while still achieving extremely low power consumption. Most flashes draw less than 1 µA when entering Deep Power-Down (DPD) mode. + +In almost all use cases, using DPD mode provides better overall benefits than fully powering off the flash, offering both improved safety and lower power consumption. + +.. warning:: + + Before using this feature, check the datasheet of the flash device used on your chip to ensure it supports the Deep Power-Down mode. + Configuring IOs (Deep-sleep Only) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/zh_CN/api-guides/low-power-mode/low-power-mode-soc.rst b/docs/zh_CN/api-guides/low-power-mode/low-power-mode-soc.rst index 8a2950b1906..7cec7b73eec 100644 --- a/docs/zh_CN/api-guides/low-power-mode/low-power-mode-soc.rst +++ b/docs/zh_CN/api-guides/low-power-mode/low-power-mode-soc.rst @@ -385,6 +385,9 @@ Light-sleep 模式配置 * - 在 light sleep 状态关闭 flash 供电 (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) - OFF + * - 在 light sleep 状态配置 flash 进入 deep power-down 模式 (:ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`) + - OFF + * - ``max_freq_mhz`` - {IDF_TARGET_NAME} 支持的最大 CPU 频率 @@ -442,6 +445,9 @@ Light-sleep 模式配置 * - 在 light sleep 状态关闭 flash 供电 (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) - OFF + * - 在 light sleep 状态配置 flash 进入 deep power-down 模式 (:ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`) + - OFF + * - ``max_freq_mhz`` - {IDF_TARGET_NAME} 支持的最大 CPU 频率 @@ -496,6 +502,9 @@ Light-sleep 模式配置 * - 在 light sleep 状态关闭 flash 供电 (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) - OFF + * - 在 light sleep 状态配置 flash 进入 deep power-down 模式 (:ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`) + - OFF + * - ``max_freq_mhz`` - {IDF_TARGET_NAME} 支持的最大 CPU 频率 @@ -589,6 +598,9 @@ Light-sleep 模式配置 * - 在 light sleep 状态关闭 flash 供电 (:ref:`CONFIG_ESP_SLEEP_POWER_DOWN_FLASH`) - OFF + * - 在 light sleep 状态配置 flash 进入 deep power-down 模式 (:ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`) + - OFF + * - ``max_freq_mhz`` - 120 diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst index d3524538bd4..bca34173e23 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst @@ -24,6 +24,7 @@ ESP-IDF 支持但不包含在芯片 ROM 中的功能 - :ref:`CONFIG_SPI_FLASH_DANGEROUS_WRITE`,启用此选项会检查是否对某些受保护的区域(如引导加载程序、分区表或应用程序本身)进行了 flash 编程。 - :ref:`CONFIG_SPI_FLASH_ENABLE_COUNTERS`,启用此选项以收集 ESP-IDF SPI flash 驱动程序 API 的性能数据。 - :ref:`CONFIG_SPI_FLASH_AUTO_SUSPEND`,启用此选项可在 flash 短时操作时自动挂起或恢复 flash 长时操作。请注意,此功能为可选功能,详情请参阅 :ref:`auto-suspend-intro`。 + - :ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`,启用此选项可在休眠时配置 flash 进入 deep power-down 模式以降低功耗。请注意,此功能为可选功能,详情请参阅 :ref:`deep-power-down-mode`。 :ESP_ROM_HAS_SPI_FLASH_MMAP and SOC_SPIRAM_XIP_SUPPORTED and not esp32s3: - :ref:`CONFIG_SPIRAM_XIP_FROM_PSRAM`,启用该选项后,可将外部 PSRAM 用作指令 cache 和只读数据 cache。但请注意,ROM 中的某些函数不支持此用法,而 ESP-IDF 提供了这些 ROM 函数的替代版本。 :esp32s3: - 启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 和 :ref:`CONFIG_SPIRAM_RODATA` 后,可将外部 PSRAM 用作指令 cache 和只读数据 cache。但请注意,ROM 中的某些函数不支持此用法,而 ESP-IDF 提供了这些 ROM 函数的替代版本。 diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst index e035234544e..abb1b624517 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_optional_feature.rst @@ -11,6 +11,8 @@ flash 的可选功能 - :ref:`high-performance-mode` +- :ref:`deep-power-down-mode` + - :ref:`32-bit-flash-doc` - :ref:`oct-flash-doc` @@ -137,6 +139,18 @@ QSPI flash 芯片的高性能模式 3. XM25QH64C (ID: 0x204017) 4. XM25QH128C (ID: 0x204018) +.. _deep-power-down-mode: + +SPI flash 芯片的深度掉电模式 +---------------------------------- + +目前仅有 ESP32-H21, ESP32-H4 和 ESP32-P4(版本小于v3) 支持此功能。 + +其他 ESP32 系列芯片暂未支持此功能。若你有相关需求,可向乐鑫(Espressif)官方提出申请。 + +深度掉电模式是大多数 SPI flash 芯片均支持的一种电源模式,相较于 standby 模式(保持片选信号有效),SPI flash 在此模式下的功耗表现更优,这能使电流降低约 10 uA。 + +若你计划在 ESP32-H21 或 ESP32-H4 上使用其他型号的闪存芯片,或是在开发其他 ESP32 系列芯片的相关项目,请务必查阅对应的 SPI flash 数据手册,或直接向我们咨询。 .. _32-bit-flash-doc: diff --git a/docs/zh_CN/api-reference/system/sleep_modes.rst b/docs/zh_CN/api-reference/system/sleep_modes.rst index 9af83b591a1..a83bcb21c7d 100644 --- a/docs/zh_CN/api-reference/system/sleep_modes.rst +++ b/docs/zh_CN/api-reference/system/sleep_modes.rst @@ -434,6 +434,17 @@ flash 断电 - Light-sleep 模式下,ESP-IDF 没有提供保证 flash 一定会被断电的机制。 - 不管用户的配置如何,函数 :cpp:func:`esp_deep_sleep_start` 都会强制断电 flash。 +flash 进入 deep power-down 模式 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +除了通过让 flash 完全断电来降低芯片功耗之外,还可以通过启用 Kconfig 配置项 :ref:`CONFIG_ESP_SLEEP_SET_FLASH_DPD`,进一步减少休眠期间 flash 的功耗。与直接对 flash 断电相比,该功能能够避免芯片从休眠唤醒时 flash 重新上电所带来的额外延迟,同时也能保持极低的功耗。大多数 flash 在进入 Deep Power-Down(DPD)模式后电流消耗低于 1 µA。 + +在几乎所有应用场景中,使用 DPD 模式都比直接断电 flash 更具优势,兼顾了安全性与低功耗表现。 + +.. warning:: + + 使用该功能前需要查阅使用芯片所搭载的 flash 的技术手册是否支持 deep power-down 模式。 + 配置 IO(仅适用于 Deep-sleep) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^