spi: support H2 spi master, slave, slave_hd driver

This commit is contained in:
wanlei 2023-01-30 12:08:04 +08:00
parent 990c6f58a6
commit 5300bd3b2f
36 changed files with 448 additions and 323 deletions

View File

@ -28,16 +28,27 @@
#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
#if CONFIG_IDF_TARGET_ESP32C6 // cs_pin conflict with uart pin
#define PIN_NUM_MISO SPI2_IOMUX_PIN_NUM_MISO
#define PIN_NUM_MOSI SPI2_IOMUX_PIN_NUM_MOSI
#define PIN_NUM_CLK SPI2_IOMUX_PIN_NUM_CLK
#define PIN_NUM_CS 10 //the IOMUX pin of SPI2 CS0&CS1 is Pin_16&17 which conflict with UART Tx&Rx Pin
#define PIN_NUM_WP SPI2_IOMUX_PIN_NUM_WP
#define PIN_NUM_HD SPI2_IOMUX_PIN_NUM_HD
#else
#define PIN_NUM_MISO SPI2_IOMUX_PIN_NUM_MISO
#define PIN_NUM_MOSI SPI2_IOMUX_PIN_NUM_MOSI
#define PIN_NUM_CLK SPI2_IOMUX_PIN_NUM_CLK
#define PIN_NUM_CS SPI2_IOMUX_PIN_NUM_CS
#define PIN_NUM_WP SPI2_IOMUX_PIN_NUM_WP
#define PIN_NUM_HD SPI2_IOMUX_PIN_NUM_HD
#endif
#if (TEST_SPI_PERIPH_NUM >= 2) // esp32, s2, s3
#define TEST_SPI_HOST SPI2_HOST
#define TEST_SLAVE_HOST SPI3_HOST
#define MASTER_IOMUX_PIN_MISO SPI2_IOMUX_PIN_NUM_MISO
#define MASTER_IOMUX_PIN_MOSI SPI2_IOMUX_PIN_NUM_MOSI
@ -45,7 +56,13 @@
#define MASTER_IOMUX_PIN_CS SPI2_IOMUX_PIN_NUM_CS
#define MASTER_IOMUX_PIN_WP SPI2_IOMUX_PIN_NUM_WP
#define MASTER_IOMUX_PIN_HD SPI2_IOMUX_PIN_NUM_HD
#else
#define TEST_SPI_HOST SPI2_HOST
#define TEST_SLAVE_HOST SPI2_HOST
#endif
#if CONFIG_IDF_TARGET_ESP32 // spi3 have iomux pin only on esp32
#define SLAVE_IOMUX_PIN_MISO SPI3_IOMUX_PIN_NUM_MISO
#define SLAVE_IOMUX_PIN_MOSI SPI3_IOMUX_PIN_NUM_MOSI
#define SLAVE_IOMUX_PIN_SCLK SPI3_IOMUX_PIN_NUM_CLK
@ -60,29 +77,12 @@
#define WIRE_DELAY 12.5
#elif CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#define TEST_SPI_HOST SPI2_HOST
#define TEST_SLAVE_HOST SPI3_HOST
#define PIN_NUM_MISO SPI2_IOMUX_PIN_NUM_MISO
#define PIN_NUM_MOSI SPI2_IOMUX_PIN_NUM_MOSI
#define PIN_NUM_CLK SPI2_IOMUX_PIN_NUM_CLK
#define PIN_NUM_CS SPI2_IOMUX_PIN_NUM_CS
#define PIN_NUM_WP SPI2_IOMUX_PIN_NUM_WP
#define PIN_NUM_HD SPI2_IOMUX_PIN_NUM_HD
#define MASTER_IOMUX_PIN_MISO SPI2_IOMUX_PIN_NUM_MISO
#define MASTER_IOMUX_PIN_MOSI SPI2_IOMUX_PIN_NUM_MOSI
#define MASTER_IOMUX_PIN_SCLK SPI2_IOMUX_PIN_NUM_CLK
#define MASTER_IOMUX_PIN_CS SPI2_IOMUX_PIN_NUM_CS
#define MASTER_IOMUX_PIN_WP SPI2_IOMUX_PIN_NUM_WP
#define MASTER_IOMUX_PIN_HD SPI2_IOMUX_PIN_NUM_HD
#define SLAVE_IOMUX_PIN_MISO -1
#define SLAVE_IOMUX_PIN_MOSI -1
#define SLAVE_IOMUX_PIN_SCLK -1
#define SLAVE_IOMUX_PIN_CS -1
#define SLAVE_IOMUX_PIN_NUM_WP -1
#define SLAVE_IOMUX_PIN_NUM_HD -1
#define SLAVE_IOMUX_PIN_WP -1
#define SLAVE_IOMUX_PIN_HD -1
#define UNCONNECTED_PIN 41
#define INPUT_ONLY_PIN 46
@ -90,43 +90,12 @@
#define ESP_SPI_SLAVE_TV 0
#define WIRE_DELAY 12.5
#elif CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32C2 || CONFIG_IDF_TARGET_ESP32H4
//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
#define PIN_NUM_MISO SPI2_IOMUX_PIN_NUM_MISO
#define PIN_NUM_MOSI SPI2_IOMUX_PIN_NUM_MOSI
#define PIN_NUM_CLK SPI2_IOMUX_PIN_NUM_CLK
#define PIN_NUM_CS SPI2_IOMUX_PIN_NUM_CS
#define PIN_NUM_WP SPI2_IOMUX_PIN_NUM_WP
#define PIN_NUM_HD SPI2_IOMUX_PIN_NUM_HD
#define SLAVE_IOMUX_PIN_MISO SPI2_IOMUX_PIN_NUM_MISO
#define SLAVE_IOMUX_PIN_MOSI SPI2_IOMUX_PIN_NUM_MOSI
#define SLAVE_IOMUX_PIN_SCLK SPI2_IOMUX_PIN_NUM_CLK
#define SLAVE_IOMUX_PIN_CS SPI2_IOMUX_PIN_NUM_CS
#define MASTER_IOMUX_PIN_MISO SPI2_IOMUX_PIN_NUM_MISO
#define MASTER_IOMUX_PIN_MOSI SPI2_IOMUX_PIN_NUM_MOSI
#define MASTER_IOMUX_PIN_SCLK SPI2_IOMUX_PIN_NUM_CLK
#define MASTER_IOMUX_PIN_CS SPI2_IOMUX_PIN_NUM_CS
#else
#define GPIO_DELAY 0
#define ESP_SPI_SLAVE_TV 0
#define WIRE_DELAY 12.5
#endif //CONFIG_IDF_TARGET_ESP32
#elif CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2
#define TEST_SPI_HOST SPI2_HOST
#define TEST_SLAVE_HOST SPI2_HOST
#define PIN_NUM_MISO SPI2_IOMUX_PIN_NUM_MISO
#define PIN_NUM_MOSI SPI2_IOMUX_PIN_NUM_MOSI
#define PIN_NUM_CLK SPI2_IOMUX_PIN_NUM_CLK
#define PIN_NUM_CS 10 //the IOMUX pin of SPI2 CS0&CS1 is Pin_16&17 which is same from UART Tx&Rx Pin
#define PIN_NUM_WP SPI2_IOMUX_PIN_NUM_WP
#define PIN_NUM_HD SPI2_IOMUX_PIN_NUM_HD
#endif
#define GET_DMA_CHAN(HOST) (HOST)

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |

