mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
spi_flash: fix cs line setup to make the flash driver more stable
This commit is contained in:
parent
88c2b69c68
commit
9c7d2c7595
@ -237,6 +237,7 @@ static void test_bus_lock(bool test_flash)
|
||||
.io_mode = SPI_FLASH_DIO,
|
||||
.speed = ESP_FLASH_5MHZ,
|
||||
.input_delay_ns = 0,
|
||||
.cs_setup = 1,
|
||||
};
|
||||
|
||||
//Clamp the WP and HD pins to VDD to make it work in DIO mode
|
||||
|
@ -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
|
||||
|
@ -34,6 +34,7 @@ typedef struct {
|
||||
* automatically assigned by the SPI bus lock.
|
||||
*/
|
||||
int cs_id;
|
||||
uint32_t cs_setup; ///< (cycles-1) of prepare phase by spi clock
|
||||
} esp_flash_spi_device_config_t;
|
||||
|
||||
/**
|
||||
|
@ -177,6 +177,7 @@ static const char TAG[] = "test_esp_flash";
|
||||
/* the pin which is usually used by the PSRAM */ \
|
||||
.cs_io_num = SPI1_CS_IO, \
|
||||
.input_delay_ns = 0, \
|
||||
.cs_setup = 1,\
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
@ -199,6 +200,7 @@ flashtest_config_t config_list[] = {
|
||||
.cs_id = 0,
|
||||
.cs_io_num = VSPI_PIN_NUM_CS,
|
||||
.input_delay_ns = 0,
|
||||
.cs_setup = 1,\
|
||||
},
|
||||
};
|
||||
#elif CONFIG_IDF_TARGET_ESP32S2
|
||||
@ -211,6 +213,7 @@ flashtest_config_t config_list[] = {
|
||||
.cs_id = 0,
|
||||
.cs_io_num = FSPI_PIN_NUM_CS,
|
||||
.input_delay_ns = 0,
|
||||
.cs_setup = 1,\
|
||||
},
|
||||
{
|
||||
.io_mode = TEST_SPI_READ_MODE,
|
||||
@ -220,6 +223,7 @@ flashtest_config_t config_list[] = {
|
||||
// uses GPIO matrix on esp32s2 regardless of FORCE_GPIO_MATRIX
|
||||
.cs_io_num = HSPI_PIN_NUM_CS,
|
||||
.input_delay_ns = 0,
|
||||
.cs_setup = 1,\
|
||||
},
|
||||
};
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
@ -233,6 +237,7 @@ flashtest_config_t config_list[] = {
|
||||
.cs_id = 0,
|
||||
.cs_io_num = FSPI_PIN_NUM_CS,
|
||||
.input_delay_ns = 0,
|
||||
.cs_setup = 1,\
|
||||
},
|
||||
};
|
||||
#elif CONFIG_IDF_TARGET_ESP32C3
|
||||
@ -249,6 +254,7 @@ flashtest_config_t config_list[] = {
|
||||
.cs_id = 0,
|
||||
.cs_io_num = FSPI_PIN_NUM_CS,
|
||||
.input_delay_ns = 0,
|
||||
.cs_setup = 1,\
|
||||
},
|
||||
};
|
||||
#endif
|
||||
@ -385,6 +391,7 @@ static void setup_new_chip(const flashtest_config_t* test_cfg, esp_flash_t** out
|
||||
.cs_id = test_cfg->cs_id,
|
||||
.cs_io_num = test_cfg->cs_io_num,
|
||||
.input_delay_ns = test_cfg->input_delay_ns,
|
||||
.cs_setup = test_cfg->cs_setup,
|
||||
};
|
||||
esp_flash_t* init_chip;
|
||||
esp_err_t err = spi_bus_add_flash_device(&init_chip, &dev_cfg);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -103,7 +103,8 @@ static esp_flash_t* example_init_ext_flash(void)
|
||||
.cs_id = 0,
|
||||
.cs_io_num = VSPI_IOMUX_PIN_NUM_CS,
|
||||
.io_mode = SPI_FLASH_DIO,
|
||||
.speed = ESP_FLASH_40MHZ
|
||||
.speed = ESP_FLASH_40MHZ,
|
||||
.cs_setup = 1,
|
||||
};
|
||||
|
||||
ESP_LOGI(TAG, "Initializing external SPI Flash");
|
||||
|
Loading…
Reference in New Issue
Block a user