Răsfoiți Sursa

spi_flash: add support for ext flash

Cao Sen Miao 4 ani în urmă
părinte
comite
992de2750e

+ 8 - 1
.gitlab/ci/target-test.yml

@@ -699,7 +699,7 @@ UT_C3_FLASH_SUSPEND:
 
 UT_S3:
   extends: .unit_test_esp32s3_template
-  parallel: 26
+  parallel: 27
   tags:
     - ESP32S3_IDF
     - UT_T1_1
@@ -710,6 +710,13 @@ UT_S3_SPI_DUAL:
     - ESP32S3_IDF
     - Example_SPI_Multi_device
 
+UT_S3_FLASH:
+  extends: .unit_test_esp32s3_template
+  parallel: 2
+  tags:
+    - ESP32S3_IDF
+    - UT_T1_ESP_FLASH
+
 .integration_test_template:
   extends:
     - .target_test_job_template

+ 10 - 1
components/hal/esp32c3/include/hal/gpspi_flash_ll.h

@@ -148,12 +148,21 @@ static inline void gpspi_flash_ll_set_buffer_data(spi_dev_t *dev, const void *bu
  */
 static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
 {
-    dev->ctrl.hold_pol = 1;
     dev->cmd.update = 1;
     while (dev->cmd.update);
     dev->cmd.usr = 1;
 }
 
+/**
+ * Set HD pin high when flash work at spi mode.
+ *
+ * @param dev Beginning address of the peripheral registers.
+ */
+static inline void gpspi_flash_ll_set_hold_pol(spi_dev_t *dev, uint32_t pol_val)
+{
+    dev->ctrl.hold_pol = pol_val;
+}
+
 /**
  * Check whether the host is idle to perform new commands.
  *

+ 10 - 1
components/hal/esp32h2/include/hal/gpspi_flash_ll.h

@@ -148,12 +148,21 @@ static inline void gpspi_flash_ll_set_buffer_data(spi_dev_t *dev, const void *bu
  */
 static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
 {
-    dev->ctrl.hold_pol = 1;
     dev->cmd.update = 1;
     while (dev->cmd.update);
     dev->cmd.usr = 1;
 }
 
+/**
+ * Set HD pin high when flash work at spi mode.
+ *
+ * @param dev Beginning address of the peripheral registers.
+ */
+static inline void gpspi_flash_ll_set_hold_pol(spi_dev_t *dev, uint32_t pol_val)
+{
+    dev->ctrl.hold_pol = pol_val;
+}
+
 /**
  * Check whether the host is idle to perform new commands.
  *

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

@@ -147,6 +147,16 @@ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
     dev->cmd.usr = 1;
 }
 
+/**
+ * Set HD pin high when flash work at spi mode.
+ *
+ * @param dev Beginning address of the peripheral registers.
+ */
+static inline void gpspi_flash_ll_set_hold_pol(spi_dev_t *dev, uint32_t pol_val)
+{
+    // Not support on esp32s2
+}
+
 /**
  * Check whether the host is idle to perform new commands.
  *

+ 17 - 1
components/hal/esp32s3/include/hal/gpspi_flash_ll.h

@@ -85,7 +85,7 @@ static inline void gpspi_flash_ll_reset(spi_dev_t *dev)
  */
 static inline bool gpspi_flash_ll_cmd_is_done(const spi_dev_t *dev)
 {
-    return (dev->cmd.val == 0);
+    return (dev->cmd.usr == 0);
 }
 
 /**
@@ -158,6 +158,16 @@ static inline void gpspi_flash_ll_user_start(spi_dev_t *dev)
     dev->cmd.usr = 1;
 }
 
+/**
+ * Set HD pin high when flash work at spi mode.
+ *
+ * @param dev Beginning address of the peripheral registers.
+ */
+static inline void gpspi_flash_ll_set_hold_pol(spi_dev_t *dev, uint32_t pol_val)
+{
+    dev->ctrl.hold_pol = pol_val;
+}
+
 /**
  * Check whether the host is idle to perform new commands.
  *
@@ -376,6 +386,12 @@ static inline void gpspi_flash_ll_set_dummy_out(spi_dev_t *dev, uint32_t out_en,
     dev->ctrl.d_pol = out_lev;
 }
 
+/**
+ * Set extra hold time of CS after the clocks.
+ *
+ * @param dev Beginning address of the peripheral registers.
+ * @param hold_n Cycles of clocks before CS is inactive
+ */
 static inline void gpspi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n)
 {
     dev->user1.cs_hold_time = hold_n - 1;

+ 3 - 20
components/hal/spi_flash_hal_common.inc

@@ -65,7 +65,10 @@ esp_err_t spi_flash_hal_device_config(spi_flash_host_inst_t *host)
         spi_flash_hal_disable_auto_resume_mode(host);
     }
 #endif //SOC_SPI_MEM_SUPPORT_AUTO_SUSPEND
