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

Merge branch 'feature/support_spi_on_8684' into 'master'

spi: support spi on 8684

Closes IDF-4470 and IDF-4024

See merge request espressif/esp-idf!16475
Armando (Dou Yiwen) 4 лет назад
Родитель
Сommit
342c830d9b
34 измененных файлов с 613 добавлено и 362 удалено
  1. 12 5
      components/driver/spi_master.c
  2. 6 3
      components/driver/test/include/test/test_common_spi.h
  3. 1 5
      components/driver/test/test_common_spi.c
  4. 16 24
      components/driver/test/test_spi_bus_lock.c
  5. 39 31
      components/driver/test/test_spi_master.c
  6. 4 4
      components/driver/test/test_spi_param.c
  7. 90 58
      components/driver/test/test_spi_sio.c
  8. 8 12
      components/driver/test/test_spi_slave.c
  9. 9 11
      components/driver/test/test_spi_slave_hd.c
  10. 315 67
      components/hal/esp8684/include/hal/spi_ll.h
  11. 10 16
      components/hal/include/hal/spi_hal.h
  12. 6 1
      components/hal/include/hal/spi_types.h
  13. 8 14
      components/hal/spi_hal.c
  14. 6 14
      components/hal/spi_hal_iram.c
  15. 7 13
      components/idf_test/include/esp32/idf_performance_target.h
  16. 7 13
      components/idf_test/include/esp32c3/idf_performance_target.h
  17. 7 13
      components/idf_test/include/esp32h2/idf_performance_target.h
  18. 3 1
      components/idf_test/include/esp32s2/idf_performance_target.h
  19. 3 1
      components/idf_test/include/esp32s3/idf_performance_target.h
  20. 5 3
      components/idf_test/include/esp8684/idf_performance_target.h
  21. 0 7
      components/idf_test/include/idf_performance.h
  22. 8 4
      components/soc/esp32/include/soc/Kconfig.soc_caps.in
  23. 9 7
      components/soc/esp32/include/soc/soc_caps.h
  24. 4 0
      components/soc/esp32s2/include/soc/Kconfig.soc_caps.in
  25. 7 7
      components/soc/esp32s2/include/soc/soc_caps.h
  26. 0 4
      components/soc/esp32s3/include/soc/Kconfig.soc_caps.in
  27. 1 2
      components/soc/esp32s3/include/soc/soc_caps.h
  28. 7 7
      docs/en/api-reference/peripherals/spi_master.rst
  29. 2 2
      docs/en/api-reference/peripherals/spi_slave.rst
  30. 2 1
      examples/peripherals/spi_slave_hd/segment_mode/README.md
  31. 2 2
      examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c
  32. 2 2
      examples/peripherals/spi_slave_hd/segment_mode/seg_slave/README.md
  33. 7 2
      examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c
  34. 0 6
      tools/ci/check_copyright_ignore.txt

+ 12 - 5
components/driver/spi_master.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -121,6 +121,8 @@ We have two bits to control the interrupt:
 #include "driver/gpio.h"
 #include "hal/spi_hal.h"
 #include "esp_heap_caps.h"
+//Temporarily include soc/rtc.h, will be replaced by clock tree API
+#include "soc/rtc.h"
 
 
 typedef struct spi_device_t spi_device_t;
@@ -318,7 +320,9 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
     spi_host_t *host = bus_driver_ctx[host_id];
     const spi_bus_attr_t* bus_attr = host->bus_attr;
     SPI_CHECK(dev_config->spics_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(dev_config->spics_io_num), "spics pin invalid", ESP_ERR_INVALID_ARG);
-    SPI_CHECK(dev_config->clock_speed_hz > 0, "invalid sclk speed", ESP_ERR_INVALID_ARG);
+    uint32_t apb_clk_freq_hz = rtc_clk_apb_freq_get();
+    assert((apb_clk_freq_hz == 80 * 1000 * 1000) || (apb_clk_freq_hz == 40 * 1000 * 1000));
+    SPI_CHECK((dev_config->clock_speed_hz > 0) && (dev_config->clock_speed_hz <= apb_clk_freq_hz) , "invalid sclk speed", ESP_ERR_INVALID_ARG);
 #ifdef CONFIG_IDF_TARGET_ESP32
     //The hardware looks like it would support this, but actually setting cs_ena_pretrans when transferring in full
     //duplex mode does absolutely nothing on the ESP32.
@@ -345,9 +349,11 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
     int duty_cycle = (dev_config->duty_cycle_pos==0) ? 128 : dev_config->duty_cycle_pos;
     int use_gpio = !(bus_attr->flags & SPICOMMON_BUSFLAG_IOMUX_PINS);
     spi_hal_timing_param_t timing_param = {
+        .clk_src_hz = rtc_clk_apb_freq_get(),
+        .clk_sel = SPI_CLK_APB,     //Currently, SPI driver only set SPI to APB clock. SPI is not supposed to be used during sleep modes.
         .half_duplex = half_duplex,
         .no_compensate = no_compensate,
-        .clock_speed_hz = dev_config->clock_speed_hz,
+        .expected_freq = dev_config->clock_speed_hz,
         .duty_cycle = duty_cycle,
         .input_delay_ns = dev_config->input_delay_ns,
         .use_gpio = use_gpio
@@ -406,7 +412,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
     hal_dev->tx_lsbfirst = dev_config->flags & SPI_DEVICE_TXBIT_LSBFIRST ? 1 : 0;
     hal_dev->rx_lsbfirst = dev_config->flags & SPI_DEVICE_RXBIT_LSBFIRST ? 1 : 0;
     hal_dev->no_compensate = dev_config->flags & SPI_DEVICE_NO_DUMMY ? 1 : 0;
-#if SOC_SPI_SUPPORT_AS_CS
+#if SOC_SPI_AS_CS_SUPPORTED
     hal_dev->as_cs = dev_config->flags& SPI_DEVICE_CLK_AS_CS ? 1 : 0;
 #endif
     hal_dev->positive_cs = dev_config->flags & SPI_DEVICE_POSITIVE_CS ? 1 : 0;
@@ -699,7 +705,8 @@ static SPI_MASTER_ISR_ATTR esp_err_t check_trans_valid(spi_device_handle_t handl
     SPI_CHECK(!((trans_desc->flags & (SPI_TRANS_MODE_DIO|SPI_TRANS_MODE_QIO)) && !is_half_duplex), "Incompatible when setting to both multi-line mode and half duplex mode", ESP_ERR_INVALID_ARG);
 #ifdef CONFIG_IDF_TARGET_ESP32
     SPI_CHECK(!is_half_duplex || !bus_attr->dma_enabled || !rx_enabled || !tx_enabled, "SPI half duplex mode does not support using DMA with both MOSI and MISO phases.", ESP_ERR_INVALID_ARG );
-#elif CONFIG_IDF_TARGET_ESP32S3
+#endif
+#if !SOC_SPI_HD_BOTH_INOUT_SUPPORTED
     SPI_CHECK(!is_half_duplex || !tx_enabled || !rx_enabled, "SPI half duplex mode is not supported when both MOSI and MISO phases are enabled.", ESP_ERR_INVALID_ARG);
 #endif
     //MOSI phase is skipped only when both tx_buffer and SPI_TRANS_USE_TXDATA are not set.

+ 6 - 3
components/driver/test/include/test/test_common_spi.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -21,6 +21,9 @@
 
 // All the tests using the header should use this definition as much as possible,
 // so that the working host can be changed easily in the future.
+
+#define TEST_SPI_PERIPH_NUM     (SOC_SPI_PERIPH_NUM - 1)
+
 #if CONFIG_IDF_TARGET_ESP32
 #define TEST_SPI_HOST           SPI2_HOST
 #define TEST_SLAVE_HOST         SPI3_HOST
@@ -83,8 +86,8 @@
 #define ESP_SPI_SLAVE_TV        0
 #define WIRE_DELAY              12.5
 
-#elif CONFIG_IDF_TARGET_ESP32C3
-//NOTE: On esp32c3, there is only 1 GPSPI controller, so master-slave test on single board should be disabled
+#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684
+//NOTE: On these chips, there is only 1 GPSPI controller, so master-slave test on single board should be disabled
 #define TEST_SPI_HOST           SPI2_HOST
 #define TEST_SLAVE_HOST         SPI2_HOST
 

+ 1 - 5
components/driver/test/test_common_spi.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -9,8 +9,6 @@
 #include "driver/gpio.h"
 #include "hal/gpio_hal.h"
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP8684)
-// TODO: SPI support IDF-4024
 
 int test_freq_default[]=TEST_FREQ_DEFAULT();
 
@@ -250,5 +248,3 @@ void get_tx_buffer(uint32_t seed, uint8_t *master_send_buf, uint8_t *slave_send_
         master_send_buf[i] = rand();
     }
 }
-
-#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP8684)

+ 16 - 24
components/driver/test/test_spi_bus_lock.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -12,8 +12,6 @@
 #include "test/test_common_spi.h"
 #include "unity.h"
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C3, ESP8684)
-// No runners currently.
 
 #if CONFIG_IDF_TARGET_ESP32
 // The VSPI pins on UT_T1_ESP_FLASH are connected to a external flash
@@ -24,13 +22,13 @@
 #define TEST_BUS_PIN_NUM_WP     VSPI_IOMUX_PIN_NUM_WP
 #define TEST_BUS_PIN_NUM_HD     VSPI_IOMUX_PIN_NUM_HD
 
-#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
-#define TEST_BUS_PIN_NUM_MISO   FSPI_IOMUX_PIN_NUM_MISO
-#define TEST_BUS_PIN_NUM_MOSI   FSPI_IOMUX_PIN_NUM_MOSI
-#define TEST_BUS_PIN_NUM_CLK    FSPI_IOMUX_PIN_NUM_CLK
-#define TEST_BUS_PIN_NUM_CS     FSPI_IOMUX_PIN_NUM_CS
-#define TEST_BUS_PIN_NUM_WP     FSPI_IOMUX_PIN_NUM_WP
-#define TEST_BUS_PIN_NUM_HD     FSPI_IOMUX_PIN_NUM_HD
+#else
+#define TEST_BUS_PIN_NUM_MISO   SPI2_IOMUX_PIN_NUM_MISO
+#define TEST_BUS_PIN_NUM_MOSI   SPI2_IOMUX_PIN_NUM_MOSI
+#define TEST_BUS_PIN_NUM_CLK    SPI2_IOMUX_PIN_NUM_CLK
+#define TEST_BUS_PIN_NUM_CS     SPI2_IOMUX_PIN_NUM_CS
+#define TEST_BUS_PIN_NUM_WP     SPI2_IOMUX_PIN_NUM_WP
+#define TEST_BUS_PIN_NUM_HD     SPI2_IOMUX_PIN_NUM_HD
 
 #endif
 
