feat(spi_flash): add flash deep power down support in spi flash

This commit is contained in:
hebinglin
2025-11-28 20:49:41 +08:00
parent 8edaf6b92e
commit e29c2c9a36
32 changed files with 491 additions and 3 deletions
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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)
@@ -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.
*
@@ -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.
*
@@ -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)
+45
View File
@@ -214,6 +214,51 @@ 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 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 20
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"
+5
View File
@@ -26,6 +26,11 @@ else()
"spi_flash_hpm_enable.c")
endif()
if(CONFIG_ESP_SLEEP_SET_FLASH_DPD)
list(APPEND srcs
"spi_flash_dpd_enable.c")
endif()
# New implementation after IDF v4.0
list(APPEND srcs
"spi_flash_chip_drivers.c"
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -156,6 +156,34 @@ const spi_flash_hpm_dummy_conf_t *spi_flash_hpm_get_dummy(void);
bool spi_flash_hpm_dummy_adjust(void);
#endif //CONFIG_SPI_FLASH_HPM_ON
#if CONFIG_ESP_SLEEP_SET_FLASH_DPD
/**
* @brief Get the duration of entering deep power-down mode.
*
* @return Entering deep power-down mode time(tDp), in microseconds.
*/
uint32_t spi_flash_dpd_get_enter_duration(void);
/**
* @brief Get the duration of exiting deep power-down mode.
*
* @return Exiting deep power-down mode time(tRES1), in microseconds.
*/
uint32_t spi_flash_dpd_get_exit_duration(void);
/**
* @brief Enable or disable SPI flash deep power-down mode.
*
* @param bool status. True: flash enable deep power-down mode. False: flash disable deep power-down mode.
*
* @note If using self-provided flash (not the chips factory-default flash), consult its datasheet to use this API safely.
*
* @return ESP_OK if success.
*/
esp_err_t spi_flash_enable_deep_power_down_mode(bool enable);
#endif
#if SOC_SPI_MEM_SUPPORT_WRAP
/**
* @brief set wrap size of flash
+3
View File
@@ -73,6 +73,9 @@ entries:
if SPI_FLASH_HPM_ON = y:
spi_flash_hpm_enable (noflash)
if ESP_SLEEP_SET_FLASH_DPD = y:
spi_flash_dpd_enable (noflash)
[mapping:spi_flash_hal]
archive: libesp_hal_mspi.a
entries:
@@ -0,0 +1,91 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdint.h>
#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;
}