mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
Merge branch 'bugfix/spi_flash_cs_setup_v4.3' into 'release/v4.3'
spi_flash: fix cs line setup to make the flash driver more stable(backport v4.3) See merge request espressif/esp-idf!13967
This commit is contained in:
@@ -402,6 +402,12 @@ static inline void spi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n)
|
||||
dev->user.cs_hold = (hold_n > 0? 1: 0);
|
||||
}
|
||||
|
||||
static inline void spi_flash_ll_set_cs_setup(spi_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
dev->ctrl2.setup_time = cs_setup_time - 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -383,6 +383,12 @@ static inline void gpspi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n)
|
||||
dev->user.cs_hold = (hold_n > 0? 1: 0);
|
||||
}
|
||||
|
||||
static inline void gpspi_flash_ll_set_cs_setup(spi_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
dev->user1.cs_setup_time = cs_setup_time - 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -75,6 +75,7 @@ typedef union {
|
||||
#define spi_flash_ll_set_dummy(dev, dummy) gpspi_flash_ll_set_dummy((spi_dev_t*)dev, dummy)
|
||||
#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_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
||||
#else
|
||||
#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)
|
||||
@@ -101,6 +102,7 @@ typedef union {
|
||||
#define spi_flash_ll_set_dummy(dev, dummy) spimem_flash_ll_set_dummy((spi_mem_dev_t*)dev, dummy)
|
||||
#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_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -549,6 +549,12 @@ static inline void spimem_flash_ll_set_hold(spi_mem_dev_t *dev, uint32_t hold_n)
|
||||
dev->user.cs_hold = (hold_n > 0? 1: 0);
|
||||
}
|
||||
|
||||
static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
dev->ctrl2.cs_setup_time = cs_setup_time - 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -370,6 +370,12 @@ static inline void gpspi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n)
|
||||
dev->user.cs_hold = (hold_n > 0? 1: 0);
|
||||
}
|
||||
|
||||
static inline void gpspi_flash_ll_set_cs_setup(spi_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
dev->ctrl2.cs_setup_time = cs_setup_time - 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -75,6 +75,7 @@ typedef union {
|
||||
#define spi_flash_ll_set_dummy(dev, dummy) gpspi_flash_ll_set_dummy((spi_dev_t*)dev, dummy)
|
||||
#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_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
||||
|
||||
#else
|
||||
|
||||
@@ -103,6 +104,7 @@ typedef union {
|
||||
#define spi_flash_ll_set_dummy(dev, dummy) spimem_flash_ll_set_dummy((spi_mem_dev_t*)dev, dummy)
|
||||
#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_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
||||
|
||||
#endif
|
||||
|
||||
|
@@ -539,6 +539,12 @@ static inline void spimem_flash_ll_set_hold(spi_mem_dev_t *dev, uint32_t hold_n)
|
||||
dev->user.cs_hold = (hold_n > 0? 1: 0);
|
||||
}
|
||||
|
||||
static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
dev->ctrl2.cs_setup_time = cs_setup_time - 1;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -382,6 +382,12 @@ static inline void gpspi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n)
|
||||
dev->user.cs_hold = (hold_n > 0? 1: 0);
|
||||
}
|
||||
|
||||
static inline void gpspi_flash_ll_set_cs_setup(spi_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
dev->user1.cs_setup_time = cs_setup_time - 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -74,6 +74,7 @@ typedef union {
|
||||
#define spi_flash_ll_set_dummy(dev, dummy) gpspi_flash_ll_set_dummy((spi_dev_t*)dev, dummy)
|
||||
#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_cs_setup(dev, cs_setup_time) gpspi_flash_ll_set_cs_setup((spi_dev_t*)dev, cs_setup_time)
|
||||
|
||||
#else
|
||||
#define spi_flash_ll_reset(dev) spimem_flash_ll_reset((spi_mem_dev_t*)dev)
|
||||
@@ -101,6 +102,7 @@ typedef union {
|
||||
#define spi_flash_ll_set_dummy(dev, dummy) spimem_flash_ll_set_dummy((spi_mem_dev_t*)dev, dummy)
|
||||
#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_cs_setup(dev, cs_setup_time) spimem_flash_ll_set_cs_setup((spi_mem_dev_t*)dev, cs_setup_time)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@@ -539,6 +539,12 @@ static inline void spimem_flash_ll_set_hold(spi_mem_dev_t *dev, uint32_t hold_n)
|
||||
dev->user.cs_hold = (hold_n > 0? 1: 0);
|
||||
}
|
||||
|
||||
static inline void spimem_flash_ll_set_cs_setup(spi_mem_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
dev->ctrl2.cs_setup_time = cs_setup_time - 1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -42,7 +42,7 @@ typedef struct {
|
||||
int cs_num; ///< Which cs pin is used, 0-2.
|
||||
struct {
|
||||
uint8_t extra_dummy; ///< Pre-calculated extra dummy used for compensation
|
||||
uint8_t reserved1; ///< Reserved, set to 0.
|
||||
uint8_t cs_setup; ///< (cycles-1) of prepare phase by spi clock.
|
||||
uint8_t cs_hold; ///< CS hold time config used by the host
|
||||
uint8_t reserved2; ///< Reserved, set to 0.
|
||||
};
|
||||
@@ -63,6 +63,7 @@ typedef struct {
|
||||
int input_delay_ns; ///< Input delay on the MISO pin after the launch clock, used for timing compensation.
|
||||
esp_flash_speed_t speed;///< SPI flash clock speed to work at.
|
||||
uint32_t cs_hold; ///< CS hold time config used by the host
|
||||
uint8_t cs_setup; ///< (cycles-1) of prepare phase by spi clock
|
||||
bool auto_sus_en; ///< Auto suspend feature enable bit 1: enable, 0: disable.
|
||||
} spi_flash_hal_config_t;
|
||||
|
||||
|
@@ -90,6 +90,7 @@ esp_err_t spi_flash_hal_init(spi_flash_hal_context_t *data_out, const spi_flash_
|
||||
.extra_dummy = get_dummy_n(!cfg->iomux, cfg->input_delay_ns, APB_CLK_FREQ/clock_cfg->div),
|
||||
.clock_conf = clock_cfg->clock_reg_val,
|
||||
.cs_hold = cfg->cs_hold,
|
||||
.cs_setup = cfg->cs_setup,
|
||||
};
|
||||
if (cfg->auto_sus_en) {
|
||||
data_out->flags |= SPI_FLASH_HOST_CONTEXT_FLAG_AUTO_SUSPEND;
|
||||
|
@@ -50,6 +50,8 @@ esp_err_t spi_flash_hal_device_config(spi_flash_host_inst_t *host)
|
||||
spi_flash_ll_set_clock(dev, &ctx->clock_conf);
|
||||
int cs_hold = ctx->cs_hold;
|
||||
spi_flash_ll_set_hold(dev, cs_hold);
|
||||
spi_flash_ll_set_cs_setup(dev, ctx->cs_setup);
|
||||
|
||||
#ifndef GPSPI_BUILD
|
||||
#if SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
|
||||
if ((ctx->flags & SPI_FLASH_HOST_CONTEXT_FLAG_AUTO_SUSPEND) != 0) {
|
||||
|
@@ -71,6 +71,7 @@ __attribute__((unused)) static const char TAG[] = "spi_flash";
|
||||
.cs_num = 0, \
|
||||
.iomux = false, \
|
||||
.input_delay_ns = 0,\
|
||||
.cs_setup = 1,\
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \
|
||||
@@ -79,6 +80,7 @@ __attribute__((unused)) static const char TAG[] = "spi_flash";
|
||||
.cs_num = 0, \
|
||||
.iomux = true, \
|
||||
.input_delay_ns = 0,\
|
||||
.cs_setup = 1,\
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
#include "esp32s3/rom/efuse.h"
|
||||
@@ -88,6 +90,7 @@ __attribute__((unused)) static const char TAG[] = "spi_flash";
|
||||
.cs_num = 0, \
|
||||
.iomux = true, \
|
||||
.input_delay_ns = 0,\
|
||||
.cs_setup = 1,\
|
||||
}
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
#include "esp32c3/rom/efuse.h"
|
||||
@@ -98,6 +101,7 @@ __attribute__((unused)) static const char TAG[] = "spi_flash";
|
||||
.cs_num = 0, \
|
||||
.iomux = true, \
|
||||
.input_delay_ns = 0,\
|
||||
.cs_setup = 1,\
|
||||
}
|
||||
#else
|
||||
#define ESP_FLASH_HOST_CONFIG_DEFAULT() (memspi_host_config_t){ \
|
||||
@@ -107,6 +111,7 @@ __attribute__((unused)) static const char TAG[] = "spi_flash";
|
||||
.iomux = true, \
|
||||
.input_delay_ns = 0,\
|
||||
.auto_sus_en = true,\
|
||||
.cs_setup = 1,\
|
||||
}
|
||||
#endif //!CONFIG_SPI_FLASH_AUTO_SUSPEND
|
||||
#endif
|
||||
|
@@ -141,48 +141,55 @@ TEST_CASE("Test spi_flash_read", "[spi_flash][esp_flash]")
|
||||
#endif
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
static void IRAM_ATTR fix_rom_func(void)
|
||||
{
|
||||
return; // ESP32 ROM has no compatible issue for now
|
||||
}
|
||||
# else
|
||||
extern void spi_common_set_dummy_output(esp_rom_spiflash_read_mode_t mode);
|
||||
extern void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv);
|
||||
static void IRAM_ATTR fix_rom_func(void)
|
||||
{
|
||||
esp_rom_spiflash_read_mode_t read_mode;
|
||||
uint8_t freqdiv;
|
||||
#if defined CONFIG_ESPTOOLPY_FLASHMODE_QIO
|
||||
read_mode = ESP_ROM_SPIFLASH_QIO_MODE;
|
||||
#elif defined CONFIG_ESPTOOLPY_FLASHMODE_QOUT
|
||||
read_mode = ESP_ROM_SPIFLASH_QOUT_MODE;
|
||||
#elif defined CONFIG_ESPTOOLPY_FLASHMODE_DIO
|
||||
read_mode = ESP_ROM_SPIFLASH_DIO_MODE;
|
||||
#elif defined CONFIG_ESPTOOLPY_FLASHMODE_DOUT
|
||||
read_mode = ESP_ROM_SPIFLASH_DOUT_MODE;
|
||||
#endif
|
||||
uint32_t freqdiv = 0;
|
||||
|
||||
# if defined CONFIG_ESPTOOLPY_FLASHFREQ_80M
|
||||
#if CONFIG_ESPTOOLPY_FLASHFREQ_80M
|
||||
freqdiv = 1;
|
||||
# elif defined CONFIG_ESPTOOLPY_FLASHFREQ_40M
|
||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_40M
|
||||
freqdiv = 2;
|
||||
# elif defined CONFIG_ESPTOOLPY_FLASHFREQ_26M
|
||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_26M
|
||||
freqdiv = 3;
|
||||
# elif defined CONFIG_ESPTOOLPY_FLASHFREQ_20M
|
||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_20M
|
||||
freqdiv = 4;
|
||||
#endif
|
||||
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
esp_rom_spiflash_config_clk(freqdiv, 1);
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
uint32_t dummy_bit = 0;
|
||||
#if CONFIG_ESPTOOLPY_FLASHFREQ_80M
|
||||
dummy_bit = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_80M;
|
||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_40M
|
||||
dummy_bit = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_40M;
|
||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_26M
|
||||
dummy_bit = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_26M;
|
||||
#elif CONFIG_ESPTOOLPY_FLASHFREQ_20M
|
||||
dummy_bit = ESP_ROM_SPIFLASH_DUMMY_LEN_PLUS_20M;
|
||||
#endif
|
||||
g_rom_spiflash_dummy_len_plus[1] = dummy_bit;
|
||||
#else
|
||||
spi_dummy_len_fix(1, freqdiv);
|
||||
esp_rom_spiflash_config_readmode(read_mode);
|
||||
#if !CONFIG_IDF_TARGET_ESP32S2
|
||||
#endif//CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
esp_rom_spiflash_read_mode_t read_mode;
|
||||
#if CONFIG_ESPTOOLPY_FLASHMODE_QIO
|
||||
read_mode = ESP_ROM_SPIFLASH_QIO_MODE;
|
||||
#elif CONFIG_ESPTOOLPY_FLASHMODE_QOUT
|
||||
read_mode = ESP_ROM_SPIFLASH_QOUT_MODE;
|
||||
#elif CONFIG_ESPTOOLPY_FLASHMODE_DIO
|
||||
read_mode = ESP_ROM_SPIFLASH_DIO_MODE;
|
||||
#elif CONFIG_ESPTOOLPY_FLASHMODE_DOUT
|
||||
read_mode = ESP_ROM_SPIFLASH_DOUT_MODE;
|
||||
#endif
|
||||
|
||||
#if !CONFIG_IDF_TARGET_ESP32S2 && !CONFIG_IDF_TARGET_ESP32
|
||||
spi_common_set_dummy_output(read_mode);
|
||||
#endif //!CONFIG_IDF_TARGET_ESP32S2
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
esp_rom_spiflash_config_clk(freqdiv, 1);
|
||||
esp_rom_spiflash_config_readmode(read_mode);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void IRAM_ATTR test_write(int dst_off, int src_off, int len)
|
||||
{
|
||||
|
Reference in New Issue
Block a user