@@ -225,17 +223,13 @@ static void test_bus_lock(bool test_flash)
     devcfg.queue_size = 100;
 
     //Initialize the SPI bus and 3 devices
-    ret=spi_bus_initialize(TEST_SPI_HOST, &buscfg, 1);
-    TEST_ESP_OK(ret);
-    ret=spi_bus_add_device(TEST_SPI_HOST, &devcfg, &context1.handle);
-    TEST_ESP_OK(ret);
-    ret=spi_bus_add_device(TEST_SPI_HOST, &devcfg, &context2.handle);
-    TEST_ESP_OK(ret);
+    TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
+    TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &context1.handle));
+    TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &context2.handle));
 
     //only have 3 cs pins, leave one for the flash
     devcfg.spics_io_num = -1;
-    ret=spi_bus_add_device(TEST_SPI_HOST, &devcfg, &context3.handle);
-    TEST_ESP_OK(ret);
+    TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &context3.handle));
     esp_flash_spi_device_config_t flash_cfg = {
         .host_id = TEST_SPI_HOST,
         .cs_id = 2,
@@ -285,7 +279,7 @@ static void test_bus_lock(bool test_flash)
     TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST) );
 }
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
+#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3, ESP32S3, ESP8684)
 //no runners
 TEST_CASE("spi bus lock, with flash","[spi][test_env=UT_T1_ESP_FLASH]")
 {
@@ -299,8 +293,8 @@ TEST_CASE("spi bus lock","[spi]")
     test_bus_lock(false);
 }
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
-//SPI1 not supported by driver
+#if !DISABLED_FOR_TARGETS(ESP32S2, ESP32C3, ESP32S3, ESP8684, ESP32H2)
+//disable, SPI1 is not available for GPSPI usage on chips later than ESP32
 static IRAM_ATTR esp_err_t test_polling_send(spi_device_handle_t handle)
 {
     for (int i = 0; i < 10; i++) {
@@ -347,10 +341,8 @@ TEST_CASE("spi master can be used on SPI1", "[spi]")
     err = spi_bus_remove_device(handle);
     TEST_ESP_OK(err);
 }
-#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
+#endif  //disable, SPI1 is not available for GPSPI usage on chips later than ESP32
 
 //TODO: add a case when a non-polling transaction happened in the bus-acquiring time and then release the bus then queue a new trans
 
 #endif //!CONFIG_ESP32_SPIRAM_SUPPORT
-
-#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C3)

+ 39 - 31
components/driver/test/test_spi_master.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -29,9 +29,8 @@
 #include "../cache_utils.h"
 #include "soc/soc_memory_layout.h"
 #include "driver/spi_common_internal.h"
+#include "soc/rtc.h"
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP8684)
-// TODO: SPI SUPPORT IDF-4024
 
 const static char TAG[] = "test_spi";
 
@@ -40,7 +39,6 @@ const static char TAG[] = "test_spi";
 
 static void check_spi_pre_n_for(int clk, int pre, int n)
 {
-    esp_err_t ret;
     spi_device_handle_t handle;
 
     spi_device_interface_config_t devcfg = {
@@ -57,12 +55,11 @@ static void check_spi_pre_n_for(int clk, int pre, int n)
     spi_transaction_t t;
     memset(&t, 0, sizeof(t));
 
-    ret = spi_bus_add_device(TEST_SPI_HOST, &devcfg, &handle);
-    TEST_ASSERT(ret == ESP_OK);
+    TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &handle));
 
     t.length = 16 * 8;
     t.tx_buffer = sendbuf;
-    ret = spi_device_transmit(handle, &t);
+    TEST_ESP_OK(spi_device_transmit(handle, &t));
 
     spi_dev_t *hw = spi_periph_signal[TEST_SPI_HOST].hw;
 
@@ -71,10 +68,20 @@ static void check_spi_pre_n_for(int clk, int pre, int n)
     TEST_ASSERT(hw->clock.clkcnt_n + 1 == n);
     TEST_ASSERT(hw->clock.clkdiv_pre + 1 == pre);
 
-    ret = spi_bus_remove_device(handle);
-    TEST_ASSERT(ret == ESP_OK);
+    TEST_ESP_OK(spi_bus_remove_device(handle));
 }
 
+#define TEST_CLK_TIMES              8
+/**
+ * In this test, SPI Clock Calculation:
+ *   Fspi = Fclk_spi_mst / (pre + n)
+ *
+ * For each item:
+ * {freq, pre, n}
+ */
+#define TEST_CLK_PARAM_APB_80       {{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 16, 50}, {333333, 4, 60}, {800000, 2, 50}, {900000, 2, 44}, {8000000, 1, 10}, {20000000, 1, 4}, {26000000, 1, 3} }
+#define TEST_CLK_PARAM_APB_40       {{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 8, 50}, {333333, 2, 60}, {800000, 1, 50}, {900000, 1, 44}, {8000000, 1, 5}, {10000000, 1, 4}, {20000000, 1, 2} }
+
 TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
 {
     spi_bus_config_t buscfg = {
@@ -84,22 +91,23 @@ TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
         .quadwp_io_num = -1,
         .quadhd_io_num = -1
     };
-    esp_err_t ret;
-    ret = spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO);
-    TEST_ASSERT(ret == ESP_OK);
+    TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, SPI_DMA_CH_AUTO));
 
-    check_spi_pre_n_for(26000000, 1, 3);
-    check_spi_pre_n_for(20000000, 1, 4);
-    check_spi_pre_n_for(8000000, 1, 10);
-    check_spi_pre_n_for(800000, 2, 50);
-    check_spi_pre_n_for(100000, 16, 50);
-    check_spi_pre_n_for(333333, 4, 60);
-    check_spi_pre_n_for(900000, 2, 44);
-    check_spi_pre_n_for(1, SOC_SPI_MAX_PRE_DIVIDER, 64); //Actually should generate the minimum clock speed, 152Hz
-    check_spi_pre_n_for(26000000, 1, 3);
-
-    ret = spi_bus_free(TEST_SPI_HOST);
-    TEST_ASSERT(ret == ESP_OK);
+    uint32_t apb_freq_hz = rtc_clk_apb_freq_get();
+    if (apb_freq_hz == (80 * MHZ)) {
+        uint32_t clk_param[TEST_CLK_TIMES][3] = TEST_CLK_PARAM_APB_80;
+        for (int i = 0; i < TEST_CLK_TIMES; i++) {
+            check_spi_pre_n_for(clk_param[i][0], clk_param[i][1], clk_param[i][2]);
+        }
+    } else {
+        TEST_ASSERT(apb_freq_hz == (40 * MHZ));
+        uint32_t clk_param[TEST_CLK_TIMES][3] = TEST_CLK_PARAM_APB_40;
+        for (int i = 0; i < TEST_CLK_TIMES; i++) {
+            check_spi_pre_n_for(clk_param[i][0], clk_param[i][1], clk_param[i][2]);
+        }
+    }
+
+    TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST));
 }
 
 static spi_device_handle_t setup_spi_bus_loopback(int clkspeed, bool dma)
@@ -285,7 +293,7 @@ TEST_CASE("SPI Master test, interaction of multiple devs", "[spi]")
     TEST_ASSERT(success);
 }
 
-#if TEST_SOC_HAS_INPUT_ONLY_PINS  //There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
+#if TEST_SOC_HAS_INPUT_ONLY_PINS  //There is no input-only pin, so this test could be ignored.
 static esp_err_t test_master_pins(int mosi, int miso, int sclk, int cs)
 {
     esp_err_t ret;
@@ -783,7 +791,9 @@ TEST_CASE("SPI Master DMA test: length, start, not aligned", "[spi]")
 }
 
 
-#if !DISABLED_FOR_TARGETS(ESP32C3)  //There is only one GPSPI controller, so single-board test is disabled.
+#if (TEST_SPI_PERIPH_NUM >= 2)
+//These will only be enabled on chips with 2 or more SPI peripherals
+
 static uint8_t bitswap(uint8_t in)
 {
     uint8_t out = 0;
@@ -1111,9 +1121,7 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]")
     spi_slave_free(TEST_SLAVE_HOST);
     master_free_device_bus(spi);
 }
-
-//There is only one GPSPI controller, so single-board test is disabled.
-#endif  //#if !DISABLED_FOR_TARGETS(ESP32C3)
+#endif  //#if (TEST_SPI_PERIPH_NUM >= 2)
 
 #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32)    //TODO: IDF-3494
 #define FD_TEST_BUF_SIZE    32
@@ -1308,6 +1316,8 @@ TEST_CASE_MULTIPLE_DEVICES("SPI Master: FD, DMA, Master Single Direction Test",
 #define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ)
 #elif CONFIG_IDF_TARGET_ESP32C3
 #define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP32C3_DEFAULT_CPU_FREQ_MHZ)
+#elif CONFIG_IDF_TARGET_ESP8684
+#define GET_US_BY_CCOUNT(t) ((double)t/CONFIG_ESP8684_DEFAULT_CPU_FREQ_MHZ)
 #endif
 
 static void speed_setup(spi_device_handle_t *spi, bool use_dma)
@@ -1445,5 +1455,3 @@ TEST_CASE("spi_speed", "[spi]")
     master_free_device_bus(spi);
 }
 #endif // CONFIG_FREERTOS_CHECK_PORT_CRITICAL_COMPLIANCE
-
-#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP8684)

+ 4 - 4
components/driver/test/test_spi_param.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -11,8 +11,8 @@
 #include "driver/spi_master.h"
 #include "driver/spi_slave.h"
 
-#if !DISABLED_FOR_TARGETS(ESP32C3, ESP8684)
-//There is only one GPSPI controller on ESP32C3 and ESP8684, so single-board test is disabled.
+#if (TEST_SPI_PERIPH_NUM >= 2)
+//These will only be enabled on chips with 2 or more SPI peripherals
 
 #ifndef MIN
 #define MIN(a, b)((a) > (b)? (b): (a))
@@ -1177,4 +1177,4 @@ TEST_SPI_MASTER_SLAVE(MODE, mode_conf, "")
 
 #endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3, ESP32C3)
 
-#endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C3, ESP8684)
+#endif // #if (TEST_SPI_PERIPH_NUM >= 2)

+ 90 - 58
components/driver/test/test_spi_sio.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -29,88 +29,122 @@
 
 #include "hal/spi_ll.h"
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP8684)
-#if !DISABLED_FOR_TARGETS(ESP32C3)  //There is only one GPSPI controller, so single-board test is disabled.
+#if (TEST_SPI_PERIPH_NUM >= 2)
+//These will be only enabled on chips with 2 or more SPI peripherals
 
 /********************************************************************************
  *      Test SIO
  ********************************************************************************/
