mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
spi_flash: 2nd stage for supporting flash suspend. (1). Support more esp chips (2). Improve real-time performance (3). Making timing more stable (4) Add documents
This commit is contained in:
parent
476e50b026
commit
ed96dadd06
@ -399,6 +399,16 @@ static inline void spi_flash_ll_set_cs_setup(spi_dev_t *dev, uint32_t cs_setup_t
|
|||||||
dev->ctrl2.setup_time = cs_setup_time - 1;
|
dev->ctrl2.setup_time = cs_setup_time - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set lock for SPI0 so that spi0 can request new cache request after a cache transfer.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void spi_flash_ll_set_pe_bit(spi_dev_t *dev)
|
||||||
|
{
|
||||||
|
// Not supported on esp32
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the spi flash source clock frequency. Used for calculating
|
* Get the spi flash source clock frequency. Used for calculating
|
||||||
* the divider parameters.
|
* the divider parameters.
|
||||||
|
@ -149,6 +149,16 @@ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void gpspi_flash_ll_set_pe_bit(spi_dev_t *dev)
|
||||||
|
{
|
||||||
|
// Not supported on GPSPI
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the host is idle to perform new commands.
|
* Check whether the host is idle to perform new commands.
|
||||||
*
|
*
|
||||||
|
@ -64,6 +64,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev)
|
#define spi_flash_ll_set_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev)
|
||||||
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) gpspi_flash_ll_set_pe_bit((spi_dev_t*)dev)
|
||||||
#else
|
#else
|
||||||
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
||||||
#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev)
|
#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev)
|
||||||
@ -91,6 +92,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev)
|
#define spi_flash_ll_set_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev)
|
||||||
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) spimem_flash_ll_set_pe_bit((spi_mem_dev_t*)dev)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ extern "C" {
|
|||||||
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
||||||
|
|
||||||
#define SPIMEM_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ (60)
|
#define SPIMEM_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ (60)
|
||||||
|
#define SPIMEM_FLASH_LL_SPI0_MAX_LOCK_VAL_MSPI_TICKS (0x1f)
|
||||||
|
|
||||||
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
||||||
|
|
||||||
@ -207,6 +208,30 @@ static inline void spimem_flash_ll_set_read_sus_status(spi_mem_dev_t *dev, uint3
|
|||||||
dev->flash_sus_ctrl.pesr_end_msk = sus_conf;
|
dev->flash_sus_ctrl.pesr_end_msk = sus_conf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the delay after Suspend/Resume
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param dly_val delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dly_val)
|
||||||
|
{
|
||||||
|
dev->ctrl1.cs_hold_dly_res = dly_val;
|
||||||
|
dev->sus_status.flash_pes_dly_128 = 1;
|
||||||
|
dev->sus_status.flash_per_dly_128 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the cs hold delay time(used to set the minimum CS high time tSHSL)
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param cs_hold_delay cs hold delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t cs_hold_delay)
|
||||||
|
{
|
||||||
|
SPIMEM0.ctrl2.cs_hold_delay = cs_hold_delay;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize auto wait idle mode
|
* Initialize auto wait idle mode
|
||||||
*
|
*
|
||||||
@ -232,6 +257,35 @@ static inline bool spimem_flash_ll_sus_status(spi_mem_dev_t *dev)
|
|||||||
return dev->sus_status.flash_sus;
|
return dev->sus_status.flash_sus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set lock for SPI0 so that spi0 can request new cache request after a cache transfer.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param lock_time Lock delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_sus_set_spi0_lock_trans(spi_mem_dev_t *dev, uint32_t lock_time)
|
||||||
|
{
|
||||||
|
dev->sus_status.spi0_lock_en = 1;
|
||||||
|
SPIMEM0.fsm.cspi_lock_delay_time = lock_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get tsus unit values in SPI_CLK cycles
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @return uint32_t tsus unit values
|
||||||
|
*/
|
||||||
|
static inline uint32_t spimem_flash_ll_get_tsus_unit_in_cycles(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
uint32_t tsus_unit = 0;
|
||||||
|
if (dev->sus_status.flash_pes_dly_128 == 1) {
|
||||||
|
tsus_unit = 128;
|
||||||
|
} else {
|
||||||
|
tsus_unit = 4;
|
||||||
|
}
|
||||||
|
return tsus_unit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable/disable write protection for the flash chip.
|
* Enable/disable write protection for the flash chip.
|
||||||
*
|
*
|
||||||
@ -320,6 +374,17 @@ static inline void spimem_flash_ll_user_start(spi_mem_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
* This function is combined with `spimem_flash_ll_user_start`. The pe_bit will be cleared automatically once the operation done.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_pe_bit(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
dev->cmd.flash_pe = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the host is idle to perform new commands.
|
* Check whether the host is idle to perform new commands.
|
||||||
*
|
*
|
||||||
|
@ -140,6 +140,16 @@ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void gpspi_flash_ll_set_pe_bit(spi_dev_t *dev)
|
||||||
|
{
|
||||||
|
// Not supported on GPSPI
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set HD pin high when flash work at spi mode.
|
* Set HD pin high when flash work at spi mode.
|
||||||
*
|
*
|
||||||
|
@ -64,6 +64,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev)
|
#define spi_flash_ll_set_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev)
|
||||||
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) gpspi_flash_ll_set_pe_bit((spi_dev_t*)dev)
|
||||||
#else
|
#else
|
||||||
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
||||||
#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev)
|
#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev)
|
||||||
@ -91,6 +92,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev)
|
#define spi_flash_ll_set_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev)
|
||||||
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) spimem_flash_ll_set_pe_bit((spi_mem_dev_t*)dev)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@ extern "C" {
|
|||||||
#define spimem_flash_ll_get_hw(host_id) (((host_id)==SPI1_HOST ? &SPIMEM1 : NULL ))
|
#define spimem_flash_ll_get_hw(host_id) (((host_id)==SPI1_HOST ? &SPIMEM1 : NULL ))
|
||||||
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
||||||
|
|
||||||
|
#define SPIMEM_FLASH_LL_SPI0_MAX_LOCK_VAL_MSPI_TICKS (0x1f)
|
||||||
|
|
||||||
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
@ -207,6 +209,30 @@ static inline void spimem_flash_ll_set_read_sus_status(spi_mem_dev_t *dev, uint3
|
|||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_ctrl, pesr_end_msk, sus_conf);
|
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_ctrl, pesr_end_msk, sus_conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the delay after Suspend/Resume
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param dly_val delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dly_val)
|
||||||
|
{
|
||||||
|
dev->ctrl1.cs_hold_dly_res = dly_val;
|
||||||
|
dev->sus_status.pes_dly_128 = 1;
|
||||||
|
dev->sus_status.per_dly_128 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the cs hold delay time(used to set the minimum CS high time tSHSL)
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param cs_hold_delay cs hold delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t cs_hold_delay)
|
||||||
|
{
|
||||||
|
SPIMEM0.ctrl2.cs_hold_delay = cs_hold_delay;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize auto wait idle mode
|
* Initialize auto wait idle mode
|
||||||
*
|
*
|
||||||
@ -232,6 +258,35 @@ static inline bool spimem_flash_ll_sus_status(spi_mem_dev_t *dev)
|
|||||||
return dev->sus_status.flash_sus;
|
return dev->sus_status.flash_sus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set lock for SPI0 so that spi0 can request new cache request after a cache transfer.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param lock_time Lock delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_sus_set_spi0_lock_trans(spi_mem_dev_t *dev, uint32_t lock_time)
|
||||||
|
{
|
||||||
|
dev->sus_status.spi0_lock_en = 1;
|
||||||
|
SPIMEM0.fsm.cspi_lock_delay_time = lock_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get tsus unit values in SPI_CLK cycles
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @return uint32_t tsus unit values
|
||||||
|
*/
|
||||||
|
static inline uint32_t spimem_flash_ll_get_tsus_unit_in_cycles(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
uint32_t tsus_unit = 0;
|
||||||
|
if (dev->sus_status.pes_dly_128 == 1) {
|
||||||
|
tsus_unit = 128;
|
||||||
|
} else {
|
||||||
|
tsus_unit = 4;
|
||||||
|
}
|
||||||
|
return tsus_unit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable/disable write protection for the flash chip.
|
* Enable/disable write protection for the flash chip.
|
||||||
*
|
*
|
||||||
@ -320,6 +375,17 @@ static inline void spimem_flash_ll_user_start(spi_mem_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
* This function is combined with `spimem_flash_ll_user_start`. The pe_bit will be cleared automatically once the operation done.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_pe_bit(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
dev->cmd.flash_pe = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the host is idle to perform new commands.
|
* Check whether the host is idle to perform new commands.
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -140,6 +140,16 @@ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void gpspi_flash_ll_set_pe_bit(spi_dev_t *dev)
|
||||||
|
{
|
||||||
|
// Not supported on GPSPI
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set HD pin high when flash work at spi mode.
|
* Set HD pin high when flash work at spi mode.
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -65,6 +65,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
||||||
#define spi_flash_ll_set_extra_address(dev, extra_addr) { /* Not supported on gpspi on ESP32-C6*/ }
|
#define spi_flash_ll_set_extra_address(dev, extra_addr) { /* Not supported on gpspi on ESP32-C6*/ }
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) gpspi_flash_ll_set_pe_bit((spi_dev_t*)dev)
|
||||||
#else
|
#else
|
||||||
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
||||||
#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev)
|
#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev)
|
||||||
@ -92,6 +93,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
||||||
#define spi_flash_ll_set_extra_address(dev, extra_addr) spimem_flash_ll_set_extra_address((spi_mem_dev_t*)dev, extra_addr)
|
#define spi_flash_ll_set_extra_address(dev, extra_addr) spimem_flash_ll_set_extra_address((spi_mem_dev_t*)dev, extra_addr)
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) spimem_flash_ll_set_pe_bit((spi_mem_dev_t*)dev)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -33,6 +33,8 @@ extern "C" {
|
|||||||
#define spimem_flash_ll_get_hw(host_id) (((host_id)==SPI1_HOST ? &SPIMEM1 : NULL ))
|
#define spimem_flash_ll_get_hw(host_id) (((host_id)==SPI1_HOST ? &SPIMEM1 : NULL ))
|
||||||
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
||||||
|
|
||||||
|
#define SPIMEM_FLASH_LL_SPI0_MAX_LOCK_VAL_MSPI_TICKS (0x1f)
|
||||||
|
|
||||||
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
@ -208,6 +210,30 @@ static inline void spimem_flash_ll_set_read_sus_status(spi_mem_dev_t *dev, uint3
|
|||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_ctrl, pesr_end_msk, sus_conf);
|
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_ctrl, pesr_end_msk, sus_conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the delay after Suspend/Resume
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param dly_val delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dly_val)
|
||||||
|
{
|
||||||
|
dev->ctrl1.cs_hold_dly_res = dly_val;
|
||||||
|
dev->sus_status.flash_per_dly_128 = 1;
|
||||||
|
dev->sus_status.flash_pes_dly_128 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the cs hold delay time(used to set the minimum CS high time tSHSL)
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param cs_hold_delay cs hold delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t cs_hold_delay)
|
||||||
|
{
|
||||||
|
SPIMEM0.ctrl2.cs_hold_delay = cs_hold_delay;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize auto wait idle mode
|
* Initialize auto wait idle mode
|
||||||
*
|
*
|
||||||
@ -233,6 +259,35 @@ static inline bool spimem_flash_ll_sus_status(spi_mem_dev_t *dev)
|
|||||||
return dev->sus_status.flash_sus;
|
return dev->sus_status.flash_sus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set lock for SPI0 so that spi0 can request new cache request after a cache transfer.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param lock_time Lock delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_sus_set_spi0_lock_trans(spi_mem_dev_t *dev, uint32_t lock_time)
|
||||||
|
{
|
||||||
|
dev->sus_status.spi0_lock_en = 1;
|
||||||
|
SPIMEM0.fsm.lock_delay_time = lock_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get tsus unit values in SPI_CLK cycles
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @return uint32_t tsus unit values
|
||||||
|
*/
|
||||||
|
static inline uint32_t spimem_flash_ll_get_tsus_unit_in_cycles(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
uint32_t tsus_unit = 0;
|
||||||
|
if (dev->sus_status.flash_pes_dly_128 == 1) {
|
||||||
|
tsus_unit = 128;
|
||||||
|
} else {
|
||||||
|
tsus_unit = 4;
|
||||||
|
}
|
||||||
|
return tsus_unit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable/disable write protection for the flash chip.
|
* Enable/disable write protection for the flash chip.
|
||||||
*
|
*
|
||||||
@ -321,6 +376,17 @@ static inline void spimem_flash_ll_user_start(spi_mem_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
* This function is combined with `spimem_flash_ll_user_start`. The pe_bit will be cleared automatically once the operation done.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_pe_bit(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
dev->cmd.flash_pe = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the host is idle to perform new commands.
|
* Check whether the host is idle to perform new commands.
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -140,6 +140,16 @@ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void gpspi_flash_ll_set_pe_bit(spi_dev_t *dev)
|
||||||
|
{
|
||||||
|
// Not supported on GPSPI
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set HD pin high when flash work at spi mode.
|
* Set HD pin high when flash work at spi mode.
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@ -65,6 +65,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
||||||
#define spi_flash_ll_set_extra_address(dev, extra_addr) { /* Not supported on gpspi on ESP32-H2*/ }
|
#define spi_flash_ll_set_extra_address(dev, extra_addr) { /* Not supported on gpspi on ESP32-H2*/ }
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) gpspi_flash_ll_set_pe_bit((spi_dev_t*)dev)
|
||||||
#else
|
#else
|
||||||
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
||||||
#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev)
|
#define spi_flash_ll_cmd_is_done(dev) spimem_flash_ll_cmd_is_done((spi_mem_dev_t*)dev)
|
||||||
@ -92,6 +93,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
||||||
#define spi_flash_ll_set_extra_address(dev, extra_addr) spimem_flash_ll_set_extra_address((spi_mem_dev_t*)dev, extra_addr)
|
#define spi_flash_ll_set_extra_address(dev, extra_addr) spimem_flash_ll_set_extra_address((spi_mem_dev_t*)dev, extra_addr)
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) spimem_flash_ll_set_pe_bit((spi_mem_dev_t*)dev)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@ extern "C" {
|
|||||||
#define spimem_flash_ll_get_hw(host_id) (((host_id)==SPI1_HOST ? &SPIMEM1 : NULL ))
|
#define spimem_flash_ll_get_hw(host_id) (((host_id)==SPI1_HOST ? &SPIMEM1 : NULL ))
|
||||||
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
||||||
|
|
||||||
|
#define SPIMEM_FLASH_LL_SPI0_MAX_LOCK_VAL_MSPI_TICKS (0x1f)
|
||||||
|
|
||||||
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
@ -210,6 +212,30 @@ static inline void spimem_flash_ll_set_read_sus_status(spi_mem_dev_t *dev, uint3
|
|||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_ctrl, pesr_end_msk, sus_conf);
|
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_sus_ctrl, pesr_end_msk, sus_conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the delay after Suspend/Resume
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param dly_val delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dly_val)
|
||||||
|
{
|
||||||
|
dev->ctrl1.cs_hold_dly_res = dly_val;
|
||||||
|
dev->sus_status.flash_per_dly_128 = 1;
|
||||||
|
dev->sus_status.flash_pes_dly_128 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the cs hold delay time(used to set the minimum CS high time tSHSL)
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param cs_hold_delay cs hold delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t cs_hold_delay)
|
||||||
|
{
|
||||||
|
SPIMEM0.ctrl2.cs_hold_delay = cs_hold_delay;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize auto wait idle mode
|
* Initialize auto wait idle mode
|
||||||
*
|
*
|
||||||
@ -235,6 +261,35 @@ static inline bool spimem_flash_ll_sus_status(spi_mem_dev_t *dev)
|
|||||||
return dev->sus_status.flash_sus;
|
return dev->sus_status.flash_sus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set lock for SPI0 so that spi0 can request new cache request after a cache transfer.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param lock_time Lock delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_sus_set_spi0_lock_trans(spi_mem_dev_t *dev, uint32_t lock_time)
|
||||||
|
{
|
||||||
|
dev->sus_status.spi0_lock_en = 1;
|
||||||
|
SPIMEM0.fsm.lock_delay_time = lock_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get tsus unit values in SPI_CLK cycles
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @return uint32_t tsus unit values
|
||||||
|
*/
|
||||||
|
static inline uint32_t spimem_flash_ll_get_tsus_unit_in_cycles(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
uint32_t tsus_unit = 0;
|
||||||
|
if (dev->sus_status.flash_pes_dly_128 == 1) {
|
||||||
|
tsus_unit = 128;
|
||||||
|
} else {
|
||||||
|
tsus_unit = 4;
|
||||||
|
}
|
||||||
|
return tsus_unit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable/disable write protection for the flash chip.
|
* Enable/disable write protection for the flash chip.
|
||||||
*
|
*
|
||||||
@ -323,6 +378,17 @@ static inline void spimem_flash_ll_user_start(spi_mem_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
* This function is combined with `spimem_flash_ll_user_start`. The pe_bit will be cleared automatically once the operation done.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_pe_bit(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
dev->cmd.flash_pe = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the host is idle to perform new commands.
|
* Check whether the host is idle to perform new commands.
|
||||||
*
|
*
|
||||||
|
@ -134,6 +134,16 @@ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void gpspi_flash_ll_set_pe_bit(spi_dev_t *dev)
|
||||||
|
{
|
||||||
|
// Not supported on GPSPI
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set HD pin high when flash work at spi mode.
|
* Set HD pin high when flash work at spi mode.
|
||||||
*
|
*
|
||||||
|
@ -65,6 +65,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev)
|
#define spi_flash_ll_set_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev)
|
||||||
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) gpspi_flash_ll_set_pe_bit((spi_dev_t*)dev)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -94,6 +95,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev)
|
#define spi_flash_ll_set_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev)
|
||||||
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) spimem_flash_ll_set_pe_bit((spi_mem_dev_t*)dev)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -316,6 +316,17 @@ static inline void spimem_flash_ll_user_start(spi_mem_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
* This function is combined with `spimem_flash_ll_user_start`. The pe_bit will be cleared automatically once the operation done.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_pe_bit(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
dev->cmd.flash_pe = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the host is idle to perform new commands.
|
* Check whether the host is idle to perform new commands.
|
||||||
*
|
*
|
||||||
|
@ -145,6 +145,16 @@ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void gpspi_flash_ll_set_pe_bit(spi_dev_t *dev)
|
||||||
|
{
|
||||||
|
// Not supported on GPSPI
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set HD pin high when flash work at spi mode.
|
* Set HD pin high when flash work at spi mode.
|
||||||
*
|
*
|
||||||
|
@ -63,6 +63,7 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev)
|
#define spi_flash_ll_set_dummy_out(dev, en, lev) gpspi_flash_ll_set_dummy_out((spi_dev_t*)dev, en, lev)
|
||||||
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) gpspi_flash_ll_set_hold((spi_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) gpspi_flash_ll_set_pe_bit((spi_dev_t*)dev)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
||||||
@ -91,6 +92,8 @@ typedef union {
|
|||||||
#define spi_flash_ll_set_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev)
|
#define spi_flash_ll_set_dummy_out(dev, en, lev) spimem_flash_ll_set_dummy_out((spi_mem_dev_t*)dev, en, lev)
|
||||||
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
#define spi_flash_ll_set_hold(dev, hold_n) spimem_flash_ll_set_hold((spi_mem_dev_t*)dev, hold_n)
|
||||||
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
#define spi_flash_ll_set_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
||||||
|
#define spi_flash_ll_set_pe_bit(dev) spimem_flash_ll_set_pe_bit((spi_mem_dev_t*)dev)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -32,6 +32,8 @@ extern "C" {
|
|||||||
#define spimem_flash_ll_get_hw(host_id) (((host_id)==SPI1_HOST ? &SPIMEM1 : NULL ))
|
#define spimem_flash_ll_get_hw(host_id) (((host_id)==SPI1_HOST ? &SPIMEM1 : NULL ))
|
||||||
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
#define spimem_flash_ll_hw_get_id(dev) ((dev) == (void*)&SPIMEM1? SPI1_HOST: -1)
|
||||||
|
|
||||||
|
#define SPIMEM_FLASH_LL_SPI0_MAX_LOCK_VAL_MSPI_TICKS (0x1f)
|
||||||
|
|
||||||
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
typedef typeof(SPIMEM1.clock.val) spimem_flash_ll_clock_reg_t;
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------
|
/*------------------------------------------------------------------------------
|
||||||
@ -120,6 +122,7 @@ static inline void spimem_flash_ll_resume(spi_mem_dev_t *dev)
|
|||||||
static inline void spimem_flash_ll_auto_suspend_init(spi_mem_dev_t *dev, bool auto_sus)
|
static inline void spimem_flash_ll_auto_suspend_init(spi_mem_dev_t *dev, bool auto_sus)
|
||||||
{
|
{
|
||||||
dev->flash_sus_ctrl.flash_pes_en = auto_sus; // enable Flash Auto-Suspend.
|
dev->flash_sus_ctrl.flash_pes_en = auto_sus; // enable Flash Auto-Suspend.
|
||||||
|
dev->flash_sus_cmd.pes_per_en = auto_sus;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,7 +170,7 @@ static inline void spimem_flash_ll_resume_cmd_setup(spi_mem_dev_t *dev, uint32_t
|
|||||||
*/
|
*/
|
||||||
static inline void spimem_flash_ll_rd_sus_cmd_setup(spi_mem_dev_t *dev, uint32_t pesr_cmd)
|
static inline void spimem_flash_ll_rd_sus_cmd_setup(spi_mem_dev_t *dev, uint32_t pesr_cmd)
|
||||||
{
|
{
|
||||||
abort(); //Not support on esp32s3
|
//Not support on esp32s3
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -201,7 +204,59 @@ static inline void spimem_flash_ll_res_check_sus_setup(spi_mem_dev_t *dev, bool
|
|||||||
*/
|
*/
|
||||||
static inline void spimem_flash_ll_set_read_sus_status(spi_mem_dev_t *dev, uint32_t sus_mask)
|
static inline void spimem_flash_ll_set_read_sus_status(spi_mem_dev_t *dev, uint32_t sus_mask)
|
||||||
{
|
{
|
||||||
abort();// Not supported on esp32s3
|
// Not supported on esp32s3
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the delay after Suspend/Resume
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param dly_val delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_sus_delay(spi_mem_dev_t *dev, uint32_t dly_val)
|
||||||
|
{
|
||||||
|
dev->ctrl1.cs_hold_dly_res = dly_val;
|
||||||
|
dev->sus_status.flash_per_dly_256 = 1;
|
||||||
|
dev->sus_status.flash_pes_dly_256 = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure the cs hold delay time(used to set the minimum CS high time tSHSL)
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param cs_hold_delay cs hold delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_set_cs_hold_delay(spi_mem_dev_t *dev, uint32_t cs_hold_delay)
|
||||||
|
{
|
||||||
|
SPIMEM0.ctrl2.cs_hold_delay = cs_hold_delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set lock for SPI0 so that spi0 can request new cache request after a cache transfer.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @param lock_time Lock delay time
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_sus_set_spi0_lock_trans(spi_mem_dev_t *dev, uint32_t lock_time)
|
||||||
|
{
|
||||||
|
// Not support on esp32s3
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get tsus unit values in SPI_CLK cycles
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
* @return uint32_t tsus unit values
|
||||||
|
*/
|
||||||
|
static inline uint32_t spimem_flash_ll_get_tsus_unit_in_cycles(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
uint32_t tsus_unit = 0;
|
||||||
|
if (dev->sus_status.flash_pes_dly_256 == 1) {
|
||||||
|
tsus_unit = 128;
|
||||||
|
} else {
|
||||||
|
tsus_unit = 4;
|
||||||
|
}
|
||||||
|
return tsus_unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -214,6 +269,8 @@ static inline void spimem_flash_ll_auto_wait_idle_init(spi_mem_dev_t *dev, bool
|
|||||||
{
|
{
|
||||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); // Set the command to send, to fetch flash status reg value.
|
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->flash_waiti_ctrl, waiti_cmd, 0x05); // Set the command to send, to fetch flash status reg value.
|
||||||
dev->flash_waiti_ctrl.waiti_en = auto_waiti; // enable auto wait-idle function.
|
dev->flash_waiti_ctrl.waiti_en = auto_waiti; // enable auto wait-idle function.
|
||||||
|
dev->flash_sus_cmd.flash_per_wait_en = 1;
|
||||||
|
dev->flash_sus_cmd.flash_pes_wait_en = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -316,6 +373,17 @@ static inline void spimem_flash_ll_user_start(spi_mem_dev_t *dev)
|
|||||||
dev->cmd.usr = 1;
|
dev->cmd.usr = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||||
|
* This function is combined with `spimem_flash_ll_user_start`. The pe_bit will be cleared automatically once the operation done.
|
||||||
|
*
|
||||||
|
* @param dev Beginning address of the peripheral registers.
|
||||||
|
*/
|
||||||
|
static inline void spimem_flash_ll_set_pe_bit(spi_mem_dev_t *dev)
|
||||||
|
{
|
||||||
|
dev->cmd.flash_pe = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the host is idle to perform new commands.
|
* Check whether the host is idle to perform new commands.
|
||||||
*
|
*
|
||||||
|
@ -47,8 +47,9 @@ typedef struct {
|
|||||||
spi_flash_sus_cmd_conf sus_cfg; ///< To store suspend command/mask information.
|
spi_flash_sus_cmd_conf sus_cfg; ///< To store suspend command/mask information.
|
||||||
uint32_t slicer_flags; /// Slicer flags for configuring how to slice data correctly while reading or writing.
|
uint32_t slicer_flags; /// Slicer flags for configuring how to slice data correctly while reading or writing.
|
||||||
#define SPI_FLASH_HOST_CONTEXT_SLICER_FLAG_DTR BIT(0) ///< Slice data according to DTR mode, the address and length must be even (A0=0).
|
#define SPI_FLASH_HOST_CONTEXT_SLICER_FLAG_DTR BIT(0) ///< Slice data according to DTR mode, the address and length must be even (A0=0).
|
||||||
|
int freq_mhz; /// Flash clock frequency.
|
||||||
} spi_flash_hal_context_t;
|
} spi_flash_hal_context_t;
|
||||||
ESP_STATIC_ASSERT(sizeof(spi_flash_hal_context_t) == 40, "size of spi_flash_hal_context_t incorrect. Please check data compatibility with the ROM");
|
ESP_STATIC_ASSERT(sizeof(spi_flash_hal_context_t) == 44, "size of spi_flash_hal_context_t incorrect. Please check data compatibility with the ROM");
|
||||||
|
|
||||||
/// This struct provide MSPI Flash necessary timing related config, should be consistent with that in union in `spi_flash_hal_config_t`.
|
/// This struct provide MSPI Flash necessary timing related config, should be consistent with that in union in `spi_flash_hal_config_t`.
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -27,6 +27,7 @@ typedef struct {
|
|||||||
#define SPI_FLASH_TRANS_FLAG_CMD16 BIT(0) ///< Send command of 16 bits
|
#define SPI_FLASH_TRANS_FLAG_CMD16 BIT(0) ///< Send command of 16 bits
|
||||||
#define SPI_FLASH_TRANS_FLAG_IGNORE_BASEIO BIT(1) ///< Not applying the basic io mode configuration for this transaction
|
#define SPI_FLASH_TRANS_FLAG_IGNORE_BASEIO BIT(1) ///< Not applying the basic io mode configuration for this transaction
|
||||||
#define SPI_FLASH_TRANS_FLAG_BYTE_SWAP BIT(2) ///< Used for DTR mode, to swap the bytes of a pair of rising/falling edge
|
#define SPI_FLASH_TRANS_FLAG_BYTE_SWAP BIT(2) ///< Used for DTR mode, to swap the bytes of a pair of rising/falling edge
|
||||||
|
#define SPI_FLASH_TRANS_FLAG_PE_CMD BIT(3) ///< Indicates that this transaction is to erase/program flash chip.
|
||||||
uint16_t command; ///< Command to send
|
uint16_t command; ///< Command to send
|
||||||
uint8_t dummy_bitlen; ///< Basic dummy bits to use
|
uint8_t dummy_bitlen; ///< Basic dummy bits to use
|
||||||
uint32_t io_mode; ///< Flash working mode when `SPI_FLASH_IGNORE_BASEIO` is specified.
|
uint32_t io_mode; ///< Flash working mode when `SPI_FLASH_IGNORE_BASEIO` is specified.
|
||||||
|
@ -103,6 +103,7 @@ esp_err_t spi_flash_hal_init(spi_flash_hal_context_t *data_out, const spi_flash_
|
|||||||
.cs_hold = cfg->cs_hold,
|
.cs_hold = cfg->cs_hold,
|
||||||
.cs_setup = cfg->cs_setup,
|
.cs_setup = cfg->cs_setup,
|
||||||
.base_io_mode = cfg->default_io_mode,
|
.base_io_mode = cfg->default_io_mode,
|
||||||
|
.freq_mhz = cfg->freq_mhz,
|
||||||
};
|
};
|
||||||
#if SOC_SPI_MEM_SUPPORT_TIMING_TUNING
|
#if SOC_SPI_MEM_SUPPORT_TIMING_TUNING
|
||||||
if (cfg->using_timing_tuning) {
|
if (cfg->using_timing_tuning) {
|
||||||
|
@ -170,6 +170,9 @@ esp_err_t spi_flash_hal_common_command(spi_flash_host_inst_t *host, spi_flash_tr
|
|||||||
spi_flash_ll_set_buffer_data(dev, trans->mosi_data, trans->mosi_len);
|
spi_flash_ll_set_buffer_data(dev, trans->mosi_data, trans->mosi_len);
|
||||||
|
|
||||||
spi_flash_ll_set_miso_bitlen(dev, trans->miso_len * 8);
|
spi_flash_ll_set_miso_bitlen(dev, trans->miso_len * 8);
|
||||||
|
if ((trans->flags & SPI_FLASH_TRANS_FLAG_PE_CMD) != 0) {
|
||||||
|
spi_flash_ll_set_pe_bit(dev);
|
||||||
|
}
|
||||||
spi_flash_ll_user_start(dev);
|
spi_flash_ll_user_start(dev);
|
||||||
host->driver->poll_cmd_done(host);
|
host->driver->poll_cmd_done(host);
|
||||||
if (trans->miso_len > 0) {
|
if (trans->miso_len > 0) {
|
||||||
|
@ -6,11 +6,14 @@
|
|||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#include "hal/spi_flash_hal.h"
|
#include "hal/spi_flash_hal.h"
|
||||||
|
|
||||||
#if SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
|
#if SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
|
||||||
void spi_flash_hal_setup_auto_suspend_mode(spi_flash_host_inst_t *host);
|
void spi_flash_hal_setup_auto_suspend_mode(spi_flash_host_inst_t *host);
|
||||||
void spi_flash_hal_disable_auto_resume_mode(spi_flash_host_inst_t *host);
|
void spi_flash_hal_disable_auto_resume_mode(spi_flash_host_inst_t *host);
|
||||||
void spi_flash_hal_disable_auto_suspend_mode(spi_flash_host_inst_t *host);
|
void spi_flash_hal_disable_auto_suspend_mode(spi_flash_host_inst_t *host);
|
||||||
void spi_flash_hal_setup_auto_resume_mode(spi_flash_host_inst_t *host);
|
void spi_flash_hal_setup_auto_resume_mode(spi_flash_host_inst_t *host);
|
||||||
|
#define SPI_FLASH_TSUS_SAFE_VAL_US (30)
|
||||||
|
#define SPI_FLASH_TSHSL2_SAFE_VAL_NS (30)
|
||||||
#endif //SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
|
#endif //SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
|
||||||
|
|
||||||
#ifndef CONFIG_SPI_FLASH_ROM_IMPL
|
#ifndef CONFIG_SPI_FLASH_ROM_IMPL
|
||||||
@ -128,10 +131,12 @@ esp_err_t spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t *host, const sp
|
|||||||
spi_mem_dev_t *dev = (spi_mem_dev_t *)spi_flash_ll_get_hw(SPI1_HOST);
|
spi_mem_dev_t *dev = (spi_mem_dev_t *)spi_flash_ll_get_hw(SPI1_HOST);
|
||||||
spi_flash_hal_context_t* ctx = (spi_flash_hal_context_t*)host;
|
spi_flash_hal_context_t* ctx = (spi_flash_hal_context_t*)host;
|
||||||
memcpy(&(ctx->sus_cfg), sus_conf, sizeof(spi_flash_sus_cmd_conf));
|
memcpy(&(ctx->sus_cfg), sus_conf, sizeof(spi_flash_sus_cmd_conf));
|
||||||
spimem_flash_ll_set_read_sus_status(dev, sus_conf->sus_mask);
|
|
||||||
spimem_flash_ll_suspend_cmd_setup(dev, sus_conf->sus_cmd);
|
spimem_flash_ll_suspend_cmd_setup(dev, sus_conf->sus_cmd);
|
||||||
spimem_flash_ll_resume_cmd_setup(dev, sus_conf->res_cmd);
|
spimem_flash_ll_resume_cmd_setup(dev, sus_conf->res_cmd);
|
||||||
|
#if SOC_SPI_MEM_SUPPORT_CHECK_SUS
|
||||||
|
spimem_flash_ll_set_read_sus_status(dev, sus_conf->sus_mask);
|
||||||
spimem_flash_ll_rd_sus_cmd_setup(dev, sus_conf->cmd_rdsr);
|
spimem_flash_ll_rd_sus_cmd_setup(dev, sus_conf->cmd_rdsr);
|
||||||
|
#endif // SOC_SPI_MEM_SUPPORT_CHECK_SUS
|
||||||
#endif // SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
|
#endif // SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@ -140,8 +145,16 @@ esp_err_t spi_flash_hal_setup_read_suspend(spi_flash_host_inst_t *host, const sp
|
|||||||
void spi_flash_hal_setup_auto_suspend_mode(spi_flash_host_inst_t *host)
|
void spi_flash_hal_setup_auto_suspend_mode(spi_flash_host_inst_t *host)
|
||||||
{
|
{
|
||||||
spi_mem_dev_t *dev = (spi_mem_dev_t*)spi_flash_ll_get_hw(SPI1_HOST);
|
spi_mem_dev_t *dev = (spi_mem_dev_t*)spi_flash_ll_get_hw(SPI1_HOST);
|
||||||
|
spi_flash_hal_context_t* ctx = (spi_flash_hal_context_t*)host;
|
||||||
spimem_flash_ll_auto_wait_idle_init(dev, true);
|
spimem_flash_ll_auto_wait_idle_init(dev, true);
|
||||||
spimem_flash_ll_auto_suspend_init(dev, true);
|
spimem_flash_ll_auto_suspend_init(dev, true);
|
||||||
|
// tsus = ceil(SPI_FLASH_TSUS_SAFE_VAL_US * ctx->freq_mhz / spimem_flash_ll_get_tsus_unit_in_cycles);
|
||||||
|
uint32_t tsus = (SPI_FLASH_TSUS_SAFE_VAL_US * ctx->freq_mhz / spimem_flash_ll_get_tsus_unit_in_cycles(dev)) + ((SPI_FLASH_TSUS_SAFE_VAL_US * ctx->freq_mhz) % spimem_flash_ll_get_tsus_unit_in_cycles(dev) != 0);
|
||||||
|
spimem_flash_ll_set_sus_delay(dev, tsus);
|
||||||
|
// tshsl2 = ceil(SPI_FLASH_TSHSL2_SAFE_VAL_NS * spimem_flash_ll_get_source_freq_mhz() * 0.001);
|
||||||
|
uint32_t tshsl2 = (SPI_FLASH_TSHSL2_SAFE_VAL_NS * spimem_flash_ll_get_source_freq_mhz() / 1000) + ((SPI_FLASH_TSHSL2_SAFE_VAL_NS * spimem_flash_ll_get_source_freq_mhz()) % 1000 != 0);
|
||||||
|
spimem_flash_set_cs_hold_delay(dev, tshsl2);
|
||||||
|
spimem_flash_ll_sus_set_spi0_lock_trans(dev, SPIMEM_FLASH_LL_SPI0_MAX_LOCK_VAL_MSPI_TICKS);
|
||||||
#if SOC_SPI_MEM_SUPPORT_CHECK_SUS
|
#if SOC_SPI_MEM_SUPPORT_CHECK_SUS
|
||||||
spimem_flash_ll_sus_check_sus_setup(dev, true);
|
spimem_flash_ll_sus_check_sus_setup(dev, true);
|
||||||
#endif
|
#endif
|
||||||
|
@ -238,7 +238,14 @@ typedef volatile struct spi_mem_dev_s {
|
|||||||
union {
|
union {
|
||||||
struct {
|
struct {
|
||||||
uint32_t flash_sus: 1; /*The status of flash suspend only used in SPI1.*/
|
uint32_t flash_sus: 1; /*The status of flash suspend only used in SPI1.*/
|
||||||
uint32_t reserved1: 31; /*reserved*/
|
uint32_t wait_pesr_cmd_2b:1;
|
||||||
|
uint32_t hpm_dly_128: 1;
|
||||||
|
uint32_t res_dly_128: 1;
|
||||||
|
uint32_t dp_dly_128: 1;
|
||||||
|
uint32_t per_dly_128: 1;
|
||||||
|
uint32_t pes_dly_128: 1;
|
||||||
|
uint32_t spi0_lock_en: 1;
|
||||||
|
uint32_t reserved1: 24; /*reserved*/
|
||||||
};
|
};
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
} sus_status;
|
} sus_status;
|
||||||
|
@ -951,10 +951,6 @@ config SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE
|
|||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
|
|
||||||
bool
|
|
||||||
default y
|
|
||||||
|
|
||||||
config SOC_SPI_MEM_SUPPORT_SW_SUSPEND
|
config SOC_SPI_MEM_SUPPORT_SW_SUSPEND
|
||||||
bool
|
bool
|
||||||
default y
|
default y
|
||||||
|
@ -414,7 +414,6 @@
|
|||||||
|
|
||||||
/*-------------------------- SPI MEM CAPS ---------------------------------------*/
|
/*-------------------------- SPI MEM CAPS ---------------------------------------*/
|
||||||
#define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE (1)
|
#define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE (1)
|
||||||
#define SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND (1)
|
|
||||||
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
|
#define SOC_SPI_MEM_SUPPORT_SW_SUSPEND (1)
|
||||||
#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1)
|
#define SOC_SPI_MEM_SUPPORT_CONFIG_GPIO_BY_EFUSE (1)
|
||||||
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
|
#define SOC_SPI_MEM_SUPPORT_WRAP (1)
|
||||||
|
@ -11,3 +11,11 @@ components/spi_flash/test_apps/flash_encryption:
|
|||||||
- if: IDF_TARGET in ["esp32c2", "esp32s2", "esp32c6", "esp32h2"]
|
- if: IDF_TARGET in ["esp32c2", "esp32s2", "esp32c6", "esp32h2"]
|
||||||
temporary: true
|
temporary: true
|
||||||
reason: No runners # IDF-5634
|
reason: No runners # IDF-5634
|
||||||
|
|
||||||
|
components/spi_flash/test_apps/flash_suspend:
|
||||||
|
disable:
|
||||||
|
- if: SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND != 1
|
||||||
|
disable_test:
|
||||||
|
- if: IDF_TARGET != "esp32c3"
|
||||||
|
temporary: true
|
||||||
|
reason: lack of runners
|
||||||
|
@ -147,17 +147,24 @@ menu "SPI Flash driver"
|
|||||||
help
|
help
|
||||||
Defines how many ticks will be before returning to continue a erasing.
|
Defines how many ticks will be before returning to continue a erasing.
|
||||||
|
|
||||||
|
config SPI_FLASH_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
|
config SPI_FLASH_AUTO_SUSPEND
|
||||||
bool "Auto suspend long erase/write operations (READ DOCS FIRST)"
|
bool "Auto suspend long erase/write operations (READ DOCS FIRST)"
|
||||||
default n
|
default n
|
||||||
depends on IDF_TARGET_ESP32C3 && !SPI_FLASH_ROM_IMPL
|
depends on SPI_FLASH_SUSPEND_QVL_SUPPORTED && !SPI_FLASH_ROM_IMPL
|
||||||
help
|
help
|
||||||
This option is default n before ESP32-C3, because it needs bootloader support.
|
This option is default n because it can't be used in every situation. You need to
|
||||||
|
evaluate this feature through suspend part in `SPI Flash API` document.
|
||||||
|
|
||||||
CAUTION: If you want to OTA to an app with this feature turned on, please make
|
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)
|
sure the bootloader has the support for it. (later than IDF v4.3)
|
||||||
|
|
||||||
Auto-suspend feature only supported by XMC chip.
|
Auto-suspend feature only supported by specific flash chips.
|
||||||
If you are using an official module, please contact Espressif Business support.
|
If you are using an official module, please contact Espressif Business support.
|
||||||
Also reading auto suspend part in `SPI Flash API` document before you enable this function.
|
Also reading auto suspend part in `SPI Flash API` document before you enable this function.
|
||||||
|
|
||||||
|
@ -97,26 +97,7 @@ esp_flash_t *esp_flash_default_chip = NULL;
|
|||||||
.input_delay_ns = 0,\
|
.input_delay_ns = 0,\
|
||||||
.cs_setup = 1,\
|
.cs_setup = 1,\
|
||||||
}
|
}
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
#else // Other target
|
||||||
#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \
|
|
||||||
.host_id = SPI1_HOST,\
|
|
||||||
.freq_mhz = DEFAULT_FLASH_SPEED, \
|
|
||||||
.cs_num = 0, \
|
|
||||||
.iomux = true, \
|
|
||||||
.input_delay_ns = 0,\
|
|
||||||
.cs_setup = 1,\
|
|
||||||
}
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
|
||||||
#include "esp32s3/rom/efuse.h"
|
|
||||||
#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \
|
|
||||||
.host_id = SPI1_HOST,\
|
|
||||||
.freq_mhz = DEFAULT_FLASH_SPEED, \
|
|
||||||
.cs_num = 0, \
|
|
||||||
.iomux = true, \
|
|
||||||
.input_delay_ns = 0,\
|
|
||||||
.cs_setup = 1,\
|
|
||||||
}
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
|
|
||||||
#if !CONFIG_SPI_FLASH_AUTO_SUSPEND
|
#if !CONFIG_SPI_FLASH_AUTO_SUSPEND
|
||||||
#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \
|
#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \
|
||||||
.host_id = SPI1_HOST,\
|
.host_id = SPI1_HOST,\
|
||||||
@ -137,7 +118,7 @@ esp_flash_t *esp_flash_default_chip = NULL;
|
|||||||
.cs_setup = 1,\
|
.cs_setup = 1,\
|
||||||
}
|
}
|
||||||
#endif //!CONFIG_SPI_FLASH_AUTO_SUSPEND
|
#endif //!CONFIG_SPI_FLASH_AUTO_SUSPEND
|
||||||
#endif
|
#endif // Other target
|
||||||
|
|
||||||
static IRAM_ATTR NOINLINE_ATTR void cs_initialize(esp_flash_t *chip, const esp_flash_spi_device_config_t *config, bool use_iomux, int cs_id)
|
static IRAM_ATTR NOINLINE_ATTR void cs_initialize(esp_flash_t *chip, const esp_flash_spi_device_config_t *config, bool use_iomux, int cs_id)
|
||||||
{
|
{
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "spi_flash_chip_generic.h"
|
#include "spi_flash_chip_generic.h"
|
||||||
#include "spi_flash_chip_gd.h"
|
#include "spi_flash_chip_gd.h"
|
||||||
#include "spi_flash_defs.h"
|
#include "spi_flash_defs.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
#define ADDR_32BIT(addr) (addr >= (1<<24))
|
#define ADDR_32BIT(addr) (addr >= (1<<24))
|
||||||
|
|
||||||
@ -33,6 +34,17 @@ spi_flash_caps_t spi_flash_chip_gd_get_caps(esp_flash_t *chip)
|
|||||||
if ((chip->chip_id & 0xFF) >= 0x19) {
|
if ((chip->chip_id & 0xFF) >= 0x19) {
|
||||||
caps_flags |= SPI_FLASH_CHIP_CAP_32MB_SUPPORT;
|
caps_flags |= SPI_FLASH_CHIP_CAP_32MB_SUPPORT;
|
||||||
}
|
}
|
||||||
|
#if CONFIG_SPI_FLASH_AUTO_SUSPEND
|
||||||
|
switch (chip->chip_id) {
|
||||||
|
/* The flash listed here can support suspend */
|
||||||
|
case 0xC84017:
|
||||||
|
case 0xC84018:
|
||||||
|
caps_flags |= SPI_FLASH_CHIP_CAP_SUSPEND;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
// flash-suspend is not supported
|
// flash-suspend is not supported
|
||||||
// flash read unique id.
|
// flash read unique id.
|
||||||
caps_flags |= SPI_FLASH_CHIP_CAP_UNIQUE_ID;
|
caps_flags |= SPI_FLASH_CHIP_CAP_UNIQUE_ID;
|
||||||
@ -112,6 +124,18 @@ esp_err_t spi_flash_chip_gd_get_io_mode(esp_flash_t *chip, esp_flash_io_mode_t*
|
|||||||
}
|
}
|
||||||
#endif //CONFIG_SPI_FLASH_ROM_IMPL
|
#endif //CONFIG_SPI_FLASH_ROM_IMPL
|
||||||
|
|
||||||
|
esp_err_t spi_flash_chip_gd_suspend_cmd_conf(esp_flash_t *chip)
|
||||||
|
{
|
||||||
|
spi_flash_sus_cmd_conf sus_conf = {
|
||||||
|
.sus_mask = 0x84,
|
||||||
|
.cmd_rdsr = CMD_RDSR2,
|
||||||
|
.sus_cmd = CMD_SUSPEND,
|
||||||
|
.res_cmd = CMD_RESUME,
|
||||||
|
};
|
||||||
|
|
||||||
|
return chip->host->driver->sus_setup(chip->host, &sus_conf);
|
||||||
|
}
|
||||||
|
|
||||||
static const char chip_name[] = "gd";
|
static const char chip_name[] = "gd";
|
||||||
|
|
||||||
// The issi chip can use the functions for generic chips except from set read mode and probe,
|
// The issi chip can use the functions for generic chips except from set read mode and probe,
|
||||||
@ -148,7 +172,7 @@ const spi_flash_chip_t esp_flash_chip_gd = {
|
|||||||
|
|
||||||
.read_reg = spi_flash_chip_generic_read_reg,
|
.read_reg = spi_flash_chip_generic_read_reg,
|
||||||
.yield = spi_flash_chip_generic_yield,
|
.yield = spi_flash_chip_generic_yield,
|
||||||
.sus_setup = spi_flash_chip_generic_suspend_cmd_conf,
|
.sus_setup = spi_flash_chip_gd_suspend_cmd_conf,
|
||||||
.read_unique_id = spi_flash_chip_generic_read_unique_id,
|
.read_unique_id = spi_flash_chip_generic_read_unique_id,
|
||||||
.get_chip_caps = spi_flash_chip_gd_get_caps,
|
.get_chip_caps = spi_flash_chip_gd_get_caps,
|
||||||
.config_host_io_mode = spi_flash_chip_generic_config_host_io_mode,
|
.config_host_io_mode = spi_flash_chip_generic_config_host_io_mode,
|
||||||
|
@ -1,16 +1,8 @@
|
|||||||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
/*
|
||||||
//
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
*
|
||||||
// you may not use this file except in compliance with the License.
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
// You may obtain a copy of the License at
|
*/
|
||||||
//
|
|
||||||
// http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
//
|
|
||||||
// Unless required by applicable law or agreed to in writing, software
|
|
||||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
// See the License for the specific language governing permissions and
|
|
||||||
// limitations under the License.
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -209,6 +201,7 @@ static esp_err_t spi_flash_command_winbond_program_4B(esp_flash_t *chip, const v
|
|||||||
.address = address,
|
.address = address,
|
||||||
.mosi_len = length,
|
.mosi_len = length,
|
||||||
.mosi_data = buffer,
|
.mosi_data = buffer,
|
||||||
|
.flags = SPI_FLASH_TRANS_FLAG_PE_CMD,
|
||||||
};
|
};
|
||||||
return chip->host->driver->common_command(chip->host, &t);
|
return chip->host->driver->common_command(chip->host, &t);
|
||||||
}
|
}
|
||||||
@ -220,6 +213,7 @@ esp_err_t spi_flash_command_winbond_erase_sector_4B(esp_flash_t *chip, uint32_t
|
|||||||
.command = (addr_4b? CMD_SECTOR_ERASE_4B: CMD_SECTOR_ERASE),
|
.command = (addr_4b? CMD_SECTOR_ERASE_4B: CMD_SECTOR_ERASE),
|
||||||
.address_bitlen = (addr_4b? 32: 24),
|
.address_bitlen = (addr_4b? 32: 24),
|
||||||
.address = start_address,
|
.address = start_address,
|
||||||
|
.flags = SPI_FLASH_TRANS_FLAG_PE_CMD,
|
||||||
};
|
};
|
||||||
return chip->host->driver->common_command(chip->host, &t);
|
return chip->host->driver->common_command(chip->host, &t);
|
||||||
}
|
}
|
||||||
@ -231,6 +225,7 @@ esp_err_t spi_flash_command_erase_block_4B(esp_flash_t *chip, uint32_t start_add
|
|||||||
.command = (addr_4b? CMD_LARGE_BLOCK_ERASE_4B: CMD_LARGE_BLOCK_ERASE),
|
.command = (addr_4b? CMD_LARGE_BLOCK_ERASE_4B: CMD_LARGE_BLOCK_ERASE),
|
||||||
.address_bitlen = (addr_4b? 32: 24),
|
.address_bitlen = (addr_4b? 32: 24),
|
||||||
.address = start_address,
|
.address = start_address,
|
||||||
|
.flags = SPI_FLASH_TRANS_FLAG_PE_CMD,
|
||||||
};
|
};
|
||||||
return chip->host->driver->common_command(chip->host, &t);
|
return chip->host->driver->common_command(chip->host, &t);
|
||||||
}
|
}
|
||||||
|
@ -459,55 +459,6 @@ static void test_flash_erase_not_trigger_wdt(const esp_partition_t *part)
|
|||||||
|
|
||||||
TEST_CASE_MULTI_FLASH_LONG("Test erasing flash chip not triggering WDT", test_flash_erase_not_trigger_wdt);
|
TEST_CASE_MULTI_FLASH_LONG("Test erasing flash chip not triggering WDT", test_flash_erase_not_trigger_wdt);
|
||||||
|
|
||||||
|
|
||||||
#if CONFIG_SPI_FLASH_AUTO_SUSPEND
|
|
||||||
void esp_test_for_suspend(void)
|
|
||||||
{
|
|
||||||
/*clear content in cache*/
|
|
||||||
#if !CONFIG_IDF_TARGET_ESP32C3
|
|
||||||
Cache_Invalidate_DCache_All();
|
|
||||||
#endif
|
|
||||||
Cache_Invalidate_ICache_All();
|
|
||||||
ESP_LOGI(TAG, "suspend test begins:");
|
|
||||||
printf("run into test suspend function\n");
|
|
||||||
printf("print something when flash is erasing:\n");
|
|
||||||
printf("aaaaa bbbbb zzzzz fffff qqqqq ccccc\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static volatile bool task_erase_end, task_suspend_end = false;
|
|
||||||
void task_erase_large_region(void *arg)
|
|
||||||
{
|
|
||||||
esp_partition_t *part = (esp_partition_t *)arg;
|
|
||||||
test_erase_large_region(part);
|
|
||||||
task_erase_end = true;
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void task_request_suspend(void *arg)
|
|
||||||
{
|
|
||||||
vTaskDelay(2);
|
|
||||||
ESP_LOGI(TAG, "flash go into suspend");
|
|
||||||
esp_test_for_suspend();
|
|
||||||
task_suspend_end = true;
|
|
||||||
vTaskDelete(NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_flash_suspend_resume(const esp_partition_t* part)
|
|
||||||
{
|
|
||||||
xTaskCreatePinnedToCore(task_request_suspend, "suspend", 2048, (void *)"test_for_suspend", UNITY_FREERTOS_PRIORITY + 3, NULL, 0);
|
|
||||||
xTaskCreatePinnedToCore(task_erase_large_region, "test", 2048, (void *)part, UNITY_FREERTOS_PRIORITY + 2, NULL, 0);
|
|
||||||
while (!task_erase_end || !task_suspend_end) {
|
|
||||||
}
|
|
||||||
vTaskDelay(200);
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("SPI flash suspend and resume test", "[esp_flash][test_env=UT_T1_Flash_Suspend]")
|
|
||||||
{
|
|
||||||
flash_test_func(test_flash_suspend_resume, 1 /* first index reserved for main flash */ );
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //CONFIG_SPI_FLASH_AUTO_SUSPEND
|
|
||||||
|
|
||||||
static void test_write_protection(const esp_partition_t* part)
|
static void test_write_protection(const esp_partition_t* part)
|
||||||
{
|
{
|
||||||
esp_flash_t* chip = part->flash_chip;
|
esp_flash_t* chip = part->flash_chip;
|
||||||
|
@ -999,7 +999,6 @@ components/spi_flash/include/spi_flash_chip_winbond.h
|
|||||||
components/spi_flash/spi_flash_chip_boya.c
|
components/spi_flash/spi_flash_chip_boya.c
|
||||||
components/spi_flash/spi_flash_chip_issi.c
|
components/spi_flash/spi_flash_chip_issi.c
|
||||||
components/spi_flash/spi_flash_chip_mxic.c
|
components/spi_flash/spi_flash_chip_mxic.c
|
||||||
components/spi_flash/spi_flash_chip_winbond.c
|
|
||||||
components/spi_flash/test/test_esp_flash.c
|
components/spi_flash/test/test_esp_flash.c
|
||||||
components/spi_flash/test/test_flash_encryption.c
|
components/spi_flash/test/test_flash_encryption.c
|
||||||
components/spi_flash/test/test_mmap.c
|
components/spi_flash/test/test_mmap.c
|
||||||
|
Loading…
Reference in New Issue
Block a user