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

Merge branch 'feature/support_spi_on_h2' into 'master'

spi: support spi on h2

Closes IDF-3796 and IDF-4226

See merge request espressif/esp-idf!17191
Armando (Dou Yiwen) 3 лет назад
Родитель
Сommit
ee034d5b6a

+ 5 - 12
components/driver/CMakeLists.txt

@@ -72,6 +72,10 @@ if(CONFIG_SOC_TWAI_SUPPORTED)
     list(APPEND srcs "twai.c")
 endif()
 
+if(CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2)
+    list(APPEND srcs "spi_slave_hd.c")
+endif()
+
 if(${target} STREQUAL "esp32")
     list(APPEND srcs "dac_common.c"
                      "sdio_slave.c"
@@ -84,7 +88,6 @@ endif()
 
 if(IDF_TARGET STREQUAL "esp32s2")
     list(APPEND srcs "dac_common.c"
-                     "spi_slave_hd.c"
                      "touch_sensor_common.c"
                      "esp32s2/touch_sensor.c"
                      "esp32s2/adc.c"
@@ -95,25 +98,15 @@ endif()
 
 if(${target} STREQUAL "esp32s3")
     list(APPEND srcs "usb_serial_jtag.c"
-                     "spi_slave_hd.c"
                      "touch_sensor_common.c"
                      "esp32s3/touch_sensor.c")
 endif()
 
 if(IDF_TARGET STREQUAL "esp32c3")
-    list(APPEND srcs "spi_slave_hd.c"
-                     "usb_serial_jtag.c"
+    list(APPEND srcs "usb_serial_jtag.c"
                      "esp32c3/adc2_init_cal.c")
 endif()
 
-if(IDF_TARGET STREQUAL "esp32h2")
-    list(APPEND srcs "spi_slave_hd.c")
-endif()
-
-if(IDF_TARGET STREQUAL "esp32c2")
-    list(APPEND srcs "spi_slave_hd.c")
-endif()
-
 if(BOOTLOADER_BUILD)
     # Bootloader shall NOT depend on the drivers
     idf_component_register()

+ 1 - 1
components/driver/spi_master.c

@@ -321,7 +321,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
     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);
     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));
+    assert((apb_clk_freq_hz == 80 * 1000 * 1000) || (apb_clk_freq_hz == 40 * 1000 * 1000) || (apb_clk_freq_hz == 48 * 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

+ 1 - 1
components/driver/test/include/test/test_common_spi.h

@@ -86,7 +86,7 @@
 #define ESP_SPI_SLAVE_TV        0
 #define WIRE_DELAY              12.5
 
-#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
+#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H2
 //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

+ 3 - 2
components/driver/test/test_common_spi.c

@@ -8,6 +8,7 @@
 #include "esp_log.h"
 #include "driver/gpio.h"
 #include "hal/gpio_hal.h"
+#include "esp_rom_gpio.h"
 
 
 int test_freq_default[]=TEST_FREQ_DEFAULT();
@@ -210,13 +211,13 @@ void master_free_device_bus(spi_device_handle_t spi)
 void spitest_gpio_output_sel(uint32_t gpio_num, int func, uint32_t signal_idx)
 {
     gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], func);
-    GPIO.func_out_sel_cfg[gpio_num].func_sel = signal_idx;
+    esp_rom_gpio_connect_out_signal(gpio_num, signal_idx, 0, 0);
 }
 
 void spitest_gpio_input_sel(uint32_t gpio_num, int func, uint32_t signal_idx)
 {
     gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[gpio_num], func);
-    GPIO.func_in_sel_cfg[signal_idx].func_sel = gpio_num;
+    esp_rom_gpio_connect_in_signal(gpio_num, signal_idx, 0);
 }
 
 //Note this cs_num is the ID of the connected devices' ID, e.g. if 2 devices are connected to the bus,

+ 1 - 1
components/driver/test/test_spi_master.c

@@ -1053,7 +1053,7 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]")
     spi_device_handle_t spi;
     spi_device_interface_config_t dev_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
     dev_cfg.flags = SPI_DEVICE_HALFDUPLEX;