View File

@ -78,12 +78,18 @@ static void check_spi_pre_n_for(spi_clock_source_t clock_source, int clk, int pr
struct test_clk_param_group_t
{
uint32_t clk_param_80m[TEST_CLK_TIMES][3];
uint32_t clk_param_48m[TEST_CLK_TIMES][3];
uint32_t clk_param_40m[TEST_CLK_TIMES][3];
uint32_t clk_param_32m[TEST_CLK_TIMES][3];
uint32_t clk_param_17m[TEST_CLK_TIMES][3];
uint32_t clk_param_7m[TEST_CLK_TIMES][3];
} test_clk_param = {
{{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} },
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 8, 60}, {333333, 3, 48}, {800000, 1, 60}, {5000000, 1, 10}, {12000000, 1, 4}, {18000000, 1, 3}, {26000000, 1, 2} },
{{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} },
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 5, 64}, {333333, 2, 48}, {800000, 1, 40}, {2000000, 1, 16}, {8000000, 1, 4}, {15000000, 1, 2}, {20000000, 1, 2} },
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 5, 35}, {333333, 1, 53}, {800000, 1, 22}, {900000, 1, 19}, {8000000, 1, 2}, {10000000, 1, 2}, {15000000, 1, 1} },
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 2, 35}, {333333, 1, 21}, {800000, 1, 9}, {900000, 1, 8}, {1100000, 1, 6}, {4000000, 1, 2,}, {7000000, 1, 1} },
};
@ -102,6 +108,15 @@ TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
}
#endif
#if SOC_SPI_SUPPORT_CLK_PLL_F48M
clk_tree_src_get_freq_hz(SPI_CLK_SRC_PLL_F48M, CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source PLL_48M = %ld\n", clock_source_hz);
TEST_ASSERT((48 * 1000 * 1000) == clock_source_hz);
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_PLL_F48M, test_clk_param.clk_param_48m[i][0], test_clk_param.clk_param_48m[i][1], test_clk_param.clk_param_48m[i][2]);
}
#endif
#if SOC_SPI_SUPPORT_CLK_PLL_F40M
clk_tree_src_get_freq_hz(SPI_CLK_SRC_PLL_F40M, CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source PLL_40M = %ld\n", clock_source_hz);
@ -124,20 +139,33 @@ TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
#if SOC_SPI_SUPPORT_CLK_XTAL
clk_tree_src_get_freq_hz(SPI_CLK_SRC_XTAL, CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source XTAL = %ld\n", clock_source_hz);
TEST_ASSERT((40 * 1000 * 1000) == clock_source_hz);
if((40 * 1000 * 1000) == clock_source_hz){
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_XTAL, test_clk_param.clk_param_40m[i][0], test_clk_param.clk_param_40m[i][1], test_clk_param.clk_param_40m[i][2]);
}
}
if((32 * 1000 * 1000) == clock_source_hz){
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_XTAL, test_clk_param.clk_param_32m[i][0], test_clk_param.clk_param_32m[i][1], test_clk_param.clk_param_32m[i][2]);
}
}
#endif
// Test RC fast osc clock source
#if SOC_SPI_SUPPORT_CLK_RC_FAST
clk_tree_src_get_freq_hz(SPI_CLK_SRC_RC_FAST, CLK_TREE_SRC_FREQ_PRECISION_APPROX, &clock_source_hz);
printf("\nTest clock source RC_FAST = %ld\n", clock_source_hz);
TEST_ASSERT((17500000) == clock_source_hz);
if((17500000) == clock_source_hz){
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_RC_FAST, test_clk_param.clk_param_17m[i][0], test_clk_param.clk_param_17m[i][1], test_clk_param.clk_param_17m[i][2]);
}
}
if((7000000) == clock_source_hz){
for (int i = 0; i < TEST_CLK_TIMES; i++) {
check_spi_pre_n_for(SPI_CLK_SRC_RC_FAST, test_clk_param.clk_param_7m[i][0], test_clk_param.clk_param_7m[i][1], test_clk_param.clk_param_7m[i][2]);
}
}
#endif
TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST));
@ -1458,6 +1486,8 @@ TEST_CASE("spi_speed", "[spi]")
//add dummy devices first
#if CONFIG_IDF_TARGET_ESP32
#define DUMMY_CS_PINS() {25, 26, 27}
#elif CONFIG_IDF_TARGET_ESP32H2
#define DUMMY_CS_PINS() {9, 10, 11, 12, 22, 25}
#else
#define DUMMY_CS_PINS() {0, 1, 4, 5, 8, 9}
#endif //CONFIG_IDF_TARGET_ESP32

View File

@ -6,6 +6,7 @@ import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic
@pytest.mark.parametrize('config', ['defaults', 'release', 'freertos_compliance', 'freertos_flash',], indirect=True)
def test_master_single_dev(case_tester) -> None: # type: ignore
@ -28,6 +29,7 @@ def test_master_esp_flash(case_tester) -> None: # type: ignore
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic_multi_device
@pytest.mark.parametrize('count, config', [(2, 'defaults',), (2, 'release',), (2, 'freertos_compliance',), (2, 'freertos_flash',)], indirect=True)
def test_master_multi_dev(case_tester) -> None: # type: ignore

View File

@ -6,6 +6,7 @@ import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic
def test_param_single_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
@ -16,6 +17,7 @@ def test_param_single_dev(case_tester) -> None: # type: ignore
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic_multi_device
@pytest.mark.parametrize('count', [2,], indirect=True)
def test_param_multi_dev(case_tester) -> None: # type: ignore

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |

View File