-TEST_CASE("local test sio", "[spi]")
+#if CONFIG_IDF_TARGET_ESP32
+#define MASTER_DIN_SIGNAL    HSPID_IN_IDX
+#else
+#define MASTER_DIN_SIGNAL    FSPID_IN_IDX
+#endif
+static void inner_connect(spi_bus_config_t bus)
 {
+    //Master MOSI(spid_out) output to `mosi_num`
+    spitest_gpio_output_sel(bus.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
+    //Slave MOSI(spid_in) input to `mosi_num`
+    spitest_gpio_input_sel(bus.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spid_in);
+
+
+    //Master MOSI input(spid_in) to `miso_num`, due to SIO mode, we use Master's `spid_in` to receive data
+    spitest_gpio_input_sel(bus.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_in);
+    //Slave MISO output(spiq_out)
+    spitest_gpio_output_sel(bus.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
+    //Force this signal goes through gpio matrix
+    GPIO.func_in_sel_cfg[MASTER_DIN_SIGNAL].sig_in_sel = 1;
+}
+
+TEST_CASE("SPI Single Board Test SIO", "[spi]")
+{
+    //Master init
     spi_device_handle_t spi;
-    WORD_ALIGNED_ATTR uint8_t master_rx_buffer[320];
-    WORD_ALIGNED_ATTR uint8_t slave_rx_buffer[320];
+    spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
 
-    uint32_t pre_set[16] = {[0 ... 15] = 0xcccccccc,};
-    spi_ll_write_buffer(SPI_LL_GET_HW(TEST_SPI_HOST),   (uint8_t*)pre_set, 16*32);
-    spi_ll_write_buffer(SPI_LL_GET_HW(TEST_SLAVE_HOST), (uint8_t*)pre_set, 16*32);
+    TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, SPI_DMA_DISABLED));
 
-    /* This test use a strange connection to test the SIO mode:
-     * master spid -> slave spid
-     * slave spiq -> master spid
-     */
-    spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
     spi_device_interface_config_t dev_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
+    dev_cfg.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE;
+    dev_cfg.clock_speed_hz = 4 * 1000 * 1000;
+    TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi));
+
+    //Slave init
+    bus_cfg.flags = 0;
     spi_slave_interface_config_t slv_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
-    slv_cfg.spics_io_num = dev_cfg.spics_io_num;
-    TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slv_cfg, 0));
+    TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slv_cfg, SPI_DMA_DISABLED));
 
-    int miso_io_num = bus_cfg.miso_io_num;
-    int mosi_io_num = bus_cfg.mosi_io_num;
-    bus_cfg.mosi_io_num = miso_io_num;
-    bus_cfg.miso_io_num = -1;
-    TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, 0));
 
-    dev_cfg.flags = SPI_DEVICE_HALFDUPLEX | SPI_DEVICE_3WIRE;
-    TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi));
+    same_pin_func_sel(bus_cfg, dev_cfg, 0);
+    inner_connect(bus_cfg);
 
-    spitest_gpio_output_sel(mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
-    spitest_gpio_output_sel(miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
-    spitest_gpio_output_sel(dev_cfg.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
-    spitest_gpio_output_sel(bus_cfg.sclk_io_num, FUNC_GPIO,  spi_periph_signal[TEST_SPI_HOST].spiclk_out);
+
+    WORD_ALIGNED_ATTR uint8_t master_rx_buffer[320];
+    WORD_ALIGNED_ATTR uint8_t slave_rx_buffer[320];
+
+    spi_transaction_t mst_trans;
+    spi_slave_transaction_t slv_trans;
+    spi_slave_transaction_t* ret;
 
     for (int i = 0; i < 8; i ++) {
-        int tlen = i*2+1;
-        int rlen = 9-i;
+        int tlen = i * 2 + 1;
+        int rlen = 9 - i;
 
-        ESP_LOGI(MASTER_TAG, "=========== TEST%d ==========", i);
+        ESP_LOGI("spi", "=========== TEST(%d) Master TX, Slave RX ==========", i);
 
-        spi_transaction_t master_t = {
-            .length = tlen*8,
-            .tx_buffer = spitest_master_send+i,
-            .rxlength = rlen*8,
-            .rx_buffer = master_rx_buffer+i,
-        };
-        spi_slave_transaction_t slave_t = {
-            .length = (tlen+rlen)*8,
-            .tx_buffer = spitest_slave_send+i,
-            .rx_buffer = slave_rx_buffer,
-        };
-        memset(master_rx_buffer, 0x66, sizeof(master_rx_buffer));
+        //Slave RX
+        memset(&slv_trans, 0x0, sizeof(spi_slave_transaction_t));
         memset(slave_rx_buffer, 0x66, sizeof(slave_rx_buffer));
-        TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_t, portMAX_DELAY));
+        slv_trans.length = tlen * 8;
+        slv_trans.rx_buffer = slave_rx_buffer + tlen * 8;
+        TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slv_trans, portMAX_DELAY));
 
-        TEST_ESP_OK(spi_device_transmit(spi, &master_t));
-        spi_slave_transaction_t* ret_t;
-        TEST_ESP_OK(spi_slave_get_trans_result(TEST_SLAVE_HOST, &ret_t, portMAX_DELAY));
-        TEST_ASSERT(ret_t == &slave_t);
+        //Master TX
+        memset(&mst_trans, 0x0, sizeof(spi_transaction_t));
+        mst_trans.length = tlen * 8;
+        mst_trans.tx_buffer = spitest_master_send;
+        TEST_ESP_OK(spi_device_transmit(spi, &mst_trans));
+
+        TEST_ESP_OK(spi_slave_get_trans_result(TEST_SLAVE_HOST, &ret, portMAX_DELAY));
+        TEST_ASSERT(ret == &slv_trans);
+
+        ESP_LOG_BUFFER_HEXDUMP("master tx", mst_trans.tx_buffer, tlen, ESP_LOG_INFO);
+        ESP_LOG_BUFFER_HEXDUMP("slave rx", slv_trans.rx_buffer, tlen, ESP_LOG_INFO);
+        TEST_ASSERT_EQUAL_HEX8_ARRAY(mst_trans.tx_buffer, slv_trans.rx_buffer, tlen);
+
+
+        ESP_LOGI("spi", "=========== TEST(%d) Master RX, Slave TX ==========", i);
+        //Slave TX
+        memset(&slv_trans, 0x0, sizeof(spi_slave_transaction_t));
 
-        ESP_LOG_BUFFER_HEXDUMP("master tx", master_t.tx_buffer, tlen, ESP_LOG_INFO);
-        ESP_LOG_BUFFER_HEXDUMP("slave rx", slave_t.rx_buffer, tlen+rlen, ESP_LOG_INFO);
-        ESP_LOG_BUFFER_HEXDUMP("slave tx", slave_t.tx_buffer, tlen+rlen, ESP_LOG_INFO);
-        ESP_LOG_BUFFER_HEXDUMP("master rx", master_t.rx_buffer, rlen, ESP_LOG_INFO);
+        slv_trans.length = rlen * 8;
+        slv_trans.tx_buffer = spitest_slave_send + rlen * 8;
+        TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slv_trans, portMAX_DELAY));
 
-        TEST_ASSERT_EQUAL_HEX8_ARRAY(master_t.tx_buffer, slave_t.rx_buffer, tlen);
-        TEST_ASSERT_EQUAL_HEX8_ARRAY(slave_t.tx_buffer + tlen, master_t.rx_buffer, rlen);
+        //Master RX
+        memset(&mst_trans, 0x0, sizeof(spi_transaction_t));
+        memset(master_rx_buffer, 0x66, sizeof(master_rx_buffer));
+        mst_trans.rxlength = rlen * 8;
+        mst_trans.rx_buffer = master_rx_buffer;
+        TEST_ESP_OK(spi_device_transmit(spi, &mst_trans));
+
+        TEST_ESP_OK(spi_slave_get_trans_result(TEST_SLAVE_HOST, &ret, portMAX_DELAY));
+        TEST_ASSERT(ret == &slv_trans);
+
+        ESP_LOG_BUFFER_HEXDUMP("slave tx", slv_trans.tx_buffer, rlen, ESP_LOG_INFO);
+        ESP_LOG_BUFFER_HEXDUMP("master rx", mst_trans.rx_buffer, rlen, ESP_LOG_INFO);
+
+        TEST_ASSERT_EQUAL_HEX8_ARRAY(slv_trans.tx_buffer, mst_trans.rx_buffer, rlen);
     }
 
     spi_slave_free(TEST_SLAVE_HOST);
     master_free_device_bus(spi);
 }