-    dev_cfg.clock_speed_hz = 4 * 1000 * 1000;
+    dev_cfg.clock_speed_hz = 1 * 1000 * 1000;
     TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi));
 
     spi_slave_interface_config_t slave_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();

+ 30 - 0
components/esp_serial_slave_link/include/essl_spi/esp32h2_defs.h

@@ -0,0 +1,30 @@
+/*
+ * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+
+#pragma once
+
+// NOTE: From the view of master
+#define CMD_HD_WRBUF_REG    0x01
+#define CMD_HD_RDBUF_REG    0x02
+#define CMD_HD_WRDMA_REG    0x03
+#define CMD_HD_RDDMA_REG    0x04
+
+#define CMD_HD_ONEBIT_MODE  0x00
+#define CMD_HD_DOUT_MODE    0x10
+#define CMD_HD_QOUT_MODE    0x20
+#define CMD_HD_DIO_MODE     0x50
+#define CMD_HD_QIO_MODE     0xA0
+
+#define CMD_HD_SEG_END_REG  0x05
+#define CMD_HD_EN_QPI_REG   0x06
+#define CMD_HD_WR_END_REG   0x07
+#define CMD_HD_INT0_REG     0x08
+#define CMD_HD_INT1_REG     0x09
+#define CMD_HD_INT2_REG     0x0A
+#define CMD_HD_EX_QPI_REG   0xDD
+
+#define SPI_SLAVE_HD_BUFFER_SIZE 64

+ 14 - 15
components/hal/esp32h2/include/hal/spi_ll.h

@@ -562,7 +562,6 @@ static inline void spi_ll_master_set_line_mode(spi_dev_t *hw, spi_line_mode_t li
 static inline void spi_ll_slave_set_seg_mode(spi_dev_t *hw, bool seg_trans)
 {
     hw->dma_conf.dma_seg_trans_en = seg_trans;
-    hw->dma_conf.rx_eof_en = seg_trans;
 }
 
 /**
@@ -960,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)
@@ -988,14 +987,14 @@ 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
 }
@@ -1028,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)
 {
-    hw->dma_int_raw.trans_done = 0;
+    hw->dma_int_clr.trans_done = 1;
 }
 
 /**
@@ -1038,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)
 {
-    hw->dma_int_raw.trans_done = 1;
+    hw->dma_int_set.trans_done_int_set = 1;
 }
 
 /**

+ 1 - 1
components/hal/spi_hal.c

@@ -79,7 +79,7 @@ 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 clk_src_freq_hz = timing_param->clk_src_hz;
-    HAL_ASSERT((clk_src_freq_hz == 80 * 1000 * 1000) || (clk_src_freq_hz == 40 * 1000 * 1000));
+    HAL_ASSERT((clk_src_freq_hz == 80 * 1000 * 1000) || (clk_src_freq_hz == 40 * 1000 * 1000) || (clk_src_freq_hz == 48 * 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.

+ 0 - 1
components/soc/esp32/include/soc/soc_caps.h

@@ -89,7 +89,6 @@
 #define SOC_MPI_SUPPORTED           1
 #define SOC_SHA_SUPPORTED           1
 
-
 /*-------------------------- ADC CAPS ----------------------------------------*/
 /**
  * TO BE REMOVED

+ 0 - 3
docs/docs_not_updated/esp32c2.txt

@@ -86,16 +86,13 @@ api-reference/storage/mass_mfg
 api-reference/storage/index
 api-reference/peripherals/adc
 api-reference/peripherals/sdspi_host
-api-reference/peripherals/spi_slave
 api-reference/peripherals/lcd
 api-reference/peripherals/secure_element
 api-reference/peripherals/ledc
 api-reference/peripherals/temp_sensor
-api-reference/peripherals/spi_features
 api-reference/peripherals/spi_slave_hd
 api-reference/peripherals/i2c
 api-reference/peripherals/dedic_gpio
-api-reference/peripherals/spi_master
 api-reference/peripherals/index
 api-reference/kconfig
 api-reference/network/esp_openthread

+ 1 - 1
docs/en/api-reference/peripherals/spi_features.rst

@@ -28,7 +28,7 @@ do transactions on the bus should wait until the BG to be successfully disabled.
       There are quite a few limitations when using SPI Master driver on the SPI1 bus, see
       :ref:`spi_master_on_spi1_bus`.
 
-  .. only:: esp32s2
+  .. only:: not esp32
 
       The SPI Master driver hasn't supported SPI1 bus. Only SPI Flash driver can attach to the bus.
 

+ 1 - 1
examples/peripherals/spi_slave/receiver/main/app_main.c

@@ -41,7 +41,7 @@ Pins in use. The SPI Master can use the GPIO mux, so feel free to change these i
 #define GPIO_SCLK 15
 #define GPIO_CS 14
 
-#elif CONFIG_IDF_TARGET_ESP32C3
+#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H2
 #define GPIO_HANDSHAKE 3
 #define GPIO_MOSI 7
 #define GPIO_MISO 2

+ 14 - 25
examples/peripherals/spi_slave/sender/main/app_main.c

@@ -10,29 +10,14 @@
 #include <stdint.h>
 #include <stddef.h>
 #include <string.h>
-
+#include "esp_log.h"
 #include "freertos/FreeRTOS.h"
 #include "freertos/task.h"
 #include "freertos/semphr.h"
 #include "freertos/queue.h"
-
-#include "lwip/sockets.h"
-#include "lwip/dns.h"
-#include "lwip/netdb.h"
-#include "lwip/igmp.h"
-
-#include "esp_wifi.h"
-#include "esp_system.h"
-#include "esp_event.h"
-#include "nvs_flash.h"
-#include "soc/rtc_periph.h"
 #include "driver/spi_master.h"
-#include "esp_log.h"
-#include "esp_spi_flash.h"
-
 #include "driver/gpio.h"
-#include "esp_intr_alloc.h"
-
+#include "esp_timer.h"
 
 /*
 SPI sender (master) example.
@@ -57,7 +42,7 @@ Pins in use. The SPI Master can use the GPIO mux, so feel free to change these i
 #define GPIO_SCLK 15
 #define GPIO_CS 14
 
-#elif CONFIG_IDF_TARGET_ESP32C3
+#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H2
 #define GPIO_HANDSHAKE 3
 #define GPIO_MOSI 7
 #define GPIO_MISO 2
@@ -93,16 +78,20 @@ static void IRAM_ATTR gpio_handshake_isr_handler(void* arg)
 {
     //Sometimes due to interference or ringing or something, we get two irqs after eachother. This is solved by
     //looking at the time between interrupts and refusing any interrupt too close to another one.
-    static uint32_t lasthandshaketime;
-    uint32_t currtime=esp_cpu_get_ccount();
-    uint32_t diff=currtime-lasthandshaketime;
-    if (diff<240000) return; //ignore everything <1ms after an earlier irq
-    lasthandshaketime=currtime;
+    static uint32_t lasthandshaketime_us;
+    uint32_t currtime_us = esp_timer_get_time();
+    uint32_t diff = currtime_us - lasthandshaketime_us;
+    if (diff < 1000) {
+        return; //ignore everything <1ms after an earlier irq
+    }
+    lasthandshaketime_us = currtime_us;
 
     //Give the semaphore.
-    BaseType_t mustYield=false;
+    BaseType_t mustYield = false;
     xSemaphoreGiveFromISR(rdySem, &mustYield);
-    if (mustYield) portYIELD_FROM_ISR();
+    if (mustYield) {
+        portYIELD_FROM_ISR();
+    }
 }
 
 //Main application

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

@@ -20,7 +20,7 @@
 #define GPIO_MISO    13
 #define GPIO_SCLK    12
 #define GPIO_CS      10
-#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
+#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H2
 #define GPIO_MOSI    7
 #define GPIO_MISO    2
 #define GPIO_SCLK    6

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

@@ -21,7 +21,7 @@
 #define GPIO_MISO 13
 #define GPIO_SCLK 12
 #define GPIO_CS   10
-#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2
+#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H2
 #define GPIO_MOSI    7
 #define GPIO_MISO    2
 #define GPIO_SCLK    6