@ -6,6 +6,7 @@ import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic
@pytest.mark.parametrize('config', ['defaults',], indirect=True)
def test_slave_single_dev(case_tester) -> None: # type: ignore
@ -17,6 +18,7 @@ def test_slave_single_dev(case_tester) -> None: # type: ignore
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic_multi_device
@pytest.mark.parametrize('count, config', [(2, 'defaults'), (2, 'iram_safe')], indirect=True)
def test_slave_multi_dev(case_tester) -> None: # type: ignore

View File

@ -6,6 +6,7 @@ import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic
def test_slave_hd_single_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
@ -16,6 +17,7 @@ def test_slave_hd_single_dev(case_tester) -> None: # type: ignore
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.supported_targets
@pytest.mark.esp32h2
@pytest.mark.generic_multi_device
@pytest.mark.parametrize('count', [2,], indirect=True)
def test_slave_hd_multi_dev(case_tester) -> None: # type: ignore

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |

View File

@ -16,3 +16,5 @@ components/esp_lcd/test_apps/rgb_lcd:
components/esp_lcd/test_apps/spi_lcd:
disable:
- if: SOC_GPSPI_SUPPORTED != 1
- if: IDF_TARGET == "esp32h2"
reason: Not tested yet.

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -24,6 +24,7 @@
#include "hal/assert.h"
#include "hal/misc.h"
#include "hal/spi_types.h"
#include "soc/pcr_struct.h"
#ifdef __cplusplus
extern "C" {
@ -74,9 +75,47 @@ typedef enum {
} spi_ll_trans_len_cond_t;
FLAG_ATTR(spi_ll_trans_len_cond_t)
// SPI base command
typedef enum {
/* Slave HD Only */
SPI_LL_BASE_CMD_HD_WRBUF = 0x01,
SPI_LL_BASE_CMD_HD_RDBUF = 0x02,
SPI_LL_BASE_CMD_HD_WRDMA = 0x03,
SPI_LL_BASE_CMD_HD_RDDMA = 0x04,
SPI_LL_BASE_CMD_HD_SEG_END = 0x05,
SPI_LL_BASE_CMD_HD_EN_QPI = 0x06,
SPI_LL_BASE_CMD_HD_WR_END = 0x07,
SPI_LL_BASE_CMD_HD_INT0 = 0x08,
SPI_LL_BASE_CMD_HD_INT1 = 0x09,
SPI_LL_BASE_CMD_HD_INT2 = 0x0A,
} spi_ll_base_command_t;
/*------------------------------------------------------------------------------
* Control
*----------------------------------------------------------------------------*/
/**
* Select SPI peripheral clock source (master).
*
* @param hw Beginning address of the peripheral registers.
* @param clk_source clock source to select, see valid sources in type `spi_clock_source_t`
*/
static inline void spi_ll_set_clk_source(spi_dev_t *hw, spi_clock_source_t clk_source)
{
switch (clk_source)
{
case SPI_CLK_SRC_RC_FAST:
PCR.spi2_clkm_conf.spi2_clkm_sel = 2;
break;
case SPI_CLK_SRC_XTAL:
PCR.spi2_clkm_conf.spi2_clkm_sel = 0;
break;
default:
PCR.spi2_clkm_conf.spi2_clkm_sel = 1;
break;
}
}
/**
* Initialize SPI peripheral (master).
*
@ -96,14 +135,13 @@ static inline void spi_ll_master_init(spi_dev_t *hw)
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;
PCR.spi2_clkm_conf.spi2_clkm_en = 1;
PCR.spi2_clkm_conf.spi2_clkm_sel = 0;
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;
hw->dma_conf.slv_tx_seg_trans_clr_en = 1;
hw->dma_conf.slv_rx_seg_trans_clr_en = 1;
hw->dma_conf.dma_slv_seg_trans_en = 0;
}
/**
@ -128,7 +166,7 @@ static inline void spi_ll_slave_init(spi_dev_t *hw)
// 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;
hw->dma_conf.dma_slv_seg_trans_en = 0;
//Disable unneeded ints
hw->dma_int_ena.val &= ~SPI_LL_UNUSED_INT_MASK;
@ -161,7 +199,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)
{
return hw->dma_int_raw.trans_done;
return hw->dma_int_raw.trans_done_int_raw;
}
/**
@ -265,7 +303,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)
{
hw->dma_int_clr.infifo_full_err = 1;
hw->dma_int_clr.dma_infifo_full_err_int_clr = 1;
}
/**
@ -275,7 +313,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)
{
hw->dma_int_clr.outfifo_empty_err = 1;
hw->dma_int_clr.dma_outfifo_empty_err_int_clr = 1;
}
/*------------------------------------------------------------------------------
@ -330,7 +368,7 @@ static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_s
//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;
hw->data_buf[(x / 32)].buf0 = word;
}
}
@ -358,10 +396,10 @@ static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t
//read-modify-write
if (copy_len != 4) {
word = hw->data_buf[byte_id / 4]; //read
word = hw->data_buf[byte_id / 4].buf0; //read
}
memcpy(((uint8_t *)&word) + offset, data, copy_len); //modify
hw->data_buf[byte_id / 4] = word; //write
hw->data_buf[byte_id / 4].buf0 = word; //write
data += copy_len;
byte_id += copy_len;
@ -380,7 +418,7 @@ static inline void spi_ll_read_buffer(spi_dev_t *hw, uint8_t *buffer_to_rcv, siz
{
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];
uint32_t word = hw->data_buf[x / 32].buf0;
int len = bitlen - x;
if (len > 32) {
len = 32;
@ -400,7 +438,7 @@ 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)
{
while (len > 0) {
uint32_t word = hw->data_buf[byte_id / 4];
uint32_t word = hw->data_buf[byte_id / 4].buf0;
int offset = byte_id % 4;
int copy_len = 4 - offset;
if (copy_len > len) {
@ -563,7 +601,7 @@ 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.dma_slv_seg_trans_en = seg_trans;
}
/**
@ -874,11 +912,11 @@ static inline void spi_ll_set_address(spi_dev_t *hw, uint64_t addr, int addrlen,
*/
addr = HAL_SWAP32(addr);
//otherwise only addr register is sent
hw->addr = addr;
hw->addr.val = 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);
hw->addr.val = addr << (32 - addrlen);
}
}
@ -952,7 +990,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)
{
return hw->slave1.data_bitlen;
return hw->slave1.slv_data_bitlen;
}
/*------------------------------------------------------------------------------
@ -961,16 +999,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_int_ena, dma_int_raw.trans_done_int_raw, dma_int_clr.trans_done_int_clr, dma_int_set.trans_done_int_set) \
item(SPI_LL_INTR_RDBUF, dma_int_ena.slv_rd_buf_done_int_ena, dma_int_raw.slv_rd_buf_done_int_raw, dma_int_clr.slv_rd_buf_done_int_clr, dma_int_set.slv_rd_buf_done_int_set) \
item(SPI_LL_INTR_WRBUF, dma_int_ena.slv_wr_buf_done_int_ena, dma_int_raw.slv_wr_buf_done_int_raw, dma_int_clr.slv_wr_buf_done_int_clr, dma_int_set.slv_wr_buf_done_int_set) \
item(SPI_LL_INTR_RDDMA, dma_int_ena.slv_rd_dma_done_int_ena, dma_int_raw.slv_rd_dma_done_int_raw, dma_int_clr.slv_rd_dma_done_int_clr, dma_int_set.slv_rd_dma_done_int_set) \
item(SPI_LL_INTR_WRDMA, dma_int_ena.slv_wr_dma_done_int_ena, dma_int_raw.slv_wr_dma_done_int_raw, dma_int_clr.slv_wr_dma_done_int_clr, dma_int_set.slv_wr_dma_done_int_set) \
item(SPI_LL_INTR_SEG_DONE, dma_int_ena.dma_seg_trans_done_int_ena, dma_int_raw.dma_seg_trans_done_int_raw, dma_int_clr.dma_seg_trans_done_int_clr, dma_int_set.dma_seg_trans_done_int_set) \
item(SPI_LL_INTR_CMD7, dma_int_ena.slv_cmd7_int_ena, dma_int_raw.slv_cmd7_int_raw, dma_int_clr.slv_cmd7_int_clr, dma_int_set.slv_cmd7_int_set) \
item(SPI_LL_INTR_CMD8, dma_int_ena.slv_cmd8_int_ena, dma_int_raw.slv_cmd8_int_raw, dma_int_clr.slv_cmd8_int_clr, dma_int_set.slv_cmd8_int_set) \
item(SPI_LL_INTR_CMD9, dma_int_ena.slv_cmd9_int_ena, dma_int_raw.slv_cmd9_int_raw, dma_int_clr.slv_cmd9_int_clr, dma_int_set.slv_cmd9_int_set) \
item(SPI_LL_INTR_CMDA, dma_int_ena.slv_cmda_int_ena, dma_int_raw.slv_cmda_int_raw, dma_int_clr.slv_cmda_int_clr, dma_int_set.slv_cmda_int_set)
static inline void spi_ll_enable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask)
@ -989,14 +1027,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
}
@ -1019,7 +1057,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)
{
hw->dma_int_ena.trans_done = 0;
hw->dma_int_ena.trans_done_int_ena = 0;
}
/**
@ -1029,7 +1067,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_int_clr = 1;
}
/**
@ -1039,7 +1077,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;
}
/**
@ -1049,7 +1087,7 @@ static inline void spi_ll_set_int_stat(spi_dev_t *hw)
*/
static inline void spi_ll_enable_int(spi_dev_t *hw)
{
hw->dma_int_ena.trans_done = 1;
hw->dma_int_ena.trans_done_int_ena = 1;
}
/*------------------------------------------------------------------------------
@ -1057,25 +1095,112 @@ 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)
{
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;
hw->slave.slv_rdbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDBUF) ? 1 : 0;
hw->slave.slv_wrbuf_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_WRBUF) ? 1 : 0;
hw->slave.slv_rddma_bitlen_en = (cond_mask & SPI_LL_TRANS_LEN_COND_RDDMA) ? 1 : 0;
hw->slave.slv_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)
{
return hw->slave1.data_bitlen / 8;
return hw->slave1.slv_data_bitlen / 8;
}
static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw)
{
return hw->slave1.last_addr;
return hw->slave1.slv_last_addr;
}
#undef SPI_LL_RST_MASK
#undef SPI_LL_UNUSED_INT_MASK
/**
* Get the base spi command
*
* @param cmd_t Command value
*/
static inline uint8_t spi_ll_get_slave_hd_base_command(spi_command_t cmd_t)
{
uint8_t cmd_base = 0x00;
switch (cmd_t)
{
case SPI_CMD_HD_WRBUF:
cmd_base = SPI_LL_BASE_CMD_HD_WRBUF;
break;
case SPI_CMD_HD_RDBUF:
cmd_base = SPI_LL_BASE_CMD_HD_RDBUF;
break;
case SPI_CMD_HD_WRDMA:
cmd_base = SPI_LL_BASE_CMD_HD_WRDMA;
break;
case SPI_CMD_HD_RDDMA:
cmd_base = SPI_LL_BASE_CMD_HD_RDDMA;
break;
case SPI_CMD_HD_SEG_END:
cmd_base = SPI_LL_BASE_CMD_HD_SEG_END;
break;
case SPI_CMD_HD_EN_QPI:
cmd_base = SPI_LL_BASE_CMD_HD_EN_QPI;
break;
case SPI_CMD_HD_WR_END:
cmd_base = SPI_LL_BASE_CMD_HD_WR_END;
break;
case SPI_CMD_HD_INT0:
cmd_base = SPI_LL_BASE_CMD_HD_INT0;
break;
case SPI_CMD_HD_INT1:
cmd_base = SPI_LL_BASE_CMD_HD_INT1;
break;
case SPI_CMD_HD_INT2:
cmd_base = SPI_LL_BASE_CMD_HD_INT2;
break;
default:
HAL_ASSERT(cmd_base);
}
return cmd_base;
}
/**
* Get the spi communication command
*
* @param cmd_t Base command value
* @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
static inline uint16_t spi_ll_get_slave_hd_command(spi_command_t cmd_t, spi_line_mode_t line_mode)
{
uint8_t cmd_base = spi_ll_get_slave_hd_base_command(cmd_t);
uint8_t cmd_mod = 0x00; //CMD:1-bit, ADDR:1-bit, DATA:1-bit
if (line_mode.data_lines == 2) {
if (line_mode.addr_lines == 2) {
cmd_mod = 0x50; //CMD:1-bit, ADDR:2-bit, DATA:2-bit
} else {
cmd_mod = 0x10; //CMD:1-bit, ADDR:1-bit, DATA:2-bit
}
} else if (line_mode.data_lines == 4) {
if (line_mode.addr_lines == 4) {
cmd_mod = 0xA0; //CMD:1-bit, ADDR:4-bit, DATA:4-bit
} else {
cmd_mod = 0x20; //CMD:1-bit, ADDR:1-bit, DATA:4-bit
}
}
if (cmd_base == SPI_LL_BASE_CMD_HD_SEG_END || cmd_base == SPI_LL_BASE_CMD_HD_EN_QPI) {
cmd_mod = 0x00;
}
return cmd_base | cmd_mod;
}
/**
* Get the dummy bits
*
* @param line_mode Line mode of SPI transaction phases: CMD, ADDR, DOUT/DIN.
*/
static inline int spi_ll_get_slave_hd_dummy_bits(spi_line_mode_t line_mode)
{
return 8;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -18,10 +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_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
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 28
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 24
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 58
#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 54
// floating point instructions per divide and per sqrt (configured for worst-case with PSRAM workaround)
#define IDF_PERFORMANCE_MAX_CYCLES_PER_DIV 70

View File

@ -67,6 +67,10 @@ config SOC_RMT_SUPPORTED
bool
default y
config SOC_GPSPI_SUPPORTED
bool
default y
config SOC_LEDC_SUPPORTED
bool
default y
@ -639,10 +643,22 @@ config SOC_SPI_SUPPORT_CONTINUOUS_TRANS
bool
default y
config SOC_SPI_SUPPORT_SLAVE_HD_VER2
bool
default y
config SOC_SPI_SUPPORT_CLK_XTAL
bool
default y
config SOC_SPI_SUPPORT_CLK_PLL_F48M
bool
default y
config SOC_SPI_SUPPORT_CLK_RC_FAST
bool
default y
config SOC_MEMSPI_IS_INDEPENDENT
bool
default y

View File

@ -325,7 +325,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of SPI
*/
#define SOC_SPI_CLKS {SOC_MOD_CLK_PLL_F48M, SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST}
#define SOC_SPI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_PLL_F48M}
/**
* @brief Type of SPI clock source.
@ -333,11 +333,11 @@ typedef enum {
typedef enum {
SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_48M as SPI source clock */
SPI_CLK_SRC_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_48M as SPI source clock */
SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as SPI source clock */
SPI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */
SPI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as SPI source clock */
} soc_periph_spi_clk_src_t;
//////////////////////////////////////////////////SDM//////////////////////////////////////////////////////////////
//////////////////////////////////////////////////SDM///////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of SDM