-#endif //!DISABLED_FOR_TARGETS(ESP32C3)  //There is only one GPSPI controller, so single-board test is disabled.
+#endif //#if (TEST_SPI_PERIPH_NUM >= 2)
 
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3, ESP8684)
+//TODO IDF-4455
+#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3, ESP32S3, ESP8684, ESP32H2)
 //These tests are ESP32 only due to lack of runners
 /********************************************************************************
  *      Test SIO Master & Slave
@@ -228,6 +262,4 @@ void test_sio_slave(void)
 }
 
 TEST_CASE_MULTIPLE_DEVICES("sio mode", "[spi][test_env=Example_SPI_Multi_device]", test_sio_master, test_sio_slave);
-#endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3)
-
-#endif // !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S3, ESP32C3)
+#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3, ESP8684, ESP32H2)

+ 8 - 12
components/driver/test/test_spi_slave.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -17,11 +17,9 @@
 #include "esp_log.h"
 #include "esp_rom_gpio.h"
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP8684)
-// TODO: SPI SUPPORT IDF-4024
 
-//There is only one GPSPI controller, so single-board test is disabled.
-#if !DISABLED_FOR_TARGETS(ESP32C3)
+#if (TEST_SPI_PERIPH_NUM >= 2)
+//These will only be enabled on chips with 2 or more SPI peripherals
 
 #ifndef CONFIG_SPIRAM
 //This test should be removed once the timing test is merged.
@@ -261,15 +259,15 @@ TEST_CASE("test slave send unaligned","[spi]")
 
 #endif // !CONFIG_SPIRAM
 
-#endif // !TEMPORARY_DISABLED_FOR_TARGETS
+#endif // #if (TEST_SPI_PERIPH_NUM >= 2)
 
-
-#if !DISABLED_FOR_TARGETS(ESP32, ESP32S2, ESP32S3)
+#if (TEST_SPI_PERIPH_NUM == 1)
 //These tests are for chips which only have 1 SPI controller
 /********************************************************************************
  *      Test By Master & Slave (2 boards)
  *
- *      PIN | Master(C3) | Slave (C3) |
+ * Master (C3, 8684, H2) && Slave (C3, 8684, H2):
+ *      PIN | Master     | Slave      |
  *      ----| ---------  | ---------  |
  *      CS  | 10         | 10         |
  *      CLK | 6          | 6          |
@@ -385,6 +383,4 @@ static void unaligned_test_slave(void)
 
 TEST_CASE_MULTIPLE_DEVICES("SPI_Slave_Unaligned_Test", "[spi_ms][test_env=Example_SPI_Multi_device][timeout=120]", unaligned_test_master, unaligned_test_slave);
 
-#endif  //#if !DISABLED_FOR_TARGETS(ESP32, ESP32S2, ESP32S3)
-
-#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP8684)
+#endif  //#if (TEST_SPI_PERIPH_NUM == 1)

+ 9 - 11
components/driver/test/test_spi_slave_hd.c

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -17,11 +17,9 @@
 #include "driver/spi_master.h"
 #include "esp_serial_slave_link/essl_spi.h"
 
-#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP8684)
-// TODO: SPI SUPPORT IDF-4024
 
-#if !DISABLED_FOR_TARGETS(ESP32C3)
-//There is only one GPSPI controller on ESP32C3, so single-board test is disabled.
+#if (TEST_SPI_PERIPH_NUM >= 2)
+//These will be only enabled on chips with 2 or more SPI peripherals
 
 #if SOC_SPI_SUPPORT_SLAVE_HD_VER2
 #include "driver/spi_slave_hd.h"
@@ -598,15 +596,17 @@ TEST_CASE("test spi slave hd segment mode, master too long", "[spi][spi_slv_hd]"
 }
 
 #endif //SOC_SPI_SUPPORT_SLAVE_HD_VER2
-#endif //#if !DISABLED_FOR_TARGETS(ESP32C3)
+#endif //#if (TEST_SPI_PERIPH_NUM >= 2)
 
-#if !DISABLED_FOR_TARGETS(ESP32, ESP32S2, ESP32S3)
+
+#if (TEST_SPI_PERIPH_NUM == 1)
 #if SOC_SPI_SUPPORT_SLAVE_HD_VER2
 //These tests are for chips which only have 1 SPI controller
 /********************************************************************************
  *      Test By Master & Slave (2 boards)
  *
- *      PIN | Master(C3) | Slave (C3) |
+ * Master (C3, 8684, H2) && Slave (C3, 8684, H2):
+ *      PIN | Master     | Slave      |
  *      ----| ---------  | ---------  |
  *      CS  | 10         | 10         |
  *      CLK | 6          | 6          |
@@ -752,6 +752,4 @@ TEST_CASE_MULTIPLE_DEVICES("SPI Slave HD: segment mode, master sends too long",
 
 #endif  //#if SOC_SPI_SUPPORT_SLAVE_HD_VER2
 
-#endif  //#if !DISABLED_FOR_TARGETS(ESP32, ESP32S2, ESP32S3)
-
-#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP8684)
+#endif  //#if (TEST_SPI_PERIPH_NUM == 1)

+ 315 - 67
components/hal/esp8684/include/hal/spi_ll.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -82,7 +82,26 @@ FLAG_ATTR(spi_ll_trans_len_cond_t)
  */
 static inline void spi_ll_master_init(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    //Reset timing
+    hw->user1.cs_setup_time = 0;
+    hw->user1.cs_hold_time = 0;
+
+    //use all 64 bytes of the buffer
+    hw->user.usr_miso_highpart = 0;
+    hw->user.usr_mosi_highpart = 0;
+
+    //Disable unneeded ints
+    hw->slave.val = 0;
+    hw->user.val = 0;
+
+    hw->clk_gate.clk_en = 1;
+    hw->clk_gate.mst_clk_active = 1;
+    hw->clk_gate.mst_clk_sel = 1;
+
+    hw->dma_conf.val = 0;
+    hw->dma_conf.tx_seg_trans_clr_en = 1;
+    hw->dma_conf.rx_seg_trans_clr_en = 1;
+    hw->dma_conf.dma_seg_trans_en = 0;
 }
 
 /**
@@ -92,7 +111,25 @@ static inline void spi_ll_master_init(spi_dev_t *hw)
  */
 static inline void spi_ll_slave_init(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    //Configure slave
+    hw->clock.val = 0;
+    hw->user.val = 0;
+    hw->ctrl.val = 0;
+    hw->user.doutdin = 1; //we only support full duplex
+    hw->user.sio = 0;
+    hw->slave.slave_mode = 1;
+    hw->slave.soft_reset = 1;
+    hw->slave.soft_reset = 0;
+    //use all 64 bytes of the buffer
+    hw->user.usr_miso_highpart = 0;
+    hw->user.usr_mosi_highpart = 0;
+
+    // Configure DMA In-Link to not be terminated when transaction bit counter exceeds
+    hw->dma_conf.rx_eof_en = 0;
+    hw->dma_conf.dma_seg_trans_en = 0;
+
+    //Disable unneeded ints
+    hw->dma_int_ena.val &= ~SPI_LL_UNUSED_INT_MASK;
 }
 
 /**
@@ -102,7 +139,15 @@ static inline void spi_ll_slave_init(spi_dev_t *hw)
  */
 static inline void spi_ll_slave_hd_init(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->clock.val = 0;
+    hw->user.val = 0;
+    hw->ctrl.val = 0;
+    hw->user.doutdin = 0;
+    hw->user.sio = 0;
+
+    hw->slave.soft_reset = 1;
+    hw->slave.soft_reset = 0;
+    hw->slave.slave_mode = 1;
 }
 
 /**
@@ -114,7 +159,7 @@ static inline void spi_ll_slave_hd_init(spi_dev_t *hw)
  */
 static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    return hw->dma_int_raw.trans_done;
 }
 
 /**
@@ -125,7 +170,9 @@ static inline bool spi_ll_usr_is_done(spi_dev_t *hw)
  */
 static inline void spi_ll_master_user_start(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->cmd.update = 1;
+    while (hw->cmd.update);
+    hw->cmd.usr = 1;
 }
 
 /**
@@ -135,7 +182,7 @@ static inline void spi_ll_master_user_start(spi_dev_t *hw)
  */
 static inline void spi_ll_slave_user_start(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->cmd.usr = 1;
 }
 
 /**
@@ -147,7 +194,7 @@ static inline void spi_ll_slave_user_start(spi_dev_t *hw)
  */
 static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    return hw->cmd.val;
 }
 
 /**
@@ -157,7 +204,8 @@ static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw)
  */
 static inline void spi_ll_slave_reset(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->slave.soft_reset = 1;
+    hw->slave.soft_reset = 0;
 }
 
 /**
@@ -169,7 +217,8 @@ static inline void spi_ll_slave_reset(spi_dev_t *hw)
  */
 static inline void spi_ll_cpu_tx_fifo_reset(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_conf.buf_afifo_rst = 1;
+    hw->dma_conf.buf_afifo_rst = 0;
 }
 
 /**
@@ -181,7 +230,8 @@ static inline void spi_ll_cpu_tx_fifo_reset(spi_dev_t *hw)
  */
 static inline void spi_ll_cpu_rx_fifo_reset(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_conf.rx_afifo_rst = 1;
+    hw->dma_conf.rx_afifo_rst = 0;
 }
 
 /**
@@ -191,7 +241,8 @@ static inline void spi_ll_cpu_rx_fifo_reset(spi_dev_t *hw)
  */
 static inline void spi_ll_dma_tx_fifo_reset(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_conf.dma_afifo_rst = 1;
+    hw->dma_conf.dma_afifo_rst = 0;
 }
 
 /**
@@ -201,7 +252,8 @@ static inline void spi_ll_dma_tx_fifo_reset(spi_dev_t *hw)
  */
 static inline void spi_ll_dma_rx_fifo_reset(spi_dev_t *hw)
 {
-   abort(); // TODO: SPI support IDF-4024
+    hw->dma_conf.rx_afifo_rst = 1;
+    hw->dma_conf.rx_afifo_rst = 0;
 }
 
 /**
@@ -211,7 +263,7 @@ static inline void spi_ll_dma_rx_fifo_reset(spi_dev_t *hw)
  */
 static inline void spi_ll_infifo_full_clr(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_int_clr.infifo_full_err = 1;
 }
 
 /**
@@ -221,7 +273,7 @@ static inline void spi_ll_infifo_full_clr(spi_dev_t *hw)
  */
 static inline void spi_ll_outfifo_empty_clr(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_int_clr.outfifo_empty_err = 1;
 }
 
 /*------------------------------------------------------------------------------
@@ -235,7 +287,7 @@ static inline void spi_ll_outfifo_empty_clr(spi_dev_t *hw)
  */
 static inline void spi_ll_dma_rx_enable(spi_dev_t *hw, bool enable)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_conf.dma_rx_ena = enable;
 }
 
 /**
@@ -246,7 +298,7 @@ static inline void spi_ll_dma_rx_enable(spi_dev_t *hw, bool enable)
  */
 static inline void spi_ll_dma_tx_enable(spi_dev_t *hw, bool enable)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_conf.dma_tx_ena = enable;
 }
 
 /**
@@ -257,7 +309,7 @@ static inline void spi_ll_dma_tx_enable(spi_dev_t *hw, bool enable)
  */
 static inline void spi_ll_dma_set_rx_eof_generation(spi_dev_t *hw, bool enable)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_conf.rx_eof_en = enable;
 }
 
 /*------------------------------------------------------------------------------
@@ -272,7 +324,12 @@ static inline void spi_ll_dma_set_rx_eof_generation(spi_dev_t *hw, bool enable)
  */
 static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_send, size_t bitlen)
 {
-    abort(); // TODO: SPI support IDF-4024
+    for (int x = 0; x < bitlen; x += 32) {
+        //Use memcpy to get around alignment issues for txdata
+        uint32_t word;
+        memcpy(&word, &buffer_to_send[x / 8], 4);
+        hw->data_buf[(x / 32)] = word;
+    }
 }
 
 /**
@@ -285,7 +342,29 @@ static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_s
  */
 static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *data, int len)
 {
-    abort(); // TODO: SPI support IDF-4024
+    HAL_ASSERT(byte_id + len <= 64);
+    HAL_ASSERT(len > 0);
+    HAL_ASSERT(byte_id >= 0);
+
+    while (len > 0) {
+        uint32_t word;
+        int offset = byte_id % 4;
+        int copy_len = 4 - offset;
+        if (copy_len > len) {
+            copy_len = len;
+        }
+
+        //read-modify-write
+        if (copy_len != 4) {
+            word = hw->data_buf[byte_id / 4];    //read
+        }
+        memcpy(((uint8_t *)&word) + offset, data, copy_len);  //modify
+        hw->data_buf[byte_id / 4] = word;                     //write
+
+        data += copy_len;
+        byte_id += copy_len;
+        len -= copy_len;
+    }
 }
 
 /**
@@ -297,7 +376,15 @@ static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t
  */
 static inline void spi_ll_read_buffer(spi_dev_t *hw, uint8_t *buffer_to_rcv, size_t bitlen)
 {
-    abort(); // TODO: SPI support IDF-4024
+    for (int x = 0; x < bitlen; x += 32) {
+        //Do a memcpy to get around possible alignment issues in rx_buffer
+        uint32_t word = hw->data_buf[x / 32];
+        int len = bitlen - x;
+        if (len > 32) {
+            len = 32;
+        }
+        memcpy(&buffer_to_rcv[x / 8], &word, (len + 7) / 8);
+    }
 }
 
 /**
@@ -310,7 +397,19 @@ static inline void spi_ll_read_buffer(spi_dev_t *hw, uint8_t *buffer_to_rcv, siz
  */
 static inline void spi_ll_read_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *out_data, int len)
 {
-    abort(); // TODO: SPI support IDF-4024
+    while (len > 0) {
+        uint32_t word = hw->data_buf[byte_id / 4];
+        int offset = byte_id % 4;
+        int copy_len = 4 - offset;
+        if (copy_len > len) {
+            copy_len = len;
+        }
+
+        memcpy(out_data, ((uint8_t *)&word) + offset, copy_len);
+        byte_id += copy_len;
+        out_data += copy_len;
+        len -= copy_len;
+    }
 }
 
 /*------------------------------------------------------------------------------
@@ -325,7 +424,11 @@ static inline void spi_ll_read_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *
  */
 static inline void spi_ll_master_set_pos_cs(spi_dev_t *hw, int cs, uint32_t pos_cs)
 {
-    abort(); // TODO: SPI support IDF-4024
+    if (pos_cs) {
+        hw->misc.master_cs_pol |= (1 << cs);
+    } else {
+        hw->misc.master_cs_pol &= ~(1 << cs);
+    }
 }
 
 /**
@@ -358,7 +461,20 @@ static inline void spi_ll_set_rx_lsbfirst(spi_dev_t *hw, bool lsbfirst)
  */
 static inline void spi_ll_master_set_mode(spi_dev_t *hw, uint8_t mode)
 {
-    abort(); // TODO: SPI support IDF-4024
+    //Configure polarity
+    if (mode == 0) {
+        hw->misc.ck_idle_edge = 0;
+        hw->user.ck_out_edge = 0;
+    } else if (mode == 1) {
+        hw->misc.ck_idle_edge = 0;
+        hw->user.ck_out_edge = 1;
+    } else if (mode == 2) {
+        hw->misc.ck_idle_edge = 1;
+        hw->user.ck_out_edge = 1;
+    } else if (mode == 3) {
+        hw->misc.ck_idle_edge = 1;
+        hw->user.ck_out_edge = 0;
+    }
 }
 
 /**
@@ -369,7 +485,28 @@ static inline void spi_ll_master_set_mode(spi_dev_t *hw, uint8_t mode)
  */
 static inline void spi_ll_slave_set_mode(spi_dev_t *hw, const int mode, bool dma_used)
 {
-    abort(); // TODO: SPI support IDF-4024
+    if (mode == 0) {
+        hw->misc.ck_idle_edge = 0;
+        hw->user.rsck_i_edge = 0;
+        hw->user.tsck_i_edge = 0;
+        hw->slave.clk_mode_13 = 0;
+    } else if (mode == 1) {
+        hw->misc.ck_idle_edge = 0;
+        hw->user.rsck_i_edge = 1;
+        hw->user.tsck_i_edge = 1;
+        hw->slave.clk_mode_13 = 1;
+    } else if (mode == 2) {
+        hw->misc.ck_idle_edge = 1;
+        hw->user.rsck_i_edge = 1;
+        hw->user.tsck_i_edge = 1;
+        hw->slave.clk_mode_13 = 0;
+    } else if (mode == 3) {
+        hw->misc.ck_idle_edge = 1;
+        hw->user.rsck_i_edge = 0;
+        hw->user.tsck_i_edge = 0;
+        hw->slave.clk_mode_13 = 1;
+    }
+    hw->slave.rsck_data_out = 0;
 }
 
 /**
@@ -380,7 +517,7 @@ static inline void spi_ll_slave_set_mode(spi_dev_t *hw, const int mode, bool dma
  */
 static inline void spi_ll_set_half_duplex(spi_dev_t *hw, bool half_duplex)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->user.doutdin = !half_duplex;
 }
 
 /**
@@ -393,7 +530,7 @@ static inline void spi_ll_set_half_duplex(spi_dev_t *hw, bool half_duplex)
  */
 static inline void spi_ll_set_sio_mode(spi_dev_t *hw, int sio_mode)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->user.sio = sio_mode;
 }
 
 /**
@@ -404,7 +541,16 @@ static inline void spi_ll_set_sio_mode(spi_dev_t *hw, int sio_mode)
  */
 static inline void spi_ll_master_set_line_mode(spi_dev_t *hw, spi_line_mode_t line_mode)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->ctrl.val &= ~SPI_LL_ONE_LINE_CTRL_MASK;
