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
This commit is contained in:
Armando (Dou Yiwen) 2022-03-30 19:59:31 +08:00
commit ee034d5b6a
15 changed files with 74 additions and 66 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -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;
}
/**

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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