View File

@ -1128,7 +1128,7 @@ typedef union {
struct {
uint32_t reserved_0:20;
/** spi2_clkm_sel : R/W; bitpos: [21:20]; default: 0;
* set this field to select clock-source. 0(default): XTAL, 1: 80MHz, 2: FOSC, 3:
* set this field to select clock-source. 0(default): XTAL, 1: 48MHz, 2: FOSC, 3:
* reserved.
*/
uint32_t spi2_clkm_sel:2;

View File

@ -49,7 +49,7 @@
#define SOC_SDM_SUPPORTED 1
#define SOC_ETM_SUPPORTED 1
#define SOC_RMT_SUPPORTED 1
// #define SOC_GPSPI_SUPPORTED 1 // TODO: IDF-6264
#define SOC_GPSPI_SUPPORTED 1
#define SOC_LEDC_SUPPORTED 1
#define SOC_I2C_SUPPORTED 1
#define SOC_SYSTIMER_SUPPORTED 1
@ -319,8 +319,10 @@
#define SOC_SPI_SLAVE_SUPPORT_SEG_TRANS 1
#define SOC_SPI_SUPPORT_CD_SIG 1
#define SOC_SPI_SUPPORT_CONTINUOUS_TRANS 1
//#define SOC_SPI_SUPPORT_SLAVE_HD_VER2 1 //TODO: IDF-6247
#define SOC_SPI_SUPPORT_SLAVE_HD_VER2 1
#define SOC_SPI_SUPPORT_CLK_XTAL 1
#define SOC_SPI_SUPPORT_CLK_PLL_F48M 1
#define SOC_SPI_SUPPORT_CLK_RC_FAST 1
// Peripheral supports DIO, DOUT, QIO, or QOUT
// host_id = 0 -> SPI0/SPI1, host_id = 1 -> SPI2,

View File

@ -8,19 +8,19 @@
#define _SOC_SPI_PINS_H_
#define SPI_FUNC_NUM 0
#define SPI_IOMUX_PIN_NUM_HD 12
#define SPI_IOMUX_PIN_NUM_CS 14
#define SPI_IOMUX_PIN_NUM_MOSI 16
#define SPI_IOMUX_PIN_NUM_CLK 15
#define SPI_IOMUX_PIN_NUM_MISO 17
#define SPI_IOMUX_PIN_NUM_WP 13
#define SPI_IOMUX_PIN_NUM_HD 18
#define SPI_IOMUX_PIN_NUM_CS 15
#define SPI_IOMUX_PIN_NUM_MOSI 20
#define SPI_IOMUX_PIN_NUM_CLK 19
#define SPI_IOMUX_PIN_NUM_MISO 16
#define SPI_IOMUX_PIN_NUM_WP 17
#define SPI2_FUNC_NUM 2
#define SPI2_IOMUX_PIN_NUM_MISO 2
#define SPI2_IOMUX_PIN_NUM_HD 4
#define SPI2_IOMUX_PIN_NUM_WP 5
#define SPI2_IOMUX_PIN_NUM_CLK 6
#define SPI2_IOMUX_PIN_NUM_MOSI 7
#define SPI2_IOMUX_PIN_NUM_CS 10
#define SPI2_IOMUX_PIN_NUM_MISO 0
#define SPI2_IOMUX_PIN_NUM_HD 3
#define SPI2_IOMUX_PIN_NUM_WP 2
#define SPI2_IOMUX_PIN_NUM_CLK 4
#define SPI2_IOMUX_PIN_NUM_MOSI 5
#define SPI2_IOMUX_PIN_NUM_CS 1
#endif

View File

@ -36,7 +36,7 @@ const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = {
.spiq_in = FSPIQ_IN_IDX,
.spiwp_in = FSPIWP_IN_IDX,
.spihd_in = FSPIHD_IN_IDX,
.spics_out = {FSPICS0_OUT_IDX},
.spics_out = {FSPICS0_OUT_IDX, FSPICS1_OUT_IDX, FSPICS2_OUT_IDX, FSPICS3_OUT_IDX, FSPICS4_OUT_IDX, FSPICS5_OUT_IDX},
.spics_in = FSPICS0_IN_IDX,
.spiclk_iomux_pin = SPI2_IOMUX_PIN_NUM_CLK,
.spid_iomux_pin = SPI2_IOMUX_PIN_NUM_MOSI,
@ -44,7 +44,7 @@ const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = {
.spiwp_iomux_pin = SPI2_IOMUX_PIN_NUM_WP,
.spihd_iomux_pin = SPI2_IOMUX_PIN_NUM_HD,
.spics0_iomux_pin = SPI2_IOMUX_PIN_NUM_CS,
.irq = ETS_MSPI_INTR_SOURCE,
.irq = ETS_GSPI2_INTR_SOURCE,
.irq_dma = -1,
.module = PERIPH_SPI2_MODULE,
.hw = &GPSPI2,

View File

@ -76,7 +76,6 @@ api-reference/peripherals/hmac
api-reference/peripherals/usb_device
api-reference/peripherals/sdspi_host
api-reference/peripherals/dac
api-reference/peripherals/spi_slave
api-reference/peripherals/i2s
api-reference/peripherals/touch_element
api-reference/peripherals/lcd
@ -93,12 +92,10 @@ api-reference/peripherals/spi_flash/index
api-reference/peripherals/spi_flash/auto_suspend.inc
api-reference/peripherals/touch_pad
api-reference/peripherals/adc_calibration
api-reference/peripherals/spi_slave_hd
api-reference/peripherals/ds
api-reference/peripherals/i2c
api-reference/peripherals/dedic_gpio
api-reference/peripherals/sd_pullup_requirements
api-reference/peripherals/spi_master
api-reference/peripherals/index
api-reference/peripherals/sdmmc_host
api-reference/kconfig

View File

@ -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", esp32c2="3", esp32c6="3"}
{IDF_TARGET_MAX_PERIPH_NUM:default="4", esp32c3="3", esp32c2="3", esp32c6="3", esp32h2="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 or esp32c2 or esp32c6
.. only:: esp32c3 or esp32c2 or esp32c6 or esp32h2
- 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 or esp32c2 or esp32c6
.. only:: esp32s3 or esp32c3 or esp32c2 or esp32c6 or esp32h2
.. note::
@ -408,7 +408,7 @@ GPIO Matrix and IO_MUX
+ +------+------+
| | GPIO Number |
+==========+======+======+
| CS0* | 15 | 5 |
| CS0 [1]_ | 15 | 5 |
+----------+------+------+
| SCLK | 14 | 18 |
+----------+------+------+
@ -421,79 +421,41 @@ GPIO Matrix and IO_MUX
| QUADHD | 4 | 21 |
+----------+------+------+
* Only the first Device attached to the bus can use the CS0 pin.
.. only:: not esp32
{IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1"}
{IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4"}
{IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5"}
{IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0"}
{IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3"}
{IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2"}
Most of chip's peripheral signals have direct connection to their dedicated IO_MUX pins. However, the signals can also be routed to any other available pins using the less direct GPIO matrix. If at least one signal is routed through the GPIO matrix, then all signals will be routed through it.
When an SPI Host is set to 80MHz or lower frequencies, routing SPI pins via GPIO matrix will behave the same comparing to routing them via IOMUX.
The IO_MUX pins for SPI buses are given below.
.. only:: esp32s2 or esp32s3
.. list-table::
:widths: 40 30
:header-rows: 1
+----------+------+------+
| Pin Name | SPI2 | SPI3 |
+ +------+------+
| | GPIO Number |
+==========+======+======+
| CS0* | 10 | N/A |
+----------+------+------+
| SCLK | 12 | N/A |
+----------+------+------+
| MISO | 13 | N/A |
+----------+------+------+
| MOSI | 11 | N/A |
+----------+------+------+
| QUADWP | 14 | N/A |
+----------+------+------+
| QUADHD | 9 | N/A |
+----------+------+------+
* - Pin Name
- GPIO Number (SPI2)
* - CS0 [1]_
- {IDF_TARGET_SPI2_IOMUX_PIN_CS}
* - SCLK
- {IDF_TARGET_SPI2_IOMUX_PIN_CLK}
* - MISO
- {IDF_TARGET_SPI2_IOMUX_PIN_MISO}
* - MOSI
- {IDF_TARGET_SPI2_IOMUX_PIN_MOSI}
* - QUADWP
- {IDF_TARGET_SPI2_IOMUX_PIN_WP}
* - QUADHD
- {IDF_TARGET_SPI2_IOMUX_PIN_HD}
.. only:: esp32c2 or esp32c3
+----------+-------------+
| Pin Name | SPI2 |
+ +-------------+
| | GPIO Number |
+==========+=============+
| CS0* | 10 |
+----------+-------------+
| SCLK | 6 |
+----------+-------------+
| MOSI | 7 |
+----------+-------------+
| MISO | 2 |
+----------+-------------+
| QUADHD | 4 |
+----------+-------------+
| QUADWP | 5 |
+----------+-------------+
.. only:: esp32c6
+----------+-------------+
| Pin Name | SPI2 |
+ +-------------+
| | GPIO Number |
+==========+=============+
| CS0* | 16 |
+----------+-------------+
| SCLK | 6 |
+----------+-------------+
| MOSI | 7 |
+----------+-------------+
| MISO | 2 |
+----------+-------------+
| QUADHD | 4 |
+----------+-------------+
| QUADWP | 5 |
+----------+-------------+
.. only:: not esp32
* Only the first Device attached to the bus can use the CS0 pin.
.. [1] Only the first Device attached to the bus can use the CS0 pin.
.. _speed_considerations:
@ -512,10 +474,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", esp32c2="42", esp32c6="34"}
{IDF_TARGET_TRANS_TIME_POLL_DMA:default="10", esp32="10", esp32s2="9", esp32c3="10", esp32s3="11", esp32c2="17", esp32c6="17"}
{IDF_TARGET_TRANS_TIME_INTR_CPU:default="25", esp32="25", esp32s2="22", esp32c3="27", esp32s3="24", esp32c2="40", esp32c6="32"}
{IDF_TARGET_TRANS_TIME_POLL_CPU:default="8", esp32="8", esp32s2="8", esp32c3="9", esp32s3="9", esp32c2="15", esp32c6="15"}
{IDF_TARGET_TRANS_TIME_INTR_DMA:default="N/A", esp32="28", esp32s2="23", esp32c3="28", esp32s3="26", esp32c2="42", esp32c6="34", esp32h2="58"}
{IDF_TARGET_TRANS_TIME_POLL_DMA:default="N/A", esp32="10", esp32s2="9", esp32c3="10", esp32s3="11", esp32c2="17", esp32c6="17", esp32h2="28"}
{IDF_TARGET_TRANS_TIME_INTR_CPU:default="N/A", esp32="25", esp32s2="22", esp32c3="27", esp32s3="24", esp32c2="40", esp32c6="32", esp32h2="54"}
{IDF_TARGET_TRANS_TIME_POLL_CPU:default="N/A", esp32="8", esp32s2="8", esp32c3="9", esp32s3="9", esp32c2="15", esp32c6="15", esp32h2="24"}
Transaction duration includes setting up SPI peripheral registers, copying data to FIFOs or setting up DMA links, and the time for SPI transaction.

View File

@ -121,104 +121,57 @@ GPIO Matrix and IO_MUX
The IO_MUX pins for SPI buses are given below.
.. list-table::
:widths: 40 30 30
:header-rows: 1
* - Pin Name
- GPIO Number (SPI2)
- GPIO Number (SPI3)
* - CS0*
- 15
- 5
* - SCLK
- 14
- 18
* - MISO
- 12
- 19
* - MOSI
- 13
- 23
* - QUADWP
- 2
- 22
* - QUADHD
- 4
- 21
+----------+------+------+
| Pin Name | SPI2 | SPI3 |
+ +------+------+
| | GPIO Number |
+==========+======+======+
| CS0 | 15 | 5 |
+----------+------+------+
| SCLK | 14 | 18 |
+----------+------+------+
| MISO | 12 | 19 |
+----------+------+------+
| MOSI | 13 | 23 |
+----------+------+------+
| QUADWP | 2 | 22 |
+----------+------+------+
| QUADHD | 4 | 21 |
+----------+------+------+
.. only:: not esp32
{IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1"}
{IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4"}
{IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5"}
{IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0"}
{IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3"}
{IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2"}
Most of chip's peripheral signals have direct connection to their dedicated IO_MUX pins. However, the signals can also be routed to any other available pins using the less direct GPIO matrix. If at least one signal is routed through the GPIO matrix, then all signals will be routed through it.
When an SPI Host is set to 80 MHz or lower frequencies, routing SPI pins via GPIO matrix will behave the same compared to routing them via IO_MUX.
The IO_MUX pins for SPI buses are given below.
.. only:: esp32s2 or esp32s3
.. list-table::
:widths: 40 30
:header-rows: 1
* - Pin Name
- GPIO Number (SPI2)
* - CS0*
- 10
* - CS0
- {IDF_TARGET_SPI2_IOMUX_PIN_CS}
* - SCLK
- 12
- {IDF_TARGET_SPI2_IOMUX_PIN_CLK}
* - MISO
- 13
- {IDF_TARGET_SPI2_IOMUX_PIN_MISO}
* - MOSI
- 11
- {IDF_TARGET_SPI2_IOMUX_PIN_MOSI}
* - QUADWP
- 14
- {IDF_TARGET_SPI2_IOMUX_PIN_WP}
* - QUADHD
- 9
.. only:: esp32c2 or esp32c3
.. list-table::
:widths: 40 30
:header-rows: 1
* - Pin Name
- GPIO Number (SPI2)
* - CS0*
- 10
* - SCLK
- 6
* - MISO
- 2
* - MOSI
- 7
* - QUADWP
- 5
* - QUADHD
- 4
.. only:: esp32c6
.. list-table::
:widths: 40 30
:header-rows: 1
* - Pin Name
- GPIO Number (SPI2)
* - CS0*
- 16
* - SCLK
- 6
* - MISO
- 2
* - MOSI
- 7
* - QUADWP
- 5
* - QUADHD
- 4
* Only the first Device attached to the bus can use the CS0 pin.
- {IDF_TARGET_SPI2_IOMUX_PIN_HD}
Speed and Timing Considerations
@ -239,7 +192,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="60", esp32="10", esp32s2="40"}
{IDF_TARGET_MAX_FREQ:default="60", esp32="10", esp32s2="40", esp32c6="40", esp32h2="32"}
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.

View File

@ -80,10 +80,14 @@ examples/peripherals/lcd/rgb_panel:
examples/peripherals/lcd/spi_lcd_touch:
disable:
- if: SOC_GPSPI_SUPPORTED != 1
- if: IDF_TARGET == "esp32h2"
reason: Not tested yet.
examples/peripherals/lcd/tjpgd:
disable:
- if: SOC_GPSPI_SUPPORTED != 1
- if: IDF_TARGET == "esp32h2"
reason: Not tested yet.
examples/peripherals/ledc:
disable:
@ -176,7 +180,7 @@ examples/peripherals/spi_slave/sender:
examples/peripherals/spi_slave_hd/append_mode/master:
disable:
- if: IDF_TARGET == "esp32c6" or IDF_TARGET == "esp32h2"
- if: IDF_TARGET == "esp32c6"
temporary: true
reason: target(s) not supported yet
@ -192,7 +196,7 @@ examples/peripherals/spi_slave_hd/segment_mode/seg_master:
examples/peripherals/spi_slave_hd/segment_mode/seg_slave:
disable:
- if: IDF_TARGET == "esp32" or IDF_TARGET == "esp32h2"
- if: IDF_TARGET == "esp32"
temporary: true
reason: not supported

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- |
| Supported Targets | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- |
# I2S TDM Example -- ES7210 4-Ch ADC Codec

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
## SPI master half duplex EEPROM example
@ -11,16 +11,16 @@
For different chip and host used, the connections may be different.
| | ESP32 | ESP32 | ESP32S2 | ESP32C2 | ESP32C3 | ESP32C6 | ESP32S3 |
| ---- | ----- | ----- | ------- | ------- | ------- | ------- | ------- |
| Host | SPI1 | HSPI | SPI2 | SPI2 | SPI2 | SPI2 | SPI2 |
| VCC | 3.3V | 3.3V | 3.3V | 3.3V | 3.3V | 3.3V | 3.3V |
| GND | GND | GND | GND | GND | GND | GND | GND |
| DO | 7 | 18 | 37 | 2 | 2 | 2 | 13 |
| DI | 8 | 23 | 35 | 7 | 7 | 7 | 11 |
| SK | 6 | 19 | 36 | 6 | 6 | 6 | 12 |
| CS | 13 | 13 | 34 | 10 | 10 | 10 | 10 |
| ORG | GND | GND | GND | GND | GND | GND | GND |
| | ESP32 | ESP32 | ESP32S2 | ESP32C2 | ESP32C3 | ESP32C6 | ESP32S3 | ESP32H2 |
| ---- | ----- | ----- | ------- | ------- | ------- | ------- | ------- | ------- |
| Host | SPI1 | HSPI | SPI2 | SPI2 | SPI2 | SPI2 | SPI2 | SPI2 |
| VCC | 3.3V | 3.3V | 3.3V | 3.3V | 3.3V | 3.3V | 3.3V | 3.3V |
| GND | GND | GND | GND | GND | GND | GND | GND | GND |
| DO | 7 | 18 | 37 | 2 | 2 | 2 | 13 | 0 |
| DI | 8 | 23 | 35 | 7 | 7 | 7 | 11 | 5 |
| SK | 6 | 19 | 36 | 6 | 6 | 6 | 12 | 4 |
| CS | 13 | 13 | 34 | 10 | 10 | 10 | 10 | 1 |
| ORG | GND | GND | GND | GND | GND | GND | GND | GND |
### Notes

View File

@ -60,6 +60,14 @@
# define PIN_NUM_MOSI 11
# define PIN_NUM_CLK 12
# define PIN_NUM_CS 10
#elif CONFIG_IDF_TARGET_ESP32H2
# define EEPROM_HOST SPI2_HOST
# define PIN_NUM_MISO 0
# define PIN_NUM_MOSI 5
# define PIN_NUM_CLK 4
# define PIN_NUM_CS 1
#endif

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
# SPI Host Driver Example

View File

@ -62,6 +62,18 @@
#define PIN_NUM_DC 9
#define PIN_NUM_RST 4
#define PIN_NUM_BCKL 5
#elif defined CONFIG_IDF_TARGET_ESP32H2
#define LCD_HOST SPI2_HOST
#define PIN_NUM_MISO 0
#define PIN_NUM_MOSI 5
#define PIN_NUM_CLK 4
#define PIN_NUM_CS 1
#define PIN_NUM_DC 10
#define PIN_NUM_RST 11
#define PIN_NUM_BCKL 12
#endif
//To speed up transfers, every SPI transfer sends a bunch of lines. This define specifies how many. More means more memory use,

View File

@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
## SPI slave example
@ -7,13 +7,13 @@ These two projects illustrate the SPI Slave driver. They're supposed to be flash
The default GPIOs used in the example are the following:
| Signal | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-C6 |
|-----------|--------|----------|----------|----------|
| Handshake | GPIO2 | GPIO2 | GPIO3 | GPIO15 |
| MOSI | GPIO12 | GPIO12 | GPIO7 | GPIO20 |
| MISO | GPIO13 | GPIO13 | GPIO2 | GPIO19 |
| SCLK | GPIO15 | GPIO15 | GPIO6 | GPIO18 |
| CS | GPIO14 | GPIO14 | GPIO10 | GPIO9 |
| Signal | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-C6 | ESP32-H2 |
|-----------|--------|----------|----------|----------|----------|
| Handshake | GPIO2 | GPIO2 | GPIO3 | GPIO15 | GPIO2 |
| MOSI | GPIO12 | GPIO12 | GPIO7 | GPIO20 | GPIO5 |
| MISO | GPIO13 | GPIO13 | GPIO2 | GPIO19 | GPIO0 |
| SCLK | GPIO15 | GPIO15 | GPIO6 | GPIO18 | GPIO4 |
| CS | GPIO14 | GPIO14 | GPIO10 | GPIO9 | GPIO1 |
Please run wires between the following GPIOs between the slave and master to make the example function:

View File

@ -55,6 +55,13 @@ Pins in use. The SPI Master can use the GPIO mux, so feel free to change these i
#define GPIO_SCLK 18
#define GPIO_CS 9
#elif CONFIG_IDF_TARGET_ESP32H2
#define GPIO_HANDSHAKE 2
#define GPIO_MOSI 5
#define GPIO_MISO 0
#define GPIO_SCLK 4
#define GPIO_CS 1
#elif CONFIG_IDF_TARGET_ESP32S3
#define GPIO_HANDSHAKE 2
#define GPIO_MOSI 11

View File

@ -56,6 +56,13 @@ Pins in use. The SPI Master can use the GPIO mux, so feel free to change these i
#define GPIO_SCLK 18
#define GPIO_CS 9
#elif CONFIG_IDF_TARGET_ESP32H2
#define GPIO_HANDSHAKE 2
#define GPIO_MOSI 5
#define GPIO_MISO 0
#define GPIO_SCLK 4
#define GPIO_CS 1
#elif CONFIG_IDF_TARGET_ESP32S3
#define GPIO_HANDSHAKE 2
#define GPIO_MOSI 11

View File

@ -1,4 +1,4 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
See README.md in the parent directory

View File

@ -15,11 +15,20 @@
#include "esp_serial_slave_link/essl.h"
#include "esp_serial_slave_link/essl_spi.h"
#ifdef CONFIG_IDF_TARGET_ESP32H2
#define GPIO_MOSI 5
#define GPIO_MISO 0
#define GPIO_SCLK 4
#define GPIO_CS 1
#else
#define GPIO_MOSI 11
#define GPIO_MISO 13
#define GPIO_SCLK 12
#define GPIO_CS 10
#define HOST_ID 1
#endif
#define HOST_ID SPI2_HOST
#define TRANSACTION_LEN 16
//The SPI transaction cycles in this example. You may change the cycle. e.g., use the ``sender`` and change it to a infinite loop
#define EXAMPLE_CYCLES 10

View File

@ -1,4 +1,4 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
See README.md in the parent directory

View File

@ -32,6 +32,13 @@
#define GPIO_MISO 20
#define GPIO_SCLK 18
#define GPIO_CS 9
#elif CONFIG_IDF_TARGET_ESP32H2
#define GPIO_HANDSHAKE 2
#define GPIO_MOSI 5
#define GPIO_MISO 0
#define GPIO_SCLK 4
#define GPIO_CS 1
#endif
#define MASTER_HOST SPI2_HOST

View File

@ -1,2 +1,2 @@
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | -------- | -------- | -------- | -------- | -------- | -------- |

View File

@ -33,6 +33,13 @@
#define GPIO_MISO 20
#define GPIO_SCLK 18
#define GPIO_CS 9
#elif CONFIG_IDF_TARGET_ESP32H2
#define GPIO_HANDSHAKE 2
#define GPIO_MOSI 5
#define GPIO_MISO 0
#define GPIO_SCLK 4
#define GPIO_CS 1
#endif
#define SLAVE_HOST SPI2_HOST