+    hw->user.val &= ~SPI_LL_ONE_LINE_USER_MASK;
+    hw->ctrl.fcmd_dual = (line_mode.cmd_lines == 2);
+    hw->ctrl.fcmd_quad = (line_mode.cmd_lines == 4);
+    hw->ctrl.faddr_dual = (line_mode.addr_lines == 2);
+    hw->ctrl.faddr_quad = (line_mode.addr_lines == 4);
+    hw->ctrl.fread_dual = (line_mode.data_lines == 2);
+    hw->user.fwrite_dual = (line_mode.data_lines == 2);
+    hw->ctrl.fread_quad = (line_mode.data_lines == 4);
+    hw->user.fwrite_quad = (line_mode.data_lines == 4);
 }
 
 /**
@@ -426,7 +572,12 @@ static inline void spi_ll_slave_set_seg_mode(spi_dev_t *hw, bool seg_trans)
  */
 static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->misc.cs0_dis = (cs_id == 0) ? 0 : 1;
+    hw->misc.cs1_dis = (cs_id == 1) ? 0 : 1;
+    hw->misc.cs2_dis = (cs_id == 2) ? 0 : 1;
+    hw->misc.cs3_dis = (cs_id == 3) ? 0 : 1;
+    hw->misc.cs4_dis = (cs_id == 4) ? 0 : 1;
+    hw->misc.cs5_dis = (cs_id == 5) ? 0 : 1;
 }
 
 /**
@@ -451,7 +602,7 @@ static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active)
  */
 static inline void spi_ll_master_set_clock_by_reg(spi_dev_t *hw, const spi_ll_clock_val_t *val)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->clock.val = *(uint32_t *)val;
 }
 
 /**
@@ -465,7 +616,7 @@ static inline void spi_ll_master_set_clock_by_reg(spi_dev_t *hw, const spi_ll_cl
  */
 static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
 {
-    abort(); // TODO: SPI support IDF-4024
+    return (fapb / (pre * n));
 }
 
 /**
@@ -480,7 +631,66 @@ static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n)
  */
 static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg)
 {
-    abort(); // TODO: SPI support IDF-4024
+typeof(GPSPI2.clock) reg;
+    int eff_clk;
+
+    //In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value.
+    if (hz > ((fapb / 4) * 3)) {
+        //Using Fapb directly will give us the best result here.
+        reg.clkcnt_l = 0;
+        reg.clkcnt_h = 0;
+        reg.clkcnt_n = 0;
+        reg.clkdiv_pre = 0;
+        reg.clk_equ_sysclk = 1;
+        eff_clk = fapb;
+    } else {
+        //For best duty cycle resolution, we want n to be as close to 32 as possible, but
+        //we also need a pre/n combo that gets us as close as possible to the intended freq.
+        //To do this, we bruteforce n and calculate the best pre to go along with that.
+        //If there's a choice between pre/n combos that give the same result, use the one
+        //with the higher n.
+        int pre, n, h, l;
+        int bestn = -1;
+        int bestpre = -1;
+        int besterr = 0;
+        int errval;
+        for (n = 2; n <= 64; n++) { //Start at 2: we need to be able to set h/l so we have at least one high and one low pulse.
+            //Effectively, this does pre=round((fapb/n)/hz).
+            pre = ((fapb / n) + (hz / 2)) / hz;
+            if (pre <= 0) {
+                pre = 1;
+            }
+            if (pre > 16) {
+                pre = 16;
+            }
+            errval = abs(spi_ll_freq_for_pre_n(fapb, pre, n) - hz);
+            if (bestn == -1 || errval <= besterr) {
+                besterr = errval;
+                bestn = n;
+                bestpre = pre;
+            }
+        }
+
+        n = bestn;
+        pre = bestpre;
+        l = n;
+        //This effectively does round((duty_cycle*n)/256)
+        h = (duty_cycle * n + 127) / 256;
+        if (h <= 0) {
+            h = 1;
+        }
+
+        reg.clk_equ_sysclk = 0;
+        reg.clkcnt_n = n - 1;
+        reg.clkdiv_pre = pre - 1;
+        reg.clkcnt_h = h - 1;
+        reg.clkcnt_l = l - 1;
+        eff_clk = spi_ll_freq_for_pre_n(fapb, pre, n);
+    }
+    if (out_reg != NULL) {
+        *(uint32_t *)out_reg = reg.val;
+    }
+    return eff_clk;
 }
 
 /**
@@ -500,7 +710,10 @@ static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_
  */
 static inline int spi_ll_master_set_clock(spi_dev_t *hw, int fapb, int hz, int duty_cycle)
 {
-    abort(); // TODO: SPI support IDF-4024
+    spi_ll_clock_val_t reg_val;
+    int freq = spi_ll_master_cal_clock(fapb, hz, duty_cycle, &reg_val);
+    spi_ll_master_set_clock_by_reg(hw, &reg_val);
+    return freq;
 }
 
 /**
@@ -537,7 +750,8 @@ static inline void spi_ll_set_miso_delay(spi_dev_t *hw, int delay_mode, int dela
  */
 static inline void spi_ll_master_set_cs_hold(spi_dev_t *hw, int hold)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->user1.cs_hold_time = hold;
+    hw->user.cs_hold = hold ? 1 : 0;
 }
 
 /**
@@ -551,7 +765,8 @@ static inline void spi_ll_master_set_cs_hold(spi_dev_t *hw, int hold)
  */
 static inline void spi_ll_master_set_cs_setup(spi_dev_t *hw, uint8_t setup)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->user1.cs_setup_time = setup - 1;
