Просмотр исходного кода

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
Michael (XIAO Xufeng) 4 лет назад
Родитель
Сommit
c42ee1b790

+ 6 - 0
components/hal/esp32/include/hal/spi_flash_ll.h

@@ -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

+ 6 - 0
components/hal/esp32c3/include/hal/gpspi_flash_ll.h

@@ -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

+ 2 - 0
components/hal/esp32c3/include/hal/spi_flash_ll.h

@@ -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
 

+ 6 - 0
components/hal/esp32c3/include/hal/spimem_flash_ll.h

@@ -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

+ 6 - 0
components/hal/esp32s2/include/hal/gpspi_flash_ll.h

@@ -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

+ 2 - 0
components/hal/esp32s2/include/hal/spi_flash_ll.h

@@ -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
 

+ 6 - 0
components/hal/esp32s2/include/hal/spimem_flash_ll.h

@@ -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
 }

+ 6 - 0
components/hal/esp32s3/include/hal/gpspi_flash_ll.h

@@ -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

+ 2 - 0
components/hal/esp32s3/include/hal/spi_flash_ll.h

@@ -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

+ 6 - 0
components/hal/esp32s3/include/hal/spimem_flash_ll.h

@@ -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

+ 2 - 1
components/hal/include/hal/spi_flash_hal.h

@@ -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;
 

+ 1 - 0
components/hal/spi_flash_hal.c

@@ -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;

+ 2 - 0
components/hal/spi_flash_hal_common.inc

@@ -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) {

+ 5 - 0
components/spi_flash/esp_flash_spi_init.c

@@ -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 - 27
components/spi_flash/test/test_read_write.c

@@ -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)
 {