mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
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:
commit
ee034d5b6a
@ -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()
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
|
@ -89,7 +89,6 @@
|
||||
#define SOC_MPI_SUPPORTED 1
|
||||
#define SOC_SHA_SUPPORTED 1
|
||||
|
||||
|
||||
/*-------------------------- ADC CAPS ----------------------------------------*/
|
||||
/**
|
||||
* TO BE REMOVED
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user