+    hw->user.cs_setup = setup ? 1 : 0;
 }
 
 /*------------------------------------------------------------------------------
@@ -566,7 +781,9 @@ static inline void spi_ll_master_set_cs_setup(spi_dev_t *hw, uint8_t setup)
  */
 static inline void spi_ll_set_mosi_bitlen(spi_dev_t *hw, size_t bitlen)
 {
-    abort(); // TODO: SPI support IDF-4024
+    if (bitlen > 0) {
+        hw->ms_dlen.ms_data_bitlen = bitlen - 1;
+    }
 }
 
 /**
@@ -577,7 +794,9 @@ static inline void spi_ll_set_mosi_bitlen(spi_dev_t *hw, size_t bitlen)
  */
 static inline void spi_ll_set_miso_bitlen(spi_dev_t *hw, size_t bitlen)
 {
-    abort(); // TODO: SPI support IDF-4024
+    if (bitlen > 0) {
+        hw->ms_dlen.ms_data_bitlen = bitlen - 1;
+    }
 }
 
 /**
@@ -588,7 +807,7 @@ static inline void spi_ll_set_miso_bitlen(spi_dev_t *hw, size_t bitlen)
  */
 static inline void spi_ll_slave_set_rx_bitlen(spi_dev_t *hw, size_t bitlen)
 {
-    abort(); // TODO: SPI support IDF-4024
+    //This is not used in esp8684
 }
 
 /**
@@ -599,7 +818,7 @@ static inline void spi_ll_slave_set_rx_bitlen(spi_dev_t *hw, size_t bitlen)
  */
 static inline void spi_ll_slave_set_tx_bitlen(spi_dev_t *hw, size_t bitlen)
 {
-    abort(); // TODO: SPI support IDF-4024
+    //This is not used in esp8684
 }
 
 /**
@@ -613,7 +832,8 @@ static inline void spi_ll_slave_set_tx_bitlen(spi_dev_t *hw, size_t bitlen)
  */
 static inline void spi_ll_set_command_bitlen(spi_dev_t *hw, int bitlen)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->user2.usr_command_bitlen = bitlen - 1;
+    hw->user.usr_command = bitlen ? 1 : 0;
 }
 
 /**
@@ -627,7 +847,8 @@ static inline void spi_ll_set_command_bitlen(spi_dev_t *hw, int bitlen)
  */
 static inline void spi_ll_set_addr_bitlen(spi_dev_t *hw, int bitlen)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->user1.usr_addr_bitlen = bitlen - 1;
+    hw->user.usr_addr = bitlen ? 1 : 0;
 }
 
 /**
@@ -642,7 +863,21 @@ static inline void spi_ll_set_addr_bitlen(spi_dev_t *hw, int bitlen)
  */
 static inline void spi_ll_set_address(spi_dev_t *hw, uint64_t addr, int addrlen, uint32_t lsbfirst)
 {
-    abort(); // TODO: SPI support IDF-4024
+    if (lsbfirst) {
+        /* The output address start from the LSB of the highest byte, i.e.
+        * addr[24] -> addr[31]
+        * ...
+        * addr[0] -> addr[7]
+        * So swap the byte order to let the LSB sent first.
+        */
+        addr = HAL_SWAP32(addr);
+        //otherwise only addr register is sent
+        hw->addr = addr;
+    } else {
+        // shift the address to MSB of addr register.
+        // output address will be sent from MSB to LSB of addr register
+        hw->addr = addr << (32 - addrlen);
+    }
 }
 
 /**
@@ -657,7 +892,16 @@ static inline void spi_ll_set_address(spi_dev_t *hw, uint64_t addr, int addrlen,
  */
 static inline void spi_ll_set_command(spi_dev_t *hw, uint16_t cmd, int cmdlen, bool lsbfirst)
 {
-    abort(); // TODO: SPI support IDF-4024
+    if (lsbfirst) {
+        // The output command start from bit0 to bit 15, kept as is.
+        HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user2, usr_command_value, cmd);
+    } else {
+        /* Output command will be sent from bit 7 to 0 of command_value, and
+         * then bit 15 to 8 of the same register field. Shift and swap to send
+         * more straightly.
+         */
+        HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user2, usr_command_value, HAL_SPI_SWAP_DATA_TX(cmd, cmdlen));
+    }
 }
 
 /**
@@ -671,7 +915,8 @@ static inline void spi_ll_set_command(spi_dev_t *hw, uint16_t cmd, int cmdlen, b
  */
 static inline void spi_ll_set_dummy(spi_dev_t *hw, int dummy_n)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->user.usr_dummy = dummy_n ? 1 : 0;
+    HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user1, usr_dummy_cyclelen, dummy_n - 1);
 }
 
 /**
@@ -682,7 +927,7 @@ static inline void spi_ll_set_dummy(spi_dev_t *hw, int dummy_n)
  */
 static inline void spi_ll_enable_miso(spi_dev_t *hw, int enable)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->user.usr_miso = enable;
 }
 
 /**
@@ -693,7 +938,7 @@ static inline void spi_ll_enable_miso(spi_dev_t *hw, int enable)
  */
 static inline void spi_ll_enable_mosi(spi_dev_t *hw, int enable)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->user.usr_mosi = enable;
 }
 
 /**
@@ -705,7 +950,7 @@ static inline void spi_ll_enable_mosi(spi_dev_t *hw, int enable)
  */
 static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    return hw->slave1.data_bitlen;
 }
 
 /*------------------------------------------------------------------------------
@@ -714,16 +959,16 @@ static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw)
 //helper macros to generate code for each interrupts
 #define FOR_EACH_ITEM(op, list) do { list(op) } while(0)
 #define INTR_LIST(item)    \
-    item(SPI_LL_INTR_TRANS_DONE,    dma_int_ena.trans_done,         dma_int_raw.trans_done,         dma_int_clr.trans_done=1) \
-    item(SPI_LL_INTR_RDBUF,         dma_int_ena.rd_buf_done,        dma_int_raw.rd_buf_done,        dma_int_clr.rd_buf_done=1) \
-    item(SPI_LL_INTR_WRBUF,         dma_int_ena.wr_buf_done,        dma_int_raw.wr_buf_done,        dma_int_clr.wr_buf_done=1) \
-    item(SPI_LL_INTR_RDDMA,         dma_int_ena.rd_dma_done,        dma_int_raw.rd_dma_done,        dma_int_clr.rd_dma_done=1) \
-    item(SPI_LL_INTR_WRDMA,         dma_int_ena.wr_dma_done,        dma_int_raw.wr_dma_done,        dma_int_clr.wr_dma_done=1) \
-    item(SPI_LL_INTR_SEG_DONE,      dma_int_ena.dma_seg_trans_done, dma_int_raw.dma_seg_trans_done, dma_int_clr.dma_seg_trans_done=1) \
-    item(SPI_LL_INTR_CMD7,          dma_int_ena.cmd7,               dma_int_raw.cmd7,               dma_int_clr.cmd7=1) \
-    item(SPI_LL_INTR_CMD8,          dma_int_ena.cmd8,               dma_int_raw.cmd8,               dma_int_clr.cmd8=1) \
-    item(SPI_LL_INTR_CMD9,          dma_int_ena.cmd9,               dma_int_raw.cmd9,               dma_int_clr.cmd9=1) \
-    item(SPI_LL_INTR_CMDA,          dma_int_ena.cmda,               dma_int_raw.cmda,               dma_int_clr.cmda=1)
+    item(SPI_LL_INTR_TRANS_DONE,    dma_int_ena.trans_done,         dma_int_raw.trans_done,         dma_int_clr.trans_done,         dma_int_set.trans_done_int_set) \
+    item(SPI_LL_INTR_RDBUF,         dma_int_ena.rd_buf_done,        dma_int_raw.rd_buf_done,        dma_int_clr.rd_buf_done,        dma_int_set.rd_buf_done_int_set) \
+    item(SPI_LL_INTR_WRBUF,         dma_int_ena.wr_buf_done,        dma_int_raw.wr_buf_done,        dma_int_clr.wr_buf_done,        dma_int_set.wr_buf_done_int_set) \
+    item(SPI_LL_INTR_RDDMA,         dma_int_ena.rd_dma_done,        dma_int_raw.rd_dma_done,        dma_int_clr.rd_dma_done,        dma_int_set.rd_dma_done_int_set) \
+    item(SPI_LL_INTR_WRDMA,         dma_int_ena.wr_dma_done,        dma_int_raw.wr_dma_done,        dma_int_clr.wr_dma_done,        dma_int_set.wr_dma_done_int_set) \
+    item(SPI_LL_INTR_SEG_DONE,      dma_int_ena.dma_seg_trans_done, dma_int_raw.dma_seg_trans_done, dma_int_clr.dma_seg_trans_done, dma_int_set.dma_seg_trans_done_int_set) \
+    item(SPI_LL_INTR_CMD7,          dma_int_ena.cmd7,               dma_int_raw.cmd7,               dma_int_clr.cmd7,               dma_int_set.cmd7_int_set) \
+    item(SPI_LL_INTR_CMD8,          dma_int_ena.cmd8,               dma_int_raw.cmd8,               dma_int_clr.cmd8,               dma_int_set.cmd8_int_set) \
+    item(SPI_LL_INTR_CMD9,          dma_int_ena.cmd9,               dma_int_raw.cmd9,               dma_int_clr.cmd9,               dma_int_set.cmd9_int_set) \
+    item(SPI_LL_INTR_CMDA,          dma_int_ena.cmda,               dma_int_raw.cmda,               dma_int_clr.cmda,               dma_int_set.cmda_int_set)
 
 
 static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
@@ -742,21 +987,21 @@ static inline void spi_ll_disable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
 
 static inline void spi_ll_set_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
 {
-#define SET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit)) hw->st_reg = 1;
+#define SET_INTR(intr_bit, _, __, ___, set_reg) if (intr_mask & (intr_bit)) hw->set_reg = 1;
     FOR_EACH_ITEM(SET_INTR, INTR_LIST);
 #undef SET_INTR
 }
 
 static inline void spi_ll_clear_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
 {
-#define CLR_INTR(intr_bit, _, __, clr_reg) if (intr_mask & (intr_bit)) hw->clr_reg;
+#define CLR_INTR(intr_bit, _, __, clr_reg, ...) if (intr_mask & (intr_bit)) hw->clr_reg = 1;
     FOR_EACH_ITEM(CLR_INTR, INTR_LIST);
 #undef CLR_INTR
 }
 
 static inline bool spi_ll_get_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
 {
-#define GET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit) && hw->st_reg) return true;
+#define GET_INTR(intr_bit, _, raw_reg, ...) if (intr_mask & (intr_bit) && hw->raw_reg) return true;
     FOR_EACH_ITEM(GET_INTR, INTR_LIST);
     return false;
 #undef GET_INTR
@@ -772,7 +1017,7 @@ static inline bool spi_ll_get_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
  */
 static inline void spi_ll_disable_int(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_int_ena.trans_done = 0;
 }
 
 /**
@@ -782,7 +1027,7 @@ static inline void spi_ll_disable_int(spi_dev_t *hw)
  */
 static inline void spi_ll_clear_int_stat(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_int_clr.trans_done = 1;
 }
 
 /**
@@ -792,7 +1037,7 @@ static inline void spi_ll_clear_int_stat(spi_dev_t *hw)
  */
 static inline void spi_ll_set_int_stat(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_int_set.trans_done_int_set = 1;
 }
 
 /**
@@ -802,7 +1047,7 @@ static inline void spi_ll_set_int_stat(spi_dev_t *hw)
  */
 static inline void spi_ll_enable_int(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->dma_int_ena.trans_done = 1;
 }
 
 /*------------------------------------------------------------------------------
@@ -810,17 +1055,20 @@ static inline void spi_ll_enable_int(spi_dev_t *hw)
  *----------------------------------------------------------------------------*/
 static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t *hw, spi_ll_trans_len_cond_t cond_mask)
 {
-    abort(); // TODO: SPI support IDF-4024
+    hw->slave.rdbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
+    hw->slave.wrbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
+    hw->slave.rddma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDDMA) ? 1 : 0;
+    hw->slave.wrdma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRDMA) ? 1 : 0;
 }
 
 static inline int spi_ll_slave_get_rx_byte_len(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    return hw->slave1.data_bitlen / 8;
 }
 
 static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
 {
-    abort(); // TODO: SPI support IDF-4024
+    return hw->slave1.last_addr;
 }
 
 #undef SPI_LL_RST_MASK