+#else
+    gpspi_flash_ll_set_hold_pol(dev, 1);
 #endif //GPSPI_BUILD
+
     return ESP_OK;
 }
 
@@ -94,26 +97,6 @@ esp_err_t spi_flash_hal_configure_host_io_mode(
         return ESP_ERR_NOT_SUPPORTED;
     }
 
-#if CONFIG_SPI_FLASH_ROM_IMPL && CONFIG_IDF_TARGET_ESP32S3
-    /*
-     * In S3 ROM, extra bits than 24-bit are used to indicate requirements of M7-M0:
-     * - 24: normal transactions
-     * - 28: 24bit DIO + conf bits (M7-M0 excluded from dummy_bitlen)
-     * - 32: 24bit QIO + conf bits (M7-M0 excluded from dummy_bitlen)
-
-     * Detect requirements for the conf bits by the address len, and modify the length to normal
-     * case (addr_bitlen = 24, dummy_bitlen includes M7-M0) as other chip versions use.
-     */
-    int m70_bits = addr_bitlen - 24;
-    if (m70_bits) {
-        HAL_ASSERT(io_mode == SPI_FLASH_DIO || io_mode == SPI_FLASH_QIO);
-        conf_required = true;
-        addr_bitlen -= m70_bits;
-        int line_width = (io_mode == SPI_FLASH_DIO? 2: 4);
-        dummy_cyclelen_base += m70_bits / line_width;
-    }
-#endif //CONFIG_SPI_FLASH_ROM_IMPL
-
 #if SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUTPUT
     // The CONTROL_DUMMY_OUTPUT feature is used to control M7-M0 bits.
     spi_flash_ll_set_dummy_out(dev, (conf_required? 1: 0), 1);

+ 1 - 1
components/soc/esp32s3/include/soc/spi_caps.h

@@ -28,7 +28,7 @@
 
 // Peripheral supports DIO, DOUT, QIO, or QOUT
 // VSPI (SPI3) only support 1-bit mode
-#define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(host_id)          ((host_id) != 2)
+#define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(host_id)          ({(void)host_id; 1;})
 
 // Peripheral supports output given level during its "dummy phase"
 #define SOC_SPI_PERIPH_SUPPORT_CONTROL_DUMMY_OUTPUT         1

+ 4 - 4
components/soc/esp32s3/spi_periph.c