+ 10 - 16
components/hal/include/hal/spi_hal.h

@@ -1,16 +1,8 @@
-// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// 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.
+/*
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 /*******************************************************************************
  * NOTICE
@@ -44,10 +36,12 @@
  * Input parameters to the ``spi_hal_cal_clock_conf`` to calculate the timing configuration
  */
 typedef struct {
+    spi_clock_source_t clk_sel;         ///< Select SPI clock source
+    uint32_t clk_src_hz;                ///< Selected SPI clock source speed in Hz
     uint32_t half_duplex;               ///< Whether half duplex mode is used, device specific
     uint32_t no_compensate;             ///< No need to add dummy to compensate the timing, device specific
-    uint32_t clock_speed_hz;            ///< Desired frequency.
-    uint32_t duty_cycle;                ///< Desired duty cycle of SPI clock
+    uint32_t expected_freq;             ///< Expected frequency in Hz.
+    uint32_t duty_cycle;                ///< Expected duty cycle of SPI clock
     uint32_t input_delay_ns;            /**< Maximum delay between SPI launch clock and the data to be valid.
                                          *   This is used to compensate/calculate the maximum frequency allowed.
                                          *   Left 0 if not known.
@@ -151,7 +145,7 @@ typedef struct {
         uint32_t tx_lsbfirst : 1;       ///< Whether LSB is sent first for TX data, device specific
         uint32_t rx_lsbfirst : 1;       ///< Whether LSB is received first for RX data, device specific
         uint32_t no_compensate : 1;     ///< No need to add dummy to compensate the timing, device specific
-#if SOC_SPI_SUPPORT_AS_CS
+#if SOC_SPI_AS_CS_SUPPORTED
         uint32_t as_cs  : 1;            ///< Whether to toggle the CS while the clock toggles, device specific
 #endif
         uint32_t positive_cs : 1;       ///< Whether the postive CS feature is abled, device specific

+ 6 - 1
components/hal/include/hal/spi_types.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -23,6 +23,11 @@ typedef enum {
     SPI_HOST_MAX,   ///< invalid host value
 } spi_host_device_t;
 
+typedef enum {
+    SPI_CLK_APB,    ///< Select APB as the source clock
+    SPI_CLK_XTAL    ///< Select XTAL as the source clock
+} spi_clock_source_t;
+
 /// SPI Events
 typedef enum {
     /* Slave HD Only */

+ 8 - 14
components/hal/spi_hal.c

@@ -1,16 +1,8 @@
-// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// 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.
+/*
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 // The HAL layer for SPI (common part)
 
@@ -85,7 +77,9 @@ esp_err_t spi_hal_cal_clock_conf(const spi_hal_timing_param_t *timing_param, int
 {
     spi_hal_timing_conf_t temp_conf;
 
-    int eff_clk_n = spi_ll_master_cal_clock(SPI_LL_PERIPH_CLK_FREQ, timing_param->clock_speed_hz, timing_param->duty_cycle, &temp_conf.clock_reg);
+    int clk_src_freq_hz = timing_param->clk_src_hz;
+    assert((clk_src_freq_hz == 80 * 1000 * 1000) || (clk_src_freq_hz == 40 * 1000 * 1000));
+    int eff_clk_n = spi_ll_master_cal_clock(clk_src_freq_hz, timing_param->expected_freq, timing_param->duty_cycle, &temp_conf.clock_reg);
 
     //When the speed is too fast, we may need to use dummy cycles to compensate the reading.
     //But these don't work for full-duplex connections.

+ 6 - 14
components/hal/spi_hal_iram.c

@@ -1,16 +1,8 @@
-// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// 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.
+/*
+ * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 // The HAL layer for SPI (common part, in iram)
 // make these functions in a seperate file to make sure all LL functions are in the IRAM.
@@ -40,7 +32,7 @@ void spi_hal_setup_device(spi_hal_context_t *hal, const spi_hal_dev_config_t *de
 {
     //Configure clock settings
     spi_dev_t *hw = hal->hw;
-#if SOC_SPI_SUPPORT_AS_CS
+#if SOC_SPI_AS_CS_SUPPORTED
     spi_ll_master_set_cksel(hw, dev->cs_pin_id, dev->as_cs);
 #endif
     spi_ll_master_set_pos_cs(hw, dev->cs_pin_id, dev->positive_cs);

+ 7 - 13
components/idf_test/include/esp32/idf_performance_target.h

@@ -1,16 +1,8 @@
-// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// 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.
+/*
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #pragma once
 
@@ -30,6 +22,8 @@
 #define IDF_PERFORMANCE_MAX_RSA_4096KEY_PUBLIC_OP                               90000
 #define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP                              870000
 
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING                               15
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING                            30
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     27
 

+ 7 - 13
components/idf_test/include/esp32c3/idf_performance_target.h

@@ -1,16 +1,8 @@
-// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// 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.
+/*
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #pragma once
 
@@ -26,6 +18,8 @@
 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP                               45000
 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP                              670000
 
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING                               15
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING                            32
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     30
 

+ 7 - 13
components/idf_test/include/esp32h2/idf_performance_target.h

@@ -1,16 +1,8 @@
-// Copyright 2020 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// 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.
+/*
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
 
 #pragma once
 
@@ -26,6 +18,8 @@
 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP                               45000
 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP                              670000
 
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING                               15
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING                            32
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     30
 

+ 3 - 1
components/idf_test/include/esp32s2/idf_performance_target.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -23,6 +23,8 @@
 #define IDF_PERFORMANCE_MAX_RSA_4096KEY_PUBLIC_OP                               62000
 #define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP                              800000
 
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING                               15
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING                            32
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     30
 

+ 3 - 1
components/idf_test/include/esp32s3/idf_performance_target.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -21,6 +21,8 @@
 #define IDF_PERFORMANCE_MAX_RSA_4096KEY_PUBLIC_OP                               80000
 #define IDF_PERFORMANCE_MAX_RSA_4096KEY_PRIVATE_OP                              1500000
 
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING                               15
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING                            32
 #define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     30
 

+ 5 - 3
components/idf_test/include/esp8684/idf_performance_target.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -18,8 +18,10 @@
 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PUBLIC_OP                               45000
 #define IDF_PERFORMANCE_MAX_RSA_3072KEY_PRIVATE_OP                              670000
 
-#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING                            32
-#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     30
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING                               20
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING                            45
+#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA                     40
 
 /*
  * Flash Performance value

+ 0 - 7
components/idf_test/include/idf_performance.h

@@ -20,13 +20,6 @@
 #define IDF_PERFORMANCE_MAX_ESP_TIMER_GET_TIME_PER_CALL                         1000
 #endif
 
-#ifndef IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING
-#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING                               15
-#endif
-#ifndef IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA
-#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA                        15
-#endif
-
 /* Due to code size & linker layout differences interacting with cache, VFS
    microbenchmark currently runs slower with PSRAM enabled. */
 #ifndef IDF_PERFORMANCE_MAX_VFS_OPEN_WRITE_CLOSE_TIME

+ 8 - 4
components/soc/esp32/include/soc/Kconfig.soc_caps.in

@@ -407,6 +407,14 @@ config SOC_SIGMADELTA_CHANNEL_NUM
     int
     default 8
 
+config SOC_SPI_HD_BOTH_INOUT_SUPPORTED
+    bool
+    default y
+
+config SOC_SPI_AS_CS_SUPPORTED
+    bool
+    default y
+
 config SOC_SPI_PERIPH_NUM
     int
     default 3
@@ -423,10 +431,6 @@ config SOC_SPI_MAX_PRE_DIVIDER
     int
     default 8192
 
-config SOC_SPI_SUPPORT_AS_CS
-    bool
-    default y
-
 config SOC_TIMER_GROUPS
     int
     default 2

+ 9 - 7
components/soc/esp32/include/soc/soc_caps.h

@@ -1,6 +1,6 @@
 
 /*
- * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -237,15 +237,17 @@
 #define SOC_SIGMADELTA_CHANNEL_NUM (8) // 8 channels
 
 /*-------------------------- SPI CAPS ----------------------------------------*/
-#define SOC_SPI_PERIPH_NUM          3
-#define SOC_SPI_DMA_CHAN_NUM        2
+#define SOC_SPI_HD_BOTH_INOUT_SUPPORTED 1  //Support enabling MOSI and MISO phases together under Halfduplex mode
+#define SOC_SPI_AS_CS_SUPPORTED         1  //Support to toggle the CS while the clock toggles
+#define SOC_SPI_PERIPH_NUM              3
+#define SOC_SPI_DMA_CHAN_NUM            2
 
-#define SOC_SPI_PERIPH_CS_NUM(i)    3
+#define SOC_SPI_PERIPH_CS_NUM(i)        3
+
+#define SOC_SPI_MAXIMUM_BUFFER_SIZE     64
+#define SOC_SPI_MAX_PRE_DIVIDER         8192
 
-#define SOC_SPI_MAXIMUM_BUFFER_SIZE 64
-#define SOC_SPI_MAX_PRE_DIVIDER     8192
 
-#define SOC_SPI_SUPPORT_AS_CS       1 //Support to toggle the CS while the clock toggles
 
 // Peripheral supports DIO, DOUT, QIO, or QOUT
 #define SOC_SPI_PERIPH_SUPPORT_MULTILINE_MODE(spi_host)         ({(void)spi_host; 1;})

+ 4 - 0
components/soc/esp32s2/include/soc/Kconfig.soc_caps.in

@@ -451,6 +451,10 @@ config SOC_SIGMADELTA_CHANNEL_NUM
     int
     default 8
 
+config SOC_SPI_HD_BOTH_INOUT_SUPPORTED
+    bool
+    default y
+
 config SOC_SPI_PERIPH_NUM
     int
     default 3

+ 7 - 7
components/soc/esp32s2/include/soc/soc_caps.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2020-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -220,14 +220,14 @@
 #define SOC_SIGMADELTA_CHANNEL_NUM (8) // 8 channels
 
 /*-------------------------- SPI CAPS ----------------------------------------*/
-#define SOC_SPI_PERIPH_NUM      3
-#define SOC_SPI_DMA_CHAN_NUM    3
-#define SOC_SPI_PERIPH_CS_NUM(i)    (((i)==0)? 2: (((i)==1)? 6: 3))
+#define SOC_SPI_HD_BOTH_INOUT_SUPPORTED     1   //Support enabling MOSI and MISO phases together under Halfduplex mode
+#define SOC_SPI_PERIPH_NUM                  3
+#define SOC_SPI_DMA_CHAN_NUM                3
+#define SOC_SPI_PERIPH_CS_NUM(i)            (((i)==0)? 2: (((i)==1)? 6: 3))
 
-#define SOC_SPI_MAXIMUM_BUFFER_SIZE     72
-#define SOC_SPI_MAX_PRE_DIVIDER         8192
+#define SOC_SPI_MAXIMUM_BUFFER_SIZE         72
+#define SOC_SPI_MAX_PRE_DIVIDER             8192
 
-//#define SOC_SPI_SUPPORT_AS_CS         //don't support to toggle the CS while the clock toggles
 #define SOC_SPI_SUPPORT_DDRCLK              1
 #define SOC_SPI_SLAVE_SUPPORT_SEG_TRANS     1
 #define SOC_SPI_SUPPORT_CD_SIG              1

+ 0 - 4
components/soc/esp32s3/include/soc/Kconfig.soc_caps.in

@@ -539,10 +539,6 @@ config SOC_SPI_PERIPH_NUM
     int
     default 3
 
-config SOC_SPI_DMA_CHAN_NUM
-    int
-    default 3
-
 config SOC_SPI_MAXIMUM_BUFFER_SIZE
     int
     default 64

+ 1 - 2
components/soc/esp32s3/include/soc/soc_caps.h

@@ -1,5 +1,5 @@
 /*
- * SPDX-FileCopyrightText: 2019-2021 Espressif Systems (Shanghai) CO LTD
+ * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD
  *
  * SPDX-License-Identifier: Apache-2.0
  */
@@ -202,7 +202,6 @@
 
 /*-------------------------- SPI CAPS ----------------------------------------*/
 #define SOC_SPI_PERIPH_NUM                  3
-#define SOC_SPI_DMA_CHAN_NUM                3
 #define SOC_SPI_PERIPH_CS_NUM(i)            3
 #define SOC_SPI_MAXIMUM_BUFFER_SIZE         64
 #define SOC_SPI_SUPPORT_DDRCLK              1

+ 7 - 7
docs/en/api-reference/peripherals/spi_master.rst

@@ -7,7 +7,7 @@ SPI Master driver is a program that controls {IDF_TARGET_NAME}'s SPI peripherals
 Overview of {IDF_TARGET_NAME}'s SPI peripherals
 -----------------------------------------------
 
-{IDF_TARGET_MAX_PERIPH_NUM:default="4", esp32c3="3"}
+{IDF_TARGET_MAX_PERIPH_NUM:default="4", esp32c3="3", esp8684="3"}
 {IDF_TARGET_SPI2_CS_NUM:default="6", esp32="3"}
 {IDF_TARGET_SPI3_CS_NUM:default="3"}
 
@@ -32,7 +32,7 @@ Overview of {IDF_TARGET_NAME}'s SPI peripherals
 
     - SPI2 and SPI3 are general purpose SPI controllers. They are open to users. SPI2 and SPI3 have independent signal buses with the same respective names. SPI2 has {IDF_TARGET_SPI2_CS_NUM} CS lines. SPI3 has {IDF_TARGET_SPI3_CS_NUM} CS lines.  Each CS line can be used to drive one SPI slave.
 
-.. only:: esp32c3
+.. only:: esp32c3 or esp8684
 
     - SPI2 is a general purpose SPI controller. It has an independent signal bus with the same name. The bus has {IDF_TARGET_SPI2_CS_NUM} CS lines to drive up to {IDF_TARGET_SPI2_CS_NUM} SPI slaves.
 
@@ -230,7 +230,7 @@ If using more than one data lines to transmit, please set `SPI_DEVICE_HALFDUPLEX
 
         Half-duplex transactions with both read and write phases are not supported when using DMA. For details and workarounds, see :ref:`spi_known_issues`.
 
-.. only:: esp32s3 or esp32c3
+.. only:: esp32s3 or esp32c3 or esp8684
 
     .. note::
 
@@ -439,10 +439,10 @@ The main parameter that determines the transfer speed for large transactions is
 Transaction Duration
 ^^^^^^^^^^^^^^^^^^^^
 
-{IDF_TARGET_TRANS_TIME_INTR_DMA:default="28", esp32="28", esp32s2="23", esp32c3="28", esp32s3="26"}
-{IDF_TARGET_TRANS_TIME_POLL_DMA:default="10", esp32="10", esp32s2="9", esp32c3="10", esp32s3="11"}
-{IDF_TARGET_TRANS_TIME_INTR_CPU:default="25", esp32="25", esp32s2="22", esp32c3="27", esp32s3="24"}
-{IDF_TARGET_TRANS_TIME_POLL_CPU:default="8", esp32="8", esp32s2="8", esp32c3="9", esp32s3="9"}
+{IDF_TARGET_TRANS_TIME_INTR_DMA:default="28", esp32="28", esp32s2="23", esp32c3="28", esp32s3="26", esp8684="42"}
+{IDF_TARGET_TRANS_TIME_POLL_DMA:default="10", esp32="10", esp32s2="9", esp32c3="10", esp32s3="11", esp8684="17"}
+{IDF_TARGET_TRANS_TIME_INTR_CPU:default="25", esp32="25", esp32s2="22", esp32c3="27", esp32s3="24", esp8684="40"}
+{IDF_TARGET_TRANS_TIME_POLL_CPU:default="8", esp32="8", esp32s2="8", esp32c3="9", esp32s3="9", esp8684="15"}
 
 Transaction duration includes setting up SPI peripheral registers, copying data to FIFOs or setting up DMA links, and the time for SPI transaction.
 

+ 2 - 2
docs/en/api-reference/peripherals/spi_slave.rst

@@ -18,7 +18,7 @@ Overview of {IDF_TARGET_NAME}'s SPI peripherals
 
     SPI2 and SPI3 have independent signal buses with the same respective names.
 
-.. only:: esp32c3
+.. only:: esp32c3 or esp8684
 
     {IDF_TARGET_NAME} integrates one general purpose SPI controller which can be used as slave node driven by an off-chip SPI master. The controller is called SPI2 and has an independent signal bus with the same name.
 
@@ -158,7 +158,7 @@ You can also configure a GPIO pin through which the Device will signal to the Ho
 SCLK Frequency Requirements
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-{IDF_TARGET_MAX_FREQ:default="40", esp32="10", esp32s2="40", esp32c3="60", esp32s3="60}
+{IDF_TARGET_MAX_FREQ:default="60", esp32="10", esp32s2="40"}
 
 The SPI slaves are designed to operate at up to {IDF_TARGET_MAX_FREQ} MHz. The data cannot be recognized or received correctly if the clock is too fast or does not have a 50% duty cycle.
 

+ 2 - 1
examples/peripherals/spi_slave_hd/segment_mode/README.md

@@ -21,7 +21,8 @@ Following is the connection between 2 ESP32S2 boards:
 | SCLK      | GPIO12 | GPIO12 |
 | CS        | GPIO10 | GPIO10 |
 
-(Feel free to change the GPIO settings by editing the macro definations at the top of ``app_main.c`` files.)
+Plase refer to the macro definations at the top of ``app_main.c`` files, to know the connection on different chips.
+Feel free to change the GPIO settings by editing the macro definations.
 
 ### Build and Flash
 

+ 2 - 2
examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c

@@ -15,12 +15,12 @@
 #include "esp_serial_slave_link/essl_spi.h"
 
 //Pin setting
-#if !CONFIG_IDF_TARGET_ESP32C3
+#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
 #define GPIO_MOSI    11
 #define GPIO_MISO    13
 #define GPIO_SCLK    12
 #define GPIO_CS      10
-#else
+#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684
 #define GPIO_MOSI    7
 #define GPIO_MISO    2
 #define GPIO_SCLK    6

+ 2 - 2
examples/peripherals/spi_slave_hd/segment_mode/seg_slave/README.md

@@ -1,2 +1,2 @@
-| Supported Targets | ESP32-S2 |
-| ----------------- | -------- |
+| Supported Targets | ESP32-S2 | ESP32-S3 | ESP32-C3 | ESP8684 |
+| ----------------- | -------- | -------- | -------- | ------- |

+ 7 - 2
examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c

@@ -16,16 +16,21 @@
 #define TIME_IS_OUT(start, end, timeout)     (timeout) > ((end)-(start)) ? 0 : 1
 
 //Pin setting
-#ifdef CONFIG_IDF_TARGET_ESP32S2
+#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
 #define GPIO_MOSI 11
 #define GPIO_MISO 13
 #define GPIO_SCLK 12
 #define GPIO_CS   10
+#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP8684
+#define GPIO_MOSI    7
+#define GPIO_MISO    2
+#define GPIO_SCLK    6
+#define GPIO_CS      10
+#endif
 
 #define SLAVE_HOST SPI2_HOST
 #define DMA_CHAN   SPI_DMA_CH_AUTO
 #define QUEUE_SIZE 4
-#endif
 
 /**
  * Helper Macros for Master-Slave synchronization, each setting is 4-byte-width

+ 0 - 6
tools/ci/check_copyright_ignore.txt

@@ -1125,7 +1125,6 @@ components/hal/include/hal/soc_hal.h
 components/hal/include/hal/spi_flash_encrypt_hal.h
 components/hal/include/hal/spi_flash_hal.h
 components/hal/include/hal/spi_flash_types.h
-components/hal/include/hal/spi_hal.h
 components/hal/include/hal/spi_slave_hal.h
 components/hal/include/hal/spi_slave_hd_hal.h
 components/hal/include/hal/systimer_hal.h
@@ -1157,8 +1156,6 @@ components/hal/soc_hal.c
 components/hal/spi_flash_encrypt_hal_iram.c
 components/hal/spi_flash_hal.c
 components/hal/spi_flash_hal_gpspi.c
-components/hal/spi_hal.c
-components/hal/spi_hal_iram.c
 components/hal/spi_slave_hal.c
 components/hal/spi_slave_hal_iram.c
 components/hal/spi_slave_hd_hal.c
@@ -1195,9 +1192,6 @@ components/heap/test/test_realloc.c
 components/heap/test/test_runtime_heap_reg.c
 components/heap/test_multi_heap_host/main.cpp
 components/heap/test_multi_heap_host/test_multi_heap.cpp
-components/idf_test/include/esp32/idf_performance_target.h
-components/idf_test/include/esp32c3/idf_performance_target.h
-components/idf_test/include/esp32h2/idf_performance_target.h
 components/idf_test/include/idf_performance.h
 components/linux/include/sys/queue.h
 components/log/esp_log_private.h