@@ -73,12 +73,12 @@ const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = {
         .spid_out = SPI3_D_OUT_IDX,
         .spiq_out = SPI3_Q_OUT_IDX,
         //SPI3 doesn't have wp and hd signals
-        .spiwp_out = -1,
-        .spihd_out = -1,
+        .spiwp_out = SPI3_WP_OUT_IDX,
+        .spihd_out = SPI3_HD_OUT_IDX,
         .spid_in = SPI3_D_IN_IDX,
         .spiq_in = SPI3_Q_IN_IDX,
-        .spiwp_in = -1,
-        .spihd_in = -1,
+        .spiwp_in = SPI3_WP_IN_IDX,
+        .spihd_in = SPI3_HD_IN_IDX,
         .spics_out = {SPI3_CS0_OUT_IDX, SPI3_CS1_OUT_IDX, SPI3_CS2_OUT_IDX},
         .spics_in = SPI3_CS0_IN_IDX,
         //SPI3 doesn't have iomux pins

+ 12 - 17
components/spi_flash/test/test_esp_flash.c

@@ -86,12 +86,12 @@ static uint8_t sector_buf[4096];
 #define SPI1_HD_IO          27  //the pin which is usually used by the PSRAM hd
 #define SPI1_WP_IO          28  //the pin which is usually used by the PSRAM wp
 
-#define FSPI_PIN_NUM_MOSI   35
-#define FSPI_PIN_NUM_MISO   37
-#define FSPI_PIN_NUM_CLK    36
-#define FSPI_PIN_NUM_HD     33
-#define FSPI_PIN_NUM_WP     38
-#define FSPI_PIN_NUM_CS     34
+#define FSPI_PIN_NUM_MOSI   11
+#define FSPI_PIN_NUM_MISO   13
+#define FSPI_PIN_NUM_CLK    12
+#define FSPI_PIN_NUM_HD     9
+#define FSPI_PIN_NUM_WP     14
+#define FSPI_PIN_NUM_CS     10
 
 // Just use the same pins for HSPI
 #define HSPI_PIN_NUM_MOSI   FSPI_PIN_NUM_MOSI
@@ -139,8 +139,7 @@ typedef void (*flash_test_func_t)(const esp_partition_t *part);
 
    These tests run for all the flash chip configs shown in config_list, below (internal and external).
  */
-#if defined(CONFIG_SPIRAM) || TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
-// No S3 runner
+#if defined(CONFIG_SPIRAM)
 #define FLASH_TEST_CASE_3(STR, FUNCT_TO_RUN)
 #define FLASH_TEST_CASE_3_IGNORE(STR, FUNCT_TO_RUN)
 #else //CONFIG_SPIRAM
@@ -230,8 +229,11 @@ flashtest_config_t config_list[] = {
 };
 #elif CONFIG_IDF_TARGET_ESP32S3
 flashtest_config_t config_list[] = {
-    FLASHTEST_CONFIG_COMMON,
-    /* No runners for esp32s3 for these config yet */
+    /* No SPI1 CS1 flash on esp32S3 test */
+    {
+        /* no need to init */
+        .host_id = -1,
+    },
     {
         .io_mode = TEST_SPI_READ_MODE,
         .speed = TEST_SPI_SPEED,
@@ -904,15 +906,12 @@ TEST_CASE("SPI flash test reading with all speed/mode permutations", "[esp_flash
 }
 
 #ifndef CONFIG_SPIRAM
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
-// No S3 runner
 TEST_CASE("SPI flash test reading with all speed/mode permutations, 3 chips", "[esp_flash_3][test_env=UT_T1_ESP_FLASH]")
 {
     for (int i = 0; i < TEST_CONFIG_NUM; i++) {
         test_permutations_chip(&config_list[i]);
     }
 }
-#endif// !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
 #endif
 
 
@@ -983,9 +982,6 @@ static void test_write_large_buffer(const esp_partition_t* part, const uint8_t *
 
 #if !CONFIG_SPIRAM
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
-// No S3 runner
-
 typedef struct {
     uint32_t us_start;
     size_t len;
@@ -1164,7 +1160,6 @@ static void test_flash_read_write_performance(const esp_partition_t *part)
 
 
 TEST_CASE("Test esp_flash read/write performance", "[esp_flash][test_env=UT_T1_ESP_FLASH]") {flash_test_func(test_flash_read_write_performance, 1);}
-#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3)
 
 #endif // !CONFIG_SPIRAM
 FLASH_TEST_CASE_3("Test esp_flash read/write performance"", 3 chips", test_flash_read_write_performance);

+ 3 - 0
tools/unit-test-app/configs/rom_options_s3

@@ -0,0 +1,3 @@
+CONFIG_IDF_TARGET="esp32s3"
+TEST_COMPONENTS=spi_flash
+CONFIG_SPI_FLASH_ROM_IMPL=y