From 51873d46aafd318aec931d783a5c01fea8b7e232 Mon Sep 17 00:00:00 2001 From: wanckl Date: Tue, 18 Mar 2025 17:14:18 +0800 Subject: [PATCH] feat(driver_spi): add h21 spi drivers supports --- .../test_apps/sdspi/README.md | 4 +- .../esp_driver_spi/src/gpspi/spi_master.c | 13 +- .../spi_bench_mark/include/spi_performance.h | 132 +- .../esp_driver_spi/test_apps/master/README.md | 4 +- .../test_apps/master/main/test_spi_master.c | 21 +- .../master/main/test_spi_master_sct.c | 2 + .../esp_driver_spi/test_apps/param/README.md | 4 +- .../test_apps/param/main/test_spi_param.c | 12 +- .../esp_driver_spi/test_apps/slave/README.md | 4 +- .../test_apps/slave/main/test_spi_slave.c | 2 + .../test_apps/slave_hd/README.md | 4 +- .../slave_hd/main/test_spi_slave_hd.c | 4 +- .../main/CMakeLists.txt | 5 +- .../main/test_intr_alloc.c | 32 +- .../esp_lcd/test_apps/spi_lcd/README.md | 4 +- .../port/arch/riscv/esp_ipc_isr_port.c | 4 +- .../port/arch/xtensa/esp_ipc_isr_port.c | 4 +- components/hal/esp32h21/include/hal/spi_ll.h | 1591 +++++++++++++++++ .../soc/esp32/include/soc/system_intr.h | 4 + .../soc/esp32c2/include/soc/system_intr.h | 5 + .../soc/esp32c3/include/soc/system_intr.h | 5 + .../soc/esp32c5/include/soc/system_intr.h | 5 + .../soc/esp32c6/include/soc/system_intr.h | 5 + .../soc/esp32c61/include/soc/system_intr.h | 5 + .../soc/esp32h2/include/soc/system_intr.h | 5 + .../esp32h21/include/soc/Kconfig.soc_caps.in | 12 +- .../soc/esp32h21/include/soc/clk_tree_defs.h | 10 +- components/soc/esp32h21/include/soc/soc.h | 1 - .../soc/esp32h21/include/soc/soc_caps.h | 15 +- .../soc/esp32h21/include/soc/spi_pins.h | 4 +- .../soc/esp32h21/include/soc/system_intr.h | 5 + .../soc/esp32h21/register/soc/pcr_struct.h | 2 +- .../soc/esp32h21/register/soc/spi_reg.h | 81 +- components/soc/esp32h21/spi_periph.c | 85 + .../soc/esp32h4/include/soc/system_intr.h | 4 + .../soc/esp32p4/include/soc/system_intr.h | 4 + .../soc/esp32s2/include/soc/system_intr.h | 5 + .../soc/esp32s3/include/soc/system_intr.h | 4 + docs/docs_not_updated/esp32h21.txt | 4 - .../api-reference/peripherals/spi_master.rst | 28 +- .../api-reference/peripherals/spi_slave.rst | 12 +- .../protocols/esp_spi_slave_protocol.rst | 40 +- .../api-reference/peripherals/spi_master.rst | 28 +- .../api-reference/peripherals/spi_slave.rst | 12 +- .../protocols/esp_serial_slave_link.rst | 2 +- .../protocols/esp_spi_slave_protocol.rst | 40 +- examples/get-started/blink/README.md | 4 +- .../peripherals/lcd/spi_lcd_touch/README.md | 4 +- examples/peripherals/lcd/tjpgd/README.md | 4 +- .../spi_master/hd_eeprom/README.md | 4 +- examples/peripherals/spi_master/lcd/README.md | 4 +- examples/peripherals/spi_slave/README.md | 4 +- .../spi_slave_hd/append_mode/master/README.md | 4 +- .../spi_slave_hd/append_mode/slave/README.md | 4 +- .../segment_mode/seg_master/README.md | 4 +- .../segment_mode/seg_slave/README.md | 4 +- examples/storage/sd_card/sdspi/README.md | 4 +- 57 files changed, 2056 insertions(+), 266 deletions(-) create mode 100644 components/hal/esp32h21/include/hal/spi_ll.h create mode 100644 components/soc/esp32h21/spi_periph.c diff --git a/components/esp_driver_sdspi/test_apps/sdspi/README.md b/components/esp_driver_sdspi/test_apps/sdspi/README.md index 7b96141437..15bfc62bf3 100644 --- a/components/esp_driver_sdspi/test_apps/sdspi/README.md +++ b/components/esp_driver_sdspi/test_apps/sdspi/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index 2a91524beb..cb3e30ef09 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -115,8 +115,8 @@ We have two bits to control the interrupt: #include "esp_private/periph_ctrl.h" #include "esp_private/spi_common_internal.h" #include "esp_private/spi_master_internal.h" +#include "esp_private/esp_clk_tree_common.h" #include "driver/spi_master.h" -#include "esp_clk_tree.h" #include "clk_ctrl_os.h" #include "esp_log.h" #include "esp_check.h" @@ -415,12 +415,10 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa SPI_CHECK(periph_rtc_dig_clk8m_enable(), "the selected clock not available", ESP_ERR_INVALID_STATE); } #endif - spi_clock_source_t clk_src = SPI_CLK_SRC_DEFAULT; + spi_clock_source_t clk_src = dev_config->clock_source ? dev_config->clock_source : SPI_CLK_SRC_DEFAULT; uint32_t clock_source_hz = 0; uint32_t clock_source_div = 1; - if (dev_config->clock_source) { - clk_src = dev_config->clock_source; - } + esp_clk_tree_enable_src(clk_src, true); esp_clk_tree_src_get_freq_hz(clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clock_source_hz); #if SPI_LL_SUPPORT_CLK_SRC_PRE_DIV SPI_CHECK((dev_config->clock_speed_hz > 0) && (dev_config->clock_speed_hz <= MIN(clock_source_hz / 2, (80 * 1000000))), "invalid sclk speed", ESP_ERR_INVALID_ARG); @@ -584,7 +582,7 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle) } #if SOC_SPI_SUPPORT_CLK_RC_FAST - if (handle->cfg.clock_source == SPI_CLK_SRC_RC_FAST) { + if (handle->hal_dev.timing_conf.clock_source == SPI_CLK_SRC_RC_FAST) { // If no transactions from other device, acquire the bus to switch module clock to `SPI_CLK_SRC_DEFAULT` // because `SPI_CLK_SRC_RC_FAST` will be disabled then, which block following transactions if (handle->host->cur_cs == DEV_NUM_MAX) { @@ -597,6 +595,7 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle) periph_rtc_dig_clk8m_disable(); } #endif + esp_clk_tree_enable_src(handle->hal_dev.timing_conf.clock_source, false); //return int spics_io_num = handle->cfg.spics_io_num; diff --git a/components/esp_driver_spi/test_apps/components/spi_bench_mark/include/spi_performance.h b/components/esp_driver_spi/test_apps/components/spi_bench_mark/include/spi_performance.h index bd734ba8c1..3c018cf74a 100644 --- a/components/esp_driver_spi/test_apps/components/spi_bench_mark/include/spi_performance.h +++ b/components/esp_driver_spi/test_apps/components/spi_bench_mark/include/spi_performance.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,87 +7,103 @@ #pragma once #if CONFIG_IDF_TARGET_ESP32 -#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 16*1000*1000 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 15 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 15 +#define IDF_TARGET_MAX_SPI_CLK_FREQ 16*1000*1000 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 15 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 15 #if !CONFIG_FREERTOS_SMP // IDF-5223 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 34 // TODO: IDF-5180 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 30 // TODO: IDF-5180 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 34 // TODO: IDF-5180 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 30 // TODO: IDF-5180 #else -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 50 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 50 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 50 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 50 #endif #elif CONFIG_IDF_TARGET_ESP32S2 -#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 40*1000*1000 -#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_TARGET_MAX_SPI_CLK_FREQ 40*1000*1000 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 15 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 15 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 32 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 30 #elif CONFIG_IDF_TARGET_ESP32S3 -#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 40*1000*1000 -#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_TARGET_MAX_SPI_CLK_FREQ 40*1000*1000 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 15 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 15 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 32 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 30 #elif CONFIG_IDF_TARGET_ESP32C2 -#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 40*1000*1000 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 23 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 18 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 47 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 42 +#define IDF_TARGET_MAX_SPI_CLK_FREQ 40*1000*1000 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 23 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 18 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 47 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 42 #elif CONFIG_IDF_TARGET_ESP32C3 -#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 40*1000*1000 +#define IDF_TARGET_MAX_SPI_CLK_FREQ 40*1000*1000 #if !CONFIG_FREERTOS_SMP // IDF-5223 -#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 33 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 30 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 15 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 15 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 33 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 30 #else -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 17 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 17 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 60 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 60 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 17 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 17 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 60 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 60 #endif #elif CONFIG_IDF_TARGET_ESP32C6 -#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 26666*1000 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 35 //TODO: IDF-9551, check perform -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 17 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 32 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 15 +#define IDF_TARGET_MAX_SPI_CLK_FREQ 26666*1000 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 35 //TODO: IDF-9551, check perform +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 17 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 32 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 15 #elif CONFIG_IDF_TARGET_ESP32H2 -#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 24*1000*1000 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 32 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 25 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 61 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 54 +#define IDF_TARGET_MAX_SPI_CLK_FREQ 24*1000*1000 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 32 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 25 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 61 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 54 #elif CONFIG_IDF_TARGET_ESP32P4 -#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 20*1000*1000 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 44 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 28 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 26 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 12 +#define IDF_TARGET_MAX_SPI_CLK_FREQ 20*1000*1000 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 44 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 28 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 26 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 12 #elif CONFIG_IDF_TARGET_ESP32C5 -#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 40*1000*1000 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 24 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 15 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 22 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 12 +#define IDF_TARGET_MAX_SPI_CLK_FREQ 40*1000*1000 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 24 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 15 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 22 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 12 #elif CONFIG_IDF_TARGET_ESP32C61 -#define IDF_PERFORMANCE_MAX_SPI_CLK_FREQ 40*1000*1000 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING 32 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING 19 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA 29 -#define IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA 14 +#define IDF_TARGET_MAX_SPI_CLK_FREQ 40*1000*1000 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 32 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 19 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 29 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 14 +#elif CONFIG_IDF_TARGET_ESP32H21 +#if SOC_CLK_TREE_SUPPORTED +//TODO: [ESP32H21] IDF-11521 update perform data according to `TEST_CASE("spi_speed", "[spi]")` +//Also update this value in doc spi_master.rst:535 +#define IDF_TARGET_MAX_SPI_CLK_FREQ 32*1000*1000 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 0 // need update to real_val + 3 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 0 // need update to real_val + 3 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 0 // need update to real_val + 3 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 0 // need update to real_val + 3 #else -#pragma message "`spi_performance.h` is not updated with your target" +// Remove after SOC_CLK_TREE_SUPPORTED +#define IDF_TARGET_MAX_SPI_CLK_FREQ 32*1000*1000 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_DMA 1000 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_DMA 1000 +#define IDF_TARGET_MAX_TRANS_TIME_INTR_CPU 1000 +#define IDF_TARGET_MAX_TRANS_TIME_POLL_CPU 1000 +#endif + #endif diff --git a/components/esp_driver_spi/test_apps/master/README.md b/components/esp_driver_spi/test_apps/master/README.md index 7b96141437..15bfc62bf3 100644 --- a/components/esp_driver_spi/test_apps/master/README.md +++ b/components/esp_driver_spi/test_apps/master/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | diff --git a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c index f612936d9a..8d6d2cea02 100644 --- a/components/esp_driver_spi/test_apps/master/main/test_spi_master.c +++ b/components/esp_driver_spi/test_apps/master/main/test_spi_master.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -114,6 +114,8 @@ TEST_CASE("SPI Master clockdiv calculation routines", "[spi]") for (int i = 0; i < TEST_CLK_TIMES; i++) { check_spi_pre_n_for(clk_param_40m[i][0], clk_param_40m[i][1], clk_param_40m[i][2]); } + } else { + ESP_LOGW(TAG, "Don't find any routing param!!"); } TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST)); @@ -147,7 +149,7 @@ TEST_CASE("SPI Master clk_source and divider accuracy", "[spi]") spi_device_handle_t handle; spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG(); devcfg.clock_source = spi_clk_sour[sour_idx]; - devcfg.clock_speed_hz = MIN(IDF_PERFORMANCE_MAX_SPI_CLK_FREQ, clock_source_hz) >> test_time; + devcfg.clock_speed_hz = MIN(IDF_TARGET_MAX_SPI_CLK_FREQ, clock_source_hz) >> test_time; devcfg.flags |= SPI_DEVICE_HALFDUPLEX; //esp32 half duplex to work on high freq #if SOC_SPI_SUPPORT_CLK_RC_FAST if (devcfg.clock_source == SPI_CLK_SRC_RC_FAST) { @@ -170,6 +172,9 @@ TEST_CASE("SPI Master clk_source and divider accuracy", "[spi]") end = esp_timer_get_time(); int trans_cost = end - start; int time_tolerance = trans_cost_us_predict * TEST_TRANS_TIME_BIAS_RATIO; +#if !SOC_CLK_TREE_SUPPORTED + time_tolerance *= 2; //cpu is executing too slow before clock supported +#endif printf("real_freq %dk predict_cost %d real_cost_us %d diff %d tolerance %d us\n", real_freq_khz, trans_cost_us_predict, trans_cost, (trans_cost - trans_cost_us_predict), time_tolerance); TEST_ASSERT_LESS_THAN_UINT32(time_tolerance, abs(trans_cost - trans_cost_us_predict)); @@ -197,7 +202,7 @@ TEST_CASE("test_device_dynamic_freq_update", "[spi]") .length = sizeof(master_send) * 8, }; - trans_cfg.override_freq_hz = IDF_PERFORMANCE_MAX_SPI_CLK_FREQ; + trans_cfg.override_freq_hz = IDF_TARGET_MAX_SPI_CLK_FREQ; for (int i = 1; i < 15; i++) { TEST_ESP_OK(spi_device_transmit(dev0, &trans_cfg)); spi_device_get_actual_freq(dev0, &master_send); @@ -1463,7 +1468,7 @@ TEST_CASE("spi_speed", "[spi]") } #ifndef CONFIG_SPIRAM printf("[Performance][%s]: %d us\n", "SPI_PER_TRANS_NO_POLLING", (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); - TEST_ASSERT_LESS_THAN_INT(IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING, (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); + TEST_ASSERT_LESS_THAN_INT(IDF_TARGET_MAX_TRANS_TIME_INTR_DMA, (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); #endif //acquire the bus to send polling transactions faster @@ -1481,7 +1486,7 @@ TEST_CASE("spi_speed", "[spi]") } #ifndef CONFIG_SPIRAM printf("[Performance][%s]: %d us\n", "SPI_PER_TRANS_POLLING", (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); - TEST_ASSERT_LESS_THAN_INT(IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING, (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); + TEST_ASSERT_LESS_THAN_INT(IDF_TARGET_MAX_TRANS_TIME_POLL_DMA, (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); #endif //release the bus @@ -1501,7 +1506,7 @@ TEST_CASE("spi_speed", "[spi]") } #ifndef CONFIG_SPIRAM printf("[Performance][%s]: %d us\n", "SPI_PER_TRANS_NO_POLLING_NO_DMA", (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); - TEST_ASSERT_LESS_THAN_INT(IDF_PERFORMANCE_MAX_SPI_PER_TRANS_NO_POLLING_NO_DMA, (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); + TEST_ASSERT_LESS_THAN_INT(IDF_TARGET_MAX_TRANS_TIME_INTR_CPU, (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); #endif //acquire the bus to send polling transactions faster @@ -1519,7 +1524,7 @@ TEST_CASE("spi_speed", "[spi]") } #ifndef CONFIG_SPIRAM printf("[Performance][%s]: %d us\n", "SPI_PER_TRANS_POLLING_NO_DMA", (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); - TEST_ASSERT_LESS_THAN_INT(IDF_PERFORMANCE_MAX_SPI_PER_TRANS_POLLING_NO_DMA, (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); + TEST_ASSERT_LESS_THAN_INT(IDF_TARGET_MAX_TRANS_TIME_POLL_CPU, (int)GET_US_BY_CCOUNT(t_flight_sorted[(TEST_TIMES + 1) / 2])); #endif //release the bus @@ -1830,6 +1835,7 @@ TEST_CASE("test_bus_free_safty_to_remain_devices", "[spi]") TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST)); } +#if SOC_LIGHT_SLEEP_SUPPORTED TEST_CASE("test_spi_master_sleep_retention", "[spi]") { // Prepare a TOP PD sleep @@ -1959,3 +1965,4 @@ TEST_CASE("test_spi_master_auto_sleep_retention", "[spi]") TEST_ESP_OK(esp_pm_configure(&pm_config)); } #endif //CONFIG_PM_ENABLE +#endif //SOC_LIGHT_SLEEP_SUPPORTED diff --git a/components/esp_driver_spi/test_apps/master/main/test_spi_master_sct.c b/components/esp_driver_spi/test_apps/master/main/test_spi_master_sct.c index d0e203704d..63fa435429 100644 --- a/components/esp_driver_spi/test_apps/master/main/test_spi_master_sct.c +++ b/components/esp_driver_spi/test_apps/master/main/test_spi_master_sct.c @@ -292,6 +292,7 @@ TEST_CASE("spi_master: test_sct_dma_desc_oob_on_tail", "[spi]") TEST_ESP_OK(spi_bus_free(SPI2_HOST)); } +#if SOC_LIGHT_SLEEP_SUPPORTED /*----------------------------------------------------------- * Sleep Retention Test *-----------------------------------------------------------*/ @@ -416,3 +417,4 @@ static void sleep_slave(void) TEST_ESP_OK(spi_slave_hd_deinit(SPI2_HOST)); } TEST_CASE_MULTIPLE_DEVICES("test_spi_master_sct_sleep_retention", "[spi_ms]", sleep_master, sleep_slave); +#endif //SOC_LIGHT_SLEEP_SUPPORTED diff --git a/components/esp_driver_spi/test_apps/param/README.md b/components/esp_driver_spi/test_apps/param/README.md index 7b96141437..15bfc62bf3 100644 --- a/components/esp_driver_spi/test_apps/param/README.md +++ b/components/esp_driver_spi/test_apps/param/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | diff --git a/components/esp_driver_spi/test_apps/param/main/test_spi_param.c b/components/esp_driver_spi/test_apps/param/main/test_spi_param.c index 9ce4e0348c..e9918a8a25 100644 --- a/components/esp_driver_spi/test_apps/param/main/test_spi_param.c +++ b/components/esp_driver_spi/test_apps/param/main/test_spi_param.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1269,12 +1269,12 @@ TEST_SPI_MASTER_SLAVE(MODE, mode_conf, "") #define TEST_STEP_LEN 96 #define TEST_STEP 2 static int s_spi_bus_freq[] = { - IDF_PERFORMANCE_MAX_SPI_CLK_FREQ / 10, - IDF_PERFORMANCE_MAX_SPI_CLK_FREQ / 7, - IDF_PERFORMANCE_MAX_SPI_CLK_FREQ / 4, - IDF_PERFORMANCE_MAX_SPI_CLK_FREQ / 2, + IDF_TARGET_MAX_SPI_CLK_FREQ / 10, + IDF_TARGET_MAX_SPI_CLK_FREQ / 7, + IDF_TARGET_MAX_SPI_CLK_FREQ / 4, + IDF_TARGET_MAX_SPI_CLK_FREQ / 2, #if !CONFIG_IDF_TARGET_ESP32P4 //TODO: IDF-8313, update P4 defaulte clock source - IDF_PERFORMANCE_MAX_SPI_CLK_FREQ, + IDF_TARGET_MAX_SPI_CLK_FREQ, #endif }; diff --git a/components/esp_driver_spi/test_apps/slave/README.md b/components/esp_driver_spi/test_apps/slave/README.md index 7b96141437..15bfc62bf3 100644 --- a/components/esp_driver_spi/test_apps/slave/README.md +++ b/components/esp_driver_spi/test_apps/slave/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | diff --git a/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c b/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c index 2f1ce6cf31..c00f53ae01 100644 --- a/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c +++ b/components/esp_driver_spi/test_apps/slave/main/test_spi_slave.c @@ -782,6 +782,7 @@ TEST_CASE("test_slave_isr_pin_to_core", "[spi]") } #endif +#if SOC_LIGHT_SLEEP_SUPPORTED TEST_CASE("test_spi_slave_sleep_retention", "[spi]") { // Prepare a TOP PD sleep @@ -842,3 +843,4 @@ TEST_CASE("test_spi_slave_sleep_retention", "[spi]") TEST_ESP_OK(sleep_cpu_configure(false)); #endif } +#endif //SOC_LIGHT_SLEEP_SUPPORTED diff --git a/components/esp_driver_spi/test_apps/slave_hd/README.md b/components/esp_driver_spi/test_apps/slave_hd/README.md index cc9654f295..ffceaeb158 100644 --- a/components/esp_driver_spi/test_apps/slave_hd/README.md +++ b/components/esp_driver_spi/test_apps/slave_hd/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | diff --git a/components/esp_driver_spi/test_apps/slave_hd/main/test_spi_slave_hd.c b/components/esp_driver_spi/test_apps/slave_hd/main/test_spi_slave_hd.c index 77a709f212..44629b2b39 100644 --- a/components/esp_driver_spi/test_apps/slave_hd/main/test_spi_slave_hd.c +++ b/components/esp_driver_spi/test_apps/slave_hd/main/test_spi_slave_hd.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1063,6 +1063,7 @@ void master_run_essl(void) } TEST_CASE_MULTIPLE_DEVICES("SPI Slave HD: Append mode", "[spi_ms]", master_run_essl, slave_run_append); +#if SOC_LIGHT_SLEEP_SUPPORTED #define TEST_SLP_BUF_ID 12 #define TEST_SLP_BUF_VAL 0xDEADBEEF TEST_CASE("test_spi_slave_hd_sleep_retention", "[spi]") @@ -1238,3 +1239,4 @@ TEST_CASE("test_spi_slave_hd_append_sleep_retention", "[spi]") TEST_ESP_OK(sleep_cpu_configure(false)); #endif } +#endif //SOC_LIGHT_SLEEP_SUPPORTED diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/CMakeLists.txt b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/CMakeLists.txt index 4b26bbdced..a0c969e448 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/CMakeLists.txt +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/CMakeLists.txt @@ -3,6 +3,7 @@ set(srcs "test_app_main.c" "test_fp.c" "test_dport_xt_highint5.S" "test_random.c" + "test_intr_alloc.c" ) if(CONFIG_SOC_GP_LDO_SUPPORTED) @@ -21,10 +22,6 @@ if(CONFIG_SOC_ETM_SUPPORTED) list(APPEND srcs "test_etm_core.c") endif() -if(CONFIG_SOC_GPTIMER_SUPPORTED AND CONFIG_SOC_GPSPI_SUPPORTED) - list(APPEND srcs "test_intr_alloc.c") -endif() - # In order for the cases defined by `TEST_CASE` to be linked into the final elf, # the component can be registered as WHOLE_ARCHIVE idf_component_register(SRCS ${srcs} diff --git a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_intr_alloc.c b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_intr_alloc.c index 4ffb1117b0..2dfbe47e16 100644 --- a/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_intr_alloc.c +++ b/components/esp_hw_support/test_apps/esp_hw_support_unity_tests/main/test_intr_alloc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,11 +19,16 @@ #include "esp_intr_alloc.h" #include "driver/gptimer.h" #include "soc/soc_caps.h" +#include "soc/system_intr.h" +#if SOC_GPSPI_SUPPORTED #include "soc/spi_periph.h" #include "hal/spi_ll.h" +#endif +#include "hal/gpio_ll.h" #include "esp_private/periph_ctrl.h" #include "esp_private/gptimer.h" +#if SOC_GPTIMER_SUPPORTED static bool on_timer_alarm(gptimer_handle_t timer, const gptimer_alarm_event_data_t *edata, void *user_ctx) { volatile int *count = (volatile int *)user_ctx; @@ -116,6 +121,7 @@ TEST_CASE("Intr_alloc test, shared ints", "[intr_alloc]") { timer_test(ESP_INTR_FLAG_SHARED); } +#endif //SOC_GPTIMER_SUPPORTED void static test_isr(void*arg) { @@ -130,13 +136,13 @@ TEST_CASE("Intr_alloc test, shared interrupts don't affect level", "[intr_alloc] intr_handle_t handle_lvl_2; /* Allocate an interrupt of level 1 that will be shared with another source */ - esp_err_t err = esp_intr_alloc(ETS_FROM_CPU_INTR2_SOURCE, + esp_err_t err = esp_intr_alloc(SYS_CPU_INTR_FROM_CPU_2_SOURCE, ESP_INTR_FLAG_LEVEL1 | ESP_INTR_FLAG_SHARED, test_isr, NULL, &handle_lvl_1); TEST_ESP_OK(err); /* Allocate a shared interrupt of a different level */ - err = esp_intr_alloc(ETS_FROM_CPU_INTR3_SOURCE, + err = esp_intr_alloc(SYS_CPU_INTR_FROM_CPU_3_SOURCE, ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_SHARED, test_isr, NULL, &handle_lvl_2); TEST_ESP_OK(err); @@ -163,7 +169,7 @@ TEST_CASE("Intr_alloc test, shared interrupts custom level cleared", "[intr_allo { intr_handle_t handle; - esp_err_t err = esp_intr_alloc(ETS_FROM_CPU_INTR2_SOURCE, + esp_err_t err = esp_intr_alloc(SYS_CPU_INTR_FROM_CPU_2_SOURCE, ESP_INTR_FLAG_LEVEL1 | ESP_INTR_FLAG_SHARED, test_isr, NULL, &handle); TEST_ESP_OK(err); @@ -174,7 +180,7 @@ TEST_CASE("Intr_alloc test, shared interrupts custom level cleared", "[intr_allo /* Free the shared interrupt and try to reallocate it with another level */ TEST_ESP_OK(esp_intr_free(handle)); - err = esp_intr_alloc(ETS_FROM_CPU_INTR3_SOURCE, + err = esp_intr_alloc(SYS_CPU_INTR_FROM_CPU_3_SOURCE, ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_SHARED, test_isr, NULL, &handle); TEST_ESP_OK(err); @@ -199,13 +205,13 @@ TEST_CASE("Intr_alloc test, shared interrupt line for two sources", "[intr_alloc intr_handle_t handle_1; intr_handle_t handle_2; - esp_err_t err = esp_intr_alloc(ETS_FROM_CPU_INTR2_SOURCE, + esp_err_t err = esp_intr_alloc(SYS_CPU_INTR_FROM_CPU_2_SOURCE, ESP_INTR_FLAG_LEVEL1 | ESP_INTR_FLAG_SHARED, test_isr, NULL, &handle_1); TEST_ESP_OK(err); /* Map another source to the exact same interrupt line */ - err = esp_intr_alloc_bind(ETS_FROM_CPU_INTR3_SOURCE, + err = esp_intr_alloc_bind(SYS_CPU_INTR_FROM_CPU_3_SOURCE, ESP_INTR_FLAG_LEVEL1 | ESP_INTR_FLAG_SHARED, test_isr, NULL, handle_1, &handle_2); TEST_ESP_OK(err); @@ -214,7 +220,7 @@ TEST_CASE("Intr_alloc test, shared interrupt line for two sources", "[intr_alloc /* Reallocate the second interrupt source with a higher level, it must fail */ TEST_ESP_OK(esp_intr_free(handle_2)); - err = esp_intr_alloc_bind(ETS_FROM_CPU_INTR3_SOURCE, + err = esp_intr_alloc_bind(SYS_CPU_INTR_FROM_CPU_3_SOURCE, ESP_INTR_FLAG_LEVEL2 | ESP_INTR_FLAG_SHARED, test_isr, NULL, handle_1, &handle_2); TEST_ASSERT(err != ESP_OK); @@ -227,11 +233,7 @@ TEST_CASE("Intr_alloc test, shared interrupt line for two sources", "[intr_alloc TEST_CASE("Allocate previously freed interrupt, with different flags", "[intr_alloc]") { intr_handle_t intr; -#if CONFIG_IDF_TARGET_ESP32P4 - int test_intr_source = ETS_GPIO_INTR0_SOURCE; -#else - int test_intr_source = ETS_GPIO_INTR_SOURCE; -#endif + int test_intr_source = GPIO_LL_INTR_SOURCE0; int isr_flags = ESP_INTR_FLAG_LEVEL2; TEST_ESP_OK(esp_intr_alloc(test_intr_source, isr_flags, test_isr, NULL, &intr)); @@ -242,6 +244,7 @@ TEST_CASE("Allocate previously freed interrupt, with different flags", "[intr_al TEST_ESP_OK(esp_intr_free(intr)); } +#if SOC_GPSPI_SUPPORTED typedef struct { bool flag1; bool flag2; @@ -418,7 +421,8 @@ TEST_CASE("alloc and free isr handle on different core when isr_free_task is NO_ { isr_alloc_free_test(true); } -#endif +#endif //CONFIG_FREERTOS_UNICORE +#endif //SOC_GPSPI_SUPPORTED #if __XTENSA__ static volatile int int_timer_ctr; diff --git a/components/esp_lcd/test_apps/spi_lcd/README.md b/components/esp_lcd/test_apps/spi_lcd/README.md index f600a6e6ef..3bc8f1af35 100644 --- a/components/esp_lcd/test_apps/spi_lcd/README.md +++ b/components/esp_lcd/test_apps/spi_lcd/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | This test app is used to test LCDs with SPI interface. diff --git a/components/esp_system/port/arch/riscv/esp_ipc_isr_port.c b/components/esp_system/port/arch/riscv/esp_ipc_isr_port.c index 0bb76c7d32..9a5a84e9b3 100644 --- a/components/esp_system/port/arch/riscv/esp_ipc_isr_port.c +++ b/components/esp_system/port/arch/riscv/esp_ipc_isr_port.c @@ -5,7 +5,7 @@ */ #include "soc/soc.h" -#include "soc/interrupts.h" +#include "soc/system_intr.h" #include "soc/hp_system_reg.h" #include "esp_intr_alloc.h" #include "riscv/interrupt.h" @@ -16,7 +16,7 @@ void esp_ipc_isr_port_init(const int cpuid) { - uint32_t intr_source = ETS_FROM_CPU_INTR2_SOURCE + cpuid; // ETS_FROM_CPU_INTR2_SOURCE and ETS_FROM_CPU_INTR3_SOURCE + uint32_t intr_source = SYS_CPU_INTR_FROM_CPU_2_SOURCE + cpuid; // ETS_FROM_CPU_INTR2_SOURCE and ETS_FROM_CPU_INTR3_SOURCE esp_intr_disable_source(ETS_IPC_ISR_INUM); diff --git a/components/esp_system/port/arch/xtensa/esp_ipc_isr_port.c b/components/esp_system/port/arch/xtensa/esp_ipc_isr_port.c index 017896bc3b..b960c4dbd4 100644 --- a/components/esp_system/port/arch/xtensa/esp_ipc_isr_port.c +++ b/components/esp_system/port/arch/xtensa/esp_ipc_isr_port.c @@ -5,7 +5,7 @@ */ #include "soc/soc.h" -#include "soc/interrupts.h" +#include "soc/system_intr.h" #include "soc/dport_reg.h" #ifndef CONFIG_IDF_TARGET_ESP32 #include "soc/system_reg.h" @@ -17,7 +17,7 @@ void esp_ipc_isr_port_init(const int cpuid) { - uint32_t intr_source = ETS_FROM_CPU_INTR2_SOURCE + cpuid; // ETS_FROM_CPU_INTR2_SOURCE and ETS_FROM_CPU_INTR3_SOURCE + uint32_t intr_source = SYS_CPU_INTR_FROM_CPU_2_SOURCE + cpuid; // ETS_FROM_CPU_INTR2_SOURCE and ETS_FROM_CPU_INTR3_SOURCE ESP_INTR_DISABLE(ETS_IPC_ISR_INUM); esp_rom_route_intr_matrix(cpuid, intr_source, ETS_IPC_ISR_INUM); ESP_INTR_ENABLE(ETS_IPC_ISR_INUM); diff --git a/components/hal/esp32h21/include/hal/spi_ll.h b/components/hal/esp32h21/include/hal/spi_ll.h new file mode 100644 index 0000000000..dbbaa0d50a --- /dev/null +++ b/components/hal/esp32h21/include/hal/spi_ll.h @@ -0,0 +1,1591 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/******************************************************************************* + * NOTICE + * The LL layer for SPI register operations + * Not public api, don't use in application code. + ******************************************************************************/ + +#pragma once + +#include //for abs() +#include +#include "esp_attr.h" +#include "esp_types.h" +#include "soc/spi_periph.h" +#include "soc/spi_struct.h" +#include "soc/chip_revision.h" +#include "soc/pcr_struct.h" +#include "soc/lldesc.h" +#include "hal/assert.h" +#include "hal/misc.h" +#include "hal/efuse_hal.h" +#include "hal/spi_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define SPI_LL_GET_HW(ID) (((ID)==1) ? &GPSPI2 : NULL) +/// Interrupt not used. Don't use in app. +#define SPI_LL_UNUSED_INT_MASK (SPI_TRANS_DONE_INT_ENA | SPI_SLV_WR_DMA_DONE_INT_ENA | SPI_SLV_RD_DMA_DONE_INT_ENA | SPI_SLV_WR_BUF_DONE_INT_ENA | SPI_SLV_RD_BUF_DONE_INT_ENA) +/// These 2 masks together will set SPI transaction to one line mode +#define SPI_LL_ONE_LINE_CTRL_MASK (SPI_FREAD_QUAD | SPI_FREAD_DUAL | SPI_FCMD_QUAD | SPI_FCMD_DUAL | SPI_FADDR_QUAD | SPI_FADDR_DUAL) +#define SPI_LL_ONE_LINE_USER_MASK (SPI_FWRITE_QUAD | SPI_FWRITE_DUAL) +/// Swap the bit order to its correct place to send +#define HAL_SPI_SWAP_DATA_TX(data, len) HAL_SWAP32((uint32_t)(data) << (32 - len)) +#define SPI_LL_DMA_MAX_BIT_LEN (1 << 18) //reg len: 18 bits +#define SPI_LL_CPU_MAX_BIT_LEN (16 * 32) //Fifo len: 16 words +#define SPI_LL_MOSI_FREE_LEVEL 1 //Default level after bus initialized + +/** + * The data structure holding calculated clock configuration. Since the + * calculation needs long time, it should be calculated during initialization and + * stored somewhere to be quickly used. + */ +typedef uint32_t spi_ll_clock_val_t; + +// Type definition of all supported interrupts +typedef enum { + SPI_LL_INTR_TRANS_DONE = BIT(0), ///< A transaction has done + SPI_LL_INTR_RDBUF = BIT(6), ///< Has received RDBUF command. Only available in slave HD. + SPI_LL_INTR_WRBUF = BIT(7), ///< Has received WRBUF command. Only available in slave HD. + SPI_LL_INTR_RDDMA = BIT(8), ///< Has received RDDMA command. Only available in slave HD. + SPI_LL_INTR_WRDMA = BIT(9), ///< Has received WRDMA command. Only available in slave HD. + SPI_LL_INTR_CMD7 = BIT(10), ///< Has received CMD7 command. Only available in slave HD. + SPI_LL_INTR_CMD8 = BIT(11), ///< Has received CMD8 command. Only available in slave HD. + SPI_LL_INTR_CMD9 = BIT(12), ///< Has received CMD9 command. Only available in slave HD. + SPI_LL_INTR_CMDA = BIT(13), ///< Has received CMDA command. Only available in slave HD. + SPI_LL_INTR_SEG_DONE = BIT(14), +} spi_ll_intr_t; + +// Flags for conditions under which the transaction length should be recorded +typedef enum { + SPI_LL_TRANS_LEN_COND_WRBUF = BIT(0), ///< WRBUF length will be recorded + SPI_LL_TRANS_LEN_COND_RDBUF = BIT(1), ///< RDBUF length will be recorded + SPI_LL_TRANS_LEN_COND_WRDMA = BIT(2), ///< WRDMA length will be recorded + SPI_LL_TRANS_LEN_COND_RDDMA = BIT(3), ///< RDDMA length will be recorded +} 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 + *----------------------------------------------------------------------------*/ +/** + * Enable peripheral register clock + * + * @param host_id Peripheral index number, see `spi_host_device_t` + * @param enable Enable/Disable + */ +static inline void spi_ll_enable_bus_clock(spi_host_device_t host_id, bool enable) +{ + HAL_ASSERT(host_id == SPI2_HOST); + PCR.spi2_conf.spi2_clk_en = enable; +} + +/** + * Reset whole peripheral register to init value defined by HW design + * + * @param host_id Peripheral index number, see `spi_host_device_t` + */ +static inline void spi_ll_reset_register(spi_host_device_t host_id) +{ + HAL_ASSERT(host_id == SPI2_HOST); + PCR.spi2_conf.spi2_rst_en = 1; + PCR.spi2_conf.spi2_rst_en = 0; +} + +/** + * Enable functional output clock within peripheral + * + * @param host_id Peripheral index number, see `spi_host_device_t` + * @param enable Enable/Disable + */ +static inline void spi_ll_enable_clock(spi_host_device_t host_id, bool enable) +{ + HAL_ASSERT(host_id == SPI2_HOST); + PCR.spi2_clkm_conf.spi2_clkm_en = enable; +} + +/** + * 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` + */ +__attribute__((always_inline)) +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). + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_master_init(spi_dev_t *hw) +{ + //Reset timing + hw->user1.cs_setup_time = 0; + hw->user1.cs_hold_time = 0; + + //use all 64 bytes of the buffer + hw->user.usr_miso_highpart = 0; + hw->user.usr_mosi_highpart = 0; + + //Disable unneeded ints + hw->slave.val = 0; + hw->user.val = 0; + + PCR.spi2_clkm_conf.spi2_clkm_sel = 0; + + hw->dma_conf.val = 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; +} + +/** + * Initialize SPI peripheral (slave). + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_slave_init(spi_dev_t *hw) +{ + //Configure slave + hw->clock.val = 0; + hw->user.val = 0; + hw->ctrl.val = 0; + hw->user.doutdin = 1; //we only support full duplex + hw->user.sio = 0; + hw->slave.slave_mode = 1; + hw->slave.soft_reset = 1; + hw->slave.soft_reset = 0; + //use all 64 bytes of the buffer + hw->user.usr_miso_highpart = 0; + hw->user.usr_mosi_highpart = 0; + + // Configure DMA In-Link to not be terminated when transaction bit counter exceeds + hw->dma_conf.rx_eof_en = 0; + hw->dma_conf.dma_slv_seg_trans_en = 0; + + //Disable unneeded ints + hw->dma_int_ena.val &= ~SPI_LL_UNUSED_INT_MASK; +} + +/** + * Initialize SPI peripheral (slave half duplex mode) + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_slave_hd_init(spi_dev_t *hw) +{ + hw->clock.val = 0; + hw->user.val = 0; + hw->ctrl.val = 0; + hw->user.doutdin = 0; + hw->user.sio = 0; + + hw->slave.soft_reset = 1; + hw->slave.soft_reset = 0; + hw->slave.slave_mode = 1; +} + +/** + * Determine and unify the default level of mosi line when bus free + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_set_mosi_free_level(spi_dev_t *hw, bool level) +{ + hw->ctrl.d_pol = level; //set default level for MOSI only on IDLE state +} + +/** + * Apply the register configurations and wait until it's done + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_apply_config(spi_dev_t *hw) +{ + hw->cmd.update = 1; + while (hw->cmd.update); //waiting config applied +} + +/** + * Check whether user-defined transaction is done. + * + * @param hw Beginning address of the peripheral registers. + * + * @return True if transaction is done, otherwise false. + */ +static inline bool spi_ll_usr_is_done(spi_dev_t *hw) +{ + return hw->dma_int_raw.trans_done_int_raw; +} + +/** + * Trigger start of user-defined transaction. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_user_start(spi_dev_t *hw) +{ + hw->cmd.usr = 1; +} + +/** + * Get current running command bit-mask. (Preview) + * + * @param hw Beginning address of the peripheral registers. + * + * @return Bitmask of running command, see ``SPI_CMD_REG``. 0 if no in-flight command. + */ +static inline uint32_t spi_ll_get_running_cmd(spi_dev_t *hw) +{ + return hw->cmd.usr; +} + +/** + * Reset the slave peripheral before next transaction. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_slave_reset(spi_dev_t *hw) +{ + hw->slave.soft_reset = 1; + hw->slave.soft_reset = 0; +} + +/** + * Reset SPI CPU TX FIFO + * + * On ESP32H21, this function is not separated + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_cpu_tx_fifo_reset(spi_dev_t *hw) +{ + hw->dma_conf.buf_afifo_rst = 1; + hw->dma_conf.buf_afifo_rst = 0; +} + +/** + * Reset SPI CPU RX FIFO + * + * On ESP32H21, this function is not separated + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_cpu_rx_fifo_reset(spi_dev_t *hw) +{ + hw->dma_conf.rx_afifo_rst = 1; + hw->dma_conf.rx_afifo_rst = 0; +} + +/** + * Reset SPI DMA TX FIFO + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_dma_tx_fifo_reset(spi_dev_t *hw) +{ + hw->dma_conf.dma_afifo_rst = 1; + hw->dma_conf.dma_afifo_rst = 0; +} + +/** + * Reset SPI DMA RX FIFO + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_dma_rx_fifo_reset(spi_dev_t *hw) +{ + hw->dma_conf.rx_afifo_rst = 1; + hw->dma_conf.rx_afifo_rst = 0; +} + +/** + * Clear in fifo full error + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_infifo_full_clr(spi_dev_t *hw) +{ + hw->dma_int_clr.dma_infifo_full_err_int_clr = 1; +} + +/** + * Clear out fifo empty error + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_outfifo_empty_clr(spi_dev_t *hw) +{ + hw->dma_int_clr.dma_outfifo_empty_err_int_clr = 1; +} + +/*------------------------------------------------------------------------------ + * DMA + *----------------------------------------------------------------------------*/ +/** + * Enable/Disable RX DMA (Peripherals->DMA->RAM) + * + * @param hw Beginning address of the peripheral registers. + * @param enable 1: enable; 2: disable + */ +static inline void spi_ll_dma_rx_enable(spi_dev_t *hw, bool enable) +{ + hw->dma_conf.dma_rx_ena = enable; +} + +/** + * Enable/Disable TX DMA (RAM->DMA->Peripherals) + * + * @param hw Beginning address of the peripheral registers. + * @param enable 1: enable; 2: disable + */ +static inline void spi_ll_dma_tx_enable(spi_dev_t *hw, bool enable) +{ + hw->dma_conf.dma_tx_ena = enable; +} + +/** + * Configuration of RX DMA EOF interrupt generation way + * + * @param hw Beginning address of the peripheral registers. + * @param enable 1: spi_dma_inlink_eof is set when the number of dma pushed data bytes is equal to the value of spi_slv/mst_dma_rd_bytelen[19:0] in spi dma transition. 0: spi_dma_inlink_eof is set by spi_trans_done in non-seg-trans or spi_dma_seg_trans_done in seg-trans. + */ +static inline void spi_ll_dma_set_rx_eof_generation(spi_dev_t *hw, bool enable) +{ + hw->dma_conf.rx_eof_en = enable; +} + +/*------------------------------------------------------------------------------ + * Buffer + *----------------------------------------------------------------------------*/ +/** + * Write to SPI hardware data buffer. + * + * @param hw Beginning address of the peripheral registers. + * @param buffer_to_send Address of the data to be written to the hardware data buffer. + * @param bitlen Length to write, in bits. + */ +static inline void spi_ll_write_buffer(spi_dev_t *hw, const uint8_t *buffer_to_send, size_t bitlen) +{ + for (int x = 0; x < bitlen; x += 32) { + //Use memcpy to get around alignment issues for txdata + uint32_t word; + memcpy(&word, &buffer_to_send[x / 8], 4); + hw->data_buf[(x / 32)].buf = word; + } +} + +/** + * Write to SPI hardware data buffer by buffer ID (address) + * + * @param hw Beginning address of the peripheral registers + * @param byte_id Start ID (address) of the hardware buffer to be written + * @param data Address of the data to be written to the hardware data buffer. + * @param len Length to write, in bytes. + */ +static inline void spi_ll_write_buffer_byte(spi_dev_t *hw, int byte_id, uint8_t *data, int len) +{ + HAL_ASSERT(byte_id + len <= 64); + HAL_ASSERT(len > 0); + HAL_ASSERT(byte_id >= 0); + + while (len > 0) { + uint32_t word; + int offset = byte_id % 4; + int copy_len = 4 - offset; + if (copy_len > len) { + copy_len = len; + } + + //read-modify-write + if (copy_len != 4) { + word = hw->data_buf[byte_id / 4].buf; //read + } + memcpy(((uint8_t *)&word) + offset, data, copy_len); //modify + hw->data_buf[byte_id / 4].buf = word; //write + + data += copy_len; + byte_id += copy_len; + len -= copy_len; + } +} + +/** + * Read from SPI hardware data buffer. + * + * @param hw Beginning address of the peripheral registers. + * @param buffer_to_rcv Address of a buffer to read data from hardware data buffer + * @param bitlen Length to read, in bits. + */ +static inline void spi_ll_read_buffer(spi_dev_t *hw, uint8_t *buffer_to_rcv, size_t bitlen) +{ + 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].buf; + int len = bitlen - x; + if (len > 32) { + len = 32; + } + memcpy(&buffer_to_rcv[x / 8], &word, (len + 7) / 8); + } +} + +/** + * Read from SPI hardware data buffer by buffer ID (address) + * + * @param hw Beginning address of the peripheral registers + * @param byte_id Start ID (address) of the hardware buffer to be read + * @param data Address of a buffer to read data from hardware data buffer + * @param len Length to read, in bytes. + */ +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].buf; + int offset = byte_id % 4; + int copy_len = 4 - offset; + if (copy_len > len) { + copy_len = len; + } + + memcpy(out_data, ((uint8_t *)&word) + offset, copy_len); + byte_id += copy_len; + out_data += copy_len; + len -= copy_len; + } +} + +/*------------------------------------------------------------------------------ + * Configs: mode + *----------------------------------------------------------------------------*/ +/** + * Enable/disable the postive-cs feature. + * + * @param hw Beginning address of the peripheral registers. + * @param cs One of the CS (0-2) to enable/disable the feature. + * @param pos_cs True to enable the feature, otherwise disable (default). + */ +static inline void spi_ll_master_set_pos_cs(spi_dev_t *hw, int cs, uint32_t pos_cs) +{ + if (pos_cs) { + hw->misc.master_cs_pol |= (1 << cs); + } else { + hw->misc.master_cs_pol &= ~(1 << cs); + } +} + +/** + * Enable/disable the LSBFIRST feature for TX data. + * + * @param hw Beginning address of the peripheral registers. + * @param lsbfirst True if LSB of TX data to be sent first, otherwise MSB is sent first (default). + */ +static inline void spi_ll_set_tx_lsbfirst(spi_dev_t *hw, bool lsbfirst) +{ + hw->ctrl.wr_bit_order = lsbfirst; +} + +/** + * Enable/disable the LSBFIRST feature for RX data. + * + * @param hw Beginning address of the peripheral registers. + * @param lsbfirst True if first bit received as LSB, otherwise as MSB (default). + */ +static inline void spi_ll_set_rx_lsbfirst(spi_dev_t *hw, bool lsbfirst) +{ + hw->ctrl.rd_bit_order = lsbfirst; +} + +/** + * Set SPI mode for the peripheral as master. + * + * @param hw Beginning address of the peripheral registers. + * @param mode SPI mode to work at, 0-3. + */ +static inline void spi_ll_master_set_mode(spi_dev_t *hw, uint8_t mode) +{ + //Configure polarity + if (mode == 0) { + hw->misc.ck_idle_edge = 0; + hw->user.ck_out_edge = 0; + } else if (mode == 1) { + hw->misc.ck_idle_edge = 0; + hw->user.ck_out_edge = 1; + } else if (mode == 2) { + hw->misc.ck_idle_edge = 1; + hw->user.ck_out_edge = 1; + } else if (mode == 3) { + hw->misc.ck_idle_edge = 1; + hw->user.ck_out_edge = 0; + } +} + +/** + * Set SPI mode for the peripheral as slave. + * + * @param hw Beginning address of the peripheral registers. + * @param mode SPI mode to work at, 0-3. + */ +static inline void spi_ll_slave_set_mode(spi_dev_t *hw, const int mode, bool dma_used) +{ + if (mode == 0) { + hw->misc.ck_idle_edge = 0; + hw->user.rsck_i_edge = 0; + hw->user.tsck_i_edge = 0; + hw->slave.clk_mode_13 = 0; + } else if (mode == 1) { + hw->misc.ck_idle_edge = 0; + hw->user.rsck_i_edge = 1; + hw->user.tsck_i_edge = 1; + hw->slave.clk_mode_13 = 1; + } else if (mode == 2) { + hw->misc.ck_idle_edge = 1; + hw->user.rsck_i_edge = 1; + hw->user.tsck_i_edge = 1; + hw->slave.clk_mode_13 = 0; + } else if (mode == 3) { + hw->misc.ck_idle_edge = 1; + hw->user.rsck_i_edge = 0; + hw->user.tsck_i_edge = 0; + hw->slave.clk_mode_13 = 1; + } + hw->slave.rsck_data_out = 0; +} + +/** + * Set SPI to work in full duplex or half duplex mode. + * + * @param hw Beginning address of the peripheral registers. + * @param half_duplex True to work in half duplex mode, otherwise in full duplex mode. + */ +static inline void spi_ll_set_half_duplex(spi_dev_t *hw, bool half_duplex) +{ + hw->user.doutdin = !half_duplex; +} + +/** + * Set SPI to work in SIO mode or not. + * + * SIO is a mode which MOSI and MISO share a line. The device MUST work in half-duplexmode. + * + * @param hw Beginning address of the peripheral registers. + * @param sio_mode True to work in SIO mode, otherwise false. + */ +static inline void spi_ll_set_sio_mode(spi_dev_t *hw, int sio_mode) +{ + hw->user.sio = sio_mode; +} + +/** + * Configure the SPI transaction line mode for the master to use. + * + * @param hw Beginning address of the peripheral registers. + * @param line_mode SPI transaction line mode to use, see ``spi_line_mode_t``. + */ +static inline void spi_ll_master_set_line_mode(spi_dev_t *hw, spi_line_mode_t line_mode) +{ + hw->ctrl.val &= ~SPI_LL_ONE_LINE_CTRL_MASK; + hw->user.val &= ~SPI_LL_ONE_LINE_USER_MASK; + hw->ctrl.fcmd_dual = (line_mode.cmd_lines == 2); + hw->ctrl.fcmd_quad = (line_mode.cmd_lines == 4); + hw->ctrl.faddr_dual = (line_mode.addr_lines == 2); + hw->ctrl.faddr_quad = (line_mode.addr_lines == 4); + hw->ctrl.fread_dual = (line_mode.data_lines == 2); + hw->ctrl.fread_quad = (line_mode.data_lines == 4); + hw->user.fwrite_dual = (line_mode.data_lines == 2); + hw->user.fwrite_quad = (line_mode.data_lines == 4); +} + +/** + * Set the SPI slave to work in segment transaction mode + * + * @param hw Beginning address of the peripheral registers. + * @param seg_trans True to work in seg mode, otherwise false. + */ +static inline void spi_ll_slave_set_seg_mode(spi_dev_t *hw, bool seg_trans) +{ + hw->dma_conf.dma_slv_seg_trans_en = seg_trans; +} + +/** + * Select one of the CS to use in current transaction. + * + * @param hw Beginning address of the peripheral registers. + * @param cs_id The cs to use, 0-2, otherwise none of them is used. + */ +static inline void spi_ll_master_select_cs(spi_dev_t *hw, int cs_id) +{ + hw->misc.cs0_dis = (cs_id == 0) ? 0 : 1; + hw->misc.cs1_dis = (cs_id == 1) ? 0 : 1; + hw->misc.cs2_dis = (cs_id == 2) ? 0 : 1; + hw->misc.cs3_dis = (cs_id == 3) ? 0 : 1; + hw->misc.cs4_dis = (cs_id == 4) ? 0 : 1; + hw->misc.cs5_dis = (cs_id == 5) ? 0 : 1; +} + +/** + * Keep Chip Select activated after the current transaction. + * + * @param hw Beginning address of the peripheral registers. + * @param keep_active if 0 don't keep CS activated, else keep CS activated + */ +static inline void spi_ll_master_keep_cs(spi_dev_t *hw, int keep_active) +{ + hw->misc.cs_keep_active = (keep_active != 0) ? 1 : 0; +} + +/*------------------------------------------------------------------------------ + * Configs: parameters + *----------------------------------------------------------------------------*/ +/** + * Set the standard clock mode for master. + * This config take effect only when SPI_CLK (pre-div before periph) div >=2 + * + * @param hw Beginning address of the peripheral registers. + * @param enable_std True for std timing, False for half cycle delay sampling. + */ +static inline void spi_ll_master_set_rx_timing_mode(spi_dev_t *hw, spi_sampling_point_t sample_point) +{ + hw->clock.clk_edge_sel = (sample_point == SPI_SAMPLING_POINT_PHASE_1); +} + +/** + * Get if standard clock mode is supported. + */ +static inline bool spi_ll_master_is_rx_std_sample_supported(void) +{ + return ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 102); +} + +/** + * Set the clock for master by stored value. + * + * @param hw Beginning address of the peripheral registers. + * @param val Stored clock configuration calculated before (by ``spi_ll_cal_clock``). + */ +static inline void spi_ll_master_set_clock_by_reg(spi_dev_t *hw, const spi_ll_clock_val_t *val) +{ + hw->clock.val = *(uint32_t *)val; +} + +/** + * Get the frequency of given dividers. Don't use in app. + * + * @param fapb APB clock of the system. + * @param pre Pre divider. + * @param n Main divider. + * + * @return Frequency of given dividers. + */ +__attribute__((always_inline)) +static inline int spi_ll_freq_for_pre_n(int fapb, int pre, int n) +{ + return (fapb / (pre * n)); +} + +/** + * Calculate the nearest frequency available for master. + * + * @param fapb APB clock of the system. + * @param hz Frequency desired. + * @param duty_cycle Duty cycle desired. + * @param out_reg Output address to store the calculated clock configurations for the return frequency. + * + * @return Actual (nearest) frequency. + */ +__attribute__((always_inline)) +static inline int spi_ll_master_cal_clock(int fapb, int hz, int duty_cycle, spi_ll_clock_val_t *out_reg) +{ + typeof(GPSPI2.clock) reg = {.val = 0}; + int eff_clk; + + //In hw, n, h and l are 1-64, pre is 1-8K. Value written to register is one lower than used value. + if (hz > ((fapb / 4) * 3)) { + //Using Fapb directly will give us the best result here. + reg.clkcnt_l = 0; + reg.clkcnt_h = 0; + reg.clkcnt_n = 0; + reg.clkdiv_pre = 0; + reg.clk_equ_sysclk = 1; + eff_clk = fapb; + } else { + //For best duty cycle resolution, we want n to be as close to 32 as possible, but + //we also need a pre/n combo that gets us as close as possible to the intended freq. + //To do this, we bruteforce n and calculate the best pre to go along with that. + //If there's a choice between pre/n combos that give the same result, use the one + //with the higher n. + int pre, n, h, l; + int bestn = -1; + int bestpre = -1; + int besterr = 0; + int errval; + for (n = 2; n <= 64; n++) { //Start at 2: we need to be able to set h/l so we have at least one high and one low pulse. + //Effectively, this does pre=round((fapb/n)/hz). + pre = ((fapb / n) + (hz / 2)) / hz; + if (pre <= 0) { + pre = 1; + } + if (pre > 16) { + pre = 16; + } + errval = abs(spi_ll_freq_for_pre_n(fapb, pre, n) - hz); + if (bestn == -1 || errval <= besterr) { + besterr = errval; + bestn = n; + bestpre = pre; + } + } + + n = bestn; + pre = bestpre; + l = n; + //This effectively does round((duty_cycle*n)/256) + h = (duty_cycle * n + 127) / 256; + if (h <= 0) { + h = 1; + } + + reg.clk_equ_sysclk = 0; + reg.clkcnt_n = n - 1; + reg.clkdiv_pre = pre - 1; + reg.clkcnt_h = h - 1; + reg.clkcnt_l = l - 1; + eff_clk = spi_ll_freq_for_pre_n(fapb, pre, n); + } + if (out_reg != NULL) { + *(uint32_t *)out_reg = reg.val; + } + return eff_clk; +} + +/** + * Calculate and set clock for SPI master according to desired parameters. + * + * This takes long, suggest to calculate the configuration during + * initialization by ``spi_ll_master_cal_clock`` and store the result, then + * configure the clock by stored value when used by + * ``spi_ll_msater_set_clock_by_reg``. + * + * @param hw Beginning address of the peripheral registers. + * @param fapb APB clock of the system. + * @param hz Frequency desired. + * @param duty_cycle Duty cycle desired. + * + * @return Actual frequency that is used. + */ +static inline int spi_ll_master_set_clock(spi_dev_t *hw, int fapb, int hz, int duty_cycle) +{ + spi_ll_clock_val_t reg_val; + int freq = spi_ll_master_cal_clock(fapb, hz, duty_cycle, ®_val); + spi_ll_master_set_clock_by_reg(hw, ®_val); + return freq; +} + +/** + * Set the mosi delay after the output edge to the signal. (Preview) + * + * The delay mode/num is a Espressif conception, may change in the new chips. + * + * @param hw Beginning address of the peripheral registers. + * @param delay_mode Delay mode, see TRM. + * @param delay_num APB clocks to delay. + */ +static inline void spi_ll_set_mosi_delay(spi_dev_t *hw, int delay_mode, int delay_num) +{ +} + +/** + * Set the miso delay applied to the input signal before the internal peripheral. (Preview) + * + * The delay mode/num is a Espressif conception, may change in the new chips. + * + * @param hw Beginning address of the peripheral registers. + * @param delay_mode Delay mode, see TRM. + * @param delay_num APB clocks to delay. + */ +static inline void spi_ll_set_miso_delay(spi_dev_t *hw, int delay_mode, int delay_num) +{ +} + +/** + * Set the delay of SPI clocks before the CS inactive edge after the last SPI clock. + * + * @param hw Beginning address of the peripheral registers. + * @param hold Delay of SPI clocks after the last clock, 0 to disable the hold phase. + */ +static inline void spi_ll_master_set_cs_hold(spi_dev_t *hw, int hold) +{ + hw->user1.cs_hold_time = hold; + hw->user.cs_hold = hold ? 1 : 0; +} + +/** + * Set the delay of SPI clocks before the first SPI clock after the CS active edge. + * + * Note ESP32H21 doesn't support to use this feature when command/address phases + * are used in full duplex mode. + * + * @param hw Beginning address of the peripheral registers. + * @param setup Delay of SPI clocks after the CS active edge, 0 to disable the setup phase. + */ +static inline void spi_ll_master_set_cs_setup(spi_dev_t *hw, uint8_t setup) +{ + hw->user1.cs_setup_time = setup - 1; + hw->user.cs_setup = setup ? 1 : 0; +} + +/*------------------------------------------------------------------------------ + * Configs: data + *----------------------------------------------------------------------------*/ +/** + * Set the output length (master). + * This should be called before master setting MISO(input) length + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen output length, in bits. + */ +static inline void spi_ll_set_mosi_bitlen(spi_dev_t *hw, size_t bitlen) +{ + if (bitlen > 0) { + hw->ms_dlen.ms_data_bitlen = bitlen - 1; + } +} + +/** + * Set the input length (master). + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen input length, in bits. + */ +static inline void spi_ll_set_miso_bitlen(spi_dev_t *hw, size_t bitlen) +{ + if (bitlen > 0) { + hw->ms_dlen.ms_data_bitlen = bitlen - 1; + } +} + +/** + * Set the maximum input length (slave). + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen Input length, in bits. + */ +static inline void spi_ll_slave_set_rx_bitlen(spi_dev_t *hw, size_t bitlen) +{ + //This is not used in ESP32H21 +} + +/** + * Set the maximum output length (slave). + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen Output length, in bits. + */ +static inline void spi_ll_slave_set_tx_bitlen(spi_dev_t *hw, size_t bitlen) +{ + //This is not used in ESP32H21 +} + +/** + * Set the length of command phase. + * + * When in 4-bit mode, the SPI cycles of the phase will be shorter. E.g. 16-bit + * command phases takes 4 cycles in 4-bit mode. + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen Length of command phase, in bits. 0 to disable the command phase. + */ +static inline void spi_ll_set_command_bitlen(spi_dev_t *hw, int bitlen) +{ + hw->user2.usr_command_bitlen = bitlen - 1; + hw->user.usr_command = bitlen ? 1 : 0; +} + +/** + * Set the length of address phase. + * + * When in 4-bit mode, the SPI cycles of the phase will be shorter. E.g. 16-bit + * address phases takes 4 cycles in 4-bit mode. + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen Length of address phase, in bits. 0 to disable the address phase. + */ +static inline void spi_ll_set_addr_bitlen(spi_dev_t *hw, int bitlen) +{ + hw->user1.usr_addr_bitlen = bitlen - 1; + hw->user.usr_addr = bitlen ? 1 : 0; +} + +/** + * Set the address value in an intuitive way. + * + * The length and lsbfirst is required to shift and swap the address to the right place. + * + * @param hw Beginning address of the peripheral registers. + * @param address Address to set + * @param addrlen Length of the address phase + * @param lsbfirst Whether the LSB first feature is enabled. + */ +static inline void spi_ll_set_address(spi_dev_t *hw, uint64_t addr, int addrlen, uint32_t lsbfirst) +{ + if (lsbfirst) { + /* The output address start from the LSB of the highest byte, i.e. + * addr[24] -> addr[31] + * ... + * addr[0] -> addr[7] + * So swap the byte order to let the LSB sent first. + */ + addr = HAL_SWAP32(addr); + //otherwise only addr register is sent + hw->addr.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.val = addr << (32 - addrlen); + } +} + +/** + * Set the command value in an intuitive way. + * + * The length and lsbfirst is required to shift and swap the command to the right place. + * + * @param hw Beginning command of the peripheral registers. + * @param command Command to set + * @param addrlen Length of the command phase + * @param lsbfirst Whether the LSB first feature is enabled. + */ +static inline void spi_ll_set_command(spi_dev_t *hw, uint16_t cmd, int cmdlen, bool lsbfirst) +{ + if (lsbfirst) { + // The output command start from bit0 to bit 15, kept as is. + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user2, usr_command_value, cmd); + } else { + /* Output command will be sent from bit 7 to 0 of command_value, and + * then bit 15 to 8 of the same register field. Shift and swap to send + * more straightly. + */ + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user2, usr_command_value, HAL_SPI_SWAP_DATA_TX(cmd, cmdlen)); + } +} + +/** + * Set dummy clocks to output before RX phase (master), or clocks to skip + * before the data phase and after the address phase (slave). + * + * Note this phase is also used to compensate RX timing in half duplex mode. + * + * @param hw Beginning address of the peripheral registers. + * @param dummy_n Dummy cycles used. 0 to disable the dummy phase. + */ +static inline void spi_ll_set_dummy(spi_dev_t *hw, int dummy_n) +{ + hw->user.usr_dummy = dummy_n ? 1 : 0; + if (dummy_n > 0) { + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->user1, usr_dummy_cyclelen, dummy_n - 1); + } +} + +/** + * Enable/disable the RX data phase. + * + * @param hw Beginning address of the peripheral registers. + * @param enable True if RX phase exist, otherwise false. + */ +static inline void spi_ll_enable_miso(spi_dev_t *hw, int enable) +{ + hw->user.usr_miso = enable; +} + +/** + * Enable/disable the TX data phase. + * + * @param hw Beginning address of the peripheral registers. + * @param enable True if TX phase exist, otherwise false. + */ +static inline void spi_ll_enable_mosi(spi_dev_t *hw, int enable) +{ + hw->user.usr_mosi = enable; +} + +/** + * Get the received bit length of the slave. + * + * @param hw Beginning address of the peripheral registers. + * + * @return Received bits of the slave. + */ +static inline uint32_t spi_ll_slave_get_rcv_bitlen(spi_dev_t *hw) +{ + return hw->slave1.slv_data_bitlen; +} + +/*------------------------------------------------------------------------------ + * Interrupts + *----------------------------------------------------------------------------*/ +//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_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) +{ +#define ENA_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 1; + FOR_EACH_ITEM(ENA_INTR, INTR_LIST); +#undef ENA_INTR +} + +static inline void spi_ll_disable_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) +{ +#define DIS_INTR(intr_bit, en_reg, ...) if (intr_mask & (intr_bit)) hw->en_reg = 0; + FOR_EACH_ITEM(DIS_INTR, INTR_LIST); +#undef DIS_INTR +} + +static inline void spi_ll_set_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) +{ +#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 = 1; + FOR_EACH_ITEM(CLR_INTR, INTR_LIST); +#undef CLR_INTR +} + +static inline bool spi_ll_get_intr(spi_dev_t *hw, spi_ll_intr_t intr_mask) +{ +#define GET_INTR(intr_bit, _, st_reg, ...) if (intr_mask & (intr_bit) && hw->st_reg) return true; + FOR_EACH_ITEM(GET_INTR, INTR_LIST); + return false; +#undef GET_INTR +} + +#undef FOR_EACH_ITEM +#undef INTR_LIST + +/** + * Disable the trans_done interrupt. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_disable_int(spi_dev_t *hw) +{ + hw->dma_int_ena.trans_done_int_ena = 0; +} + +/** + * Clear the trans_done interrupt. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_clear_int_stat(spi_dev_t *hw) +{ + hw->dma_int_clr.trans_done_int_clr = 1; +} + +/** + * Set the trans_done interrupt. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_set_int_stat(spi_dev_t *hw) +{ + hw->dma_int_set.trans_done_int_set = 1; +} + +/** + * Enable the trans_done interrupt. + * + * @param hw Beginning address of the peripheral registers. + */ +static inline void spi_ll_enable_int(spi_dev_t *hw) +{ + hw->dma_int_ena.trans_done_int_ena = 1; +} + +/*------------------------------------------------------------------------------ + * Slave HD + *----------------------------------------------------------------------------*/ +static inline void spi_ll_slave_hd_set_len_cond(spi_dev_t *hw, spi_ll_trans_len_cond_t cond_mask) +{ + 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.slv_data_bitlen / 8; +} + +static inline uint32_t spi_ll_slave_hd_get_last_addr(spi_dev_t *hw) +{ + return hw->slave1.slv_last_addr; +} + +/*------------------------------------------------------------------------------ + * Segmented-Configure-Transfer + *----------------------------------------------------------------------------*/ +#define SPI_LL_CONF_BUF_SET_BIT(_w, _m) ({ \ + (_w) |= (_m); \ + }) +#define SPI_LL_CONF_BUF_CLR_BIT(_w, _m) ({ \ + (_w) &= ~(_m); \ + }) + +#define SPI_LL_CONF_BUF_SET_FIELD(_w, _f, val) ({ \ + ((_w) = (((_w) & ~((_f##_V) << (_f##_S))) | (((val) & (_f##_V))<<(_f##_S)))); \ + }) + +#define SPI_LL_CONF_BUF_GET_FIELD(_w, _f) ({ \ + (((_w) >> (_f##_S)) & (_f##_V)); \ + }) + +//This offset is 1, for bitmap +#define SPI_LL_CONF_BUFFER_OFFSET (1) +//bitmap must be the first +#define SPI_LL_CONF_BITMAP_POS (0) + +#define SPI_LL_ADDR_REG_POS (0) +#define SPI_LL_CTRL_REG_POS (1) +#define SPI_LL_CLOCK_REG_POS (2) +#define SPI_LL_USER_REG_POS (3) +#define SPI_LL_USER1_REG_POS (4) +#define SPI_LL_USER2_REG_POS (5) +#define SPI_LL_MS_DLEN_REG_POS (6) +#define SPI_LL_MISC_REG_POS (7) +#define SPI_LL_DIN_MODE_REG_POS (8) +#define SPI_LL_DIN_NUM_REG_POS (9) +#define SPI_LL_DOUT_MODE_REG_POS (10) +#define SPI_LL_DMA_CONF_REG_POS (11) +#define SPI_LL_DMA_INT_ENA_REG_POS (12) +#define SPI_LL_DMA_INT_CLR_REG_POS (13) + +#define SPI_LL_SCT_MAGIC_NUMBER (0x2) + +/** + * Set conf phase bits len to HW for segment config trans mode. + * + * @param hw Beginning address of the peripheral registers. + * @param conf_bitlen Value of field conf_bitslen in cmd reg. + */ +static inline void spi_ll_set_conf_phase_bits_len(spi_dev_t *hw, uint32_t conf_bitlen) +{ + if (conf_bitlen <= SOC_SPI_SCT_CONF_BITLEN_MAX) { + hw->cmd.conf_bitlen = conf_bitlen; + } +} + +/** + * Update the conf buffer for conf phase + * + * @param hw Beginning address of the peripheral registers. + * @param is_end Is this transaction the end of this segment. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_conf_phase_conf_buffer(spi_dev_t *hw, bool is_end, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: usr_conf_nxt + if (is_end) { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_CONF_NXT_M); + } else { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_CONF_NXT_M); + } +} + +/** + * Update the line mode of conf buffer for conf phase + * + * @param hw Beginning address of the peripheral registers. + * @param line_mode line mode struct of each phase. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_line_mode_conf_buff(spi_dev_t *hw, spi_line_mode_t line_mode, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] &= ~SPI_LL_ONE_LINE_CTRL_MASK; + conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] &= ~SPI_LL_ONE_LINE_USER_MASK; + + switch (line_mode.cmd_lines) { + case 2: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FCMD_DUAL_M); break; + case 4: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FCMD_QUAD_M); break; + case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FCMD_OCT_M); break; + default: break; + } + + switch (line_mode.addr_lines) { + case 2: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FADDR_DUAL_M); break; + case 4: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FADDR_QUAD_M); break; + case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FADDR_OCT_M); break; + default: break; + } + + switch (line_mode.data_lines) { + case 2: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FREAD_DUAL_M); + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FWRITE_DUAL_M); + break; + case 4: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FREAD_QUAD_M); + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FWRITE_QUAD_M); + break; + case 8: SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FREAD_OCT_M); + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_FWRITE_OCT_M); + break; + default: break; + } +} + +/** + * Update the conf buffer for prep phase + * + * @param hw Beginning address of the peripheral registers. + * @param setup CS setup time + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_prep_phase_conf_buffer(spi_dev_t *hw, uint8_t setup, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: cs_setup + if (setup) { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_SETUP_M); + } else { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_SETUP_M); + } + + //user1 reg: cs_setup_time + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER1_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_SETUP_TIME, setup - 1); +} + +/** + * Update the conf buffer for cmd phase + * + * @param hw Beginning address of the peripheral registers. + * @param cmd Command value + * @param cmdlen Length of the cmd phase + * @param lsbfirst Whether LSB first + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_cmd_phase_conf_buffer(spi_dev_t *hw, uint16_t cmd, int cmdlen, bool lsbfirst, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: usr_command + if (cmdlen) { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_COMMAND_M); + } else { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_COMMAND_M); + } + + //user2 reg: usr_command_bitlen + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER2_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_COMMAND_BITLEN, cmdlen - 1); + + //user2 reg: usr_command_value + if (lsbfirst) { + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER2_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_COMMAND_VALUE, cmd); + } else { + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER2_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_COMMAND_VALUE, HAL_SPI_SWAP_DATA_TX(cmd, cmdlen)); + } +} + +/** + * Update the conf buffer for addr phase + * + * @param hw Beginning address of the peripheral registers. + * @param addr Address to set + * @param addrlen Length of the address phase + * @param lsbfirst whether the LSB first feature is enabled. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_addr_phase_conf_buffer(spi_dev_t *hw, uint64_t addr, int addrlen, bool lsbfirst, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: usr_addr + if (addrlen) { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_ADDR_M); + } else { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_ADDR_M); + } + + //user1 reg: usr_addr_bitlen + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER1_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_ADDR_BITLEN, addrlen - 1); + + //addr reg: addr + if (lsbfirst) { + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_ADDR_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_ADDR_VALUE, HAL_SWAP32(addr)); + } else { + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_ADDR_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_ADDR_VALUE, (addr << (32 - addrlen))); + } +} + +/** + * Update the conf buffer for dummy phase + * + * @param hw Beginning address of the peripheral registers. + * @param dummy_n Dummy cycles used. 0 to disable the dummy phase. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_dummy_phase_conf_buffer(spi_dev_t *hw, int dummy_n, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: usr_dummy + if (dummy_n) { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_DUMMY_M); + } else { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_DUMMY_M); + } + + //user1 reg: usr_dummy_cyclelen + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER1_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_DUMMY_CYCLELEN, dummy_n - 1); +} + +/** + * Update the conf buffer for dout phase + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen output length, in bits. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_dout_phase_conf_buffer(spi_dev_t *hw, int bitlen, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + if (bitlen) { + //user reg: usr_mosi + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_MOSI_M); + //dma_conf reg: dma_tx_ena + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_DMA_CONF_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_DMA_TX_ENA_M); + //ms_dlen reg: ms_data_bitlen + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_MS_DLEN_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_MS_DATA_BITLEN, bitlen - 1); + } else { + //user reg: usr_mosi + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_MOSI_M); + //dma_conf reg: dma_tx_ena + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_DMA_CONF_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_DMA_TX_ENA_M); + } +} + +/** + * Update the conf buffer for din phase + * + * @param hw Beginning address of the peripheral registers. + * @param bitlen input length, in bits. + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_din_phase_conf_buffer(spi_dev_t *hw, int bitlen, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + if (bitlen) { + //user reg: usr_miso + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_MISO_M); + //dma_conf reg: dma_rx_ena + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_DMA_CONF_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_DMA_RX_ENA_M); + //ms_dlen reg: ms_data_bitlen + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_MS_DLEN_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_MS_DATA_BITLEN, bitlen - 1); + } else { + //user reg: usr_miso + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_USR_MISO_M); + //dma_conf reg: dma_rx_ena + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_DMA_CONF_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_DMA_RX_ENA_M); + } +} + +/** + * Update the conf buffer for done phase + * + * @param hw Beginning address of the peripheral registers. + * @param setup CS hold time + * @param conf_buffer Conf buffer to be updated. + */ +static inline void spi_ll_format_done_phase_conf_buffer(spi_dev_t *hw, int hold, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + //user reg: cs_hold + if (hold) { + SPI_LL_CONF_BUF_SET_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_HOLD_M); + } else { + SPI_LL_CONF_BUF_CLR_BIT(conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_HOLD_M); + } + + //user1 reg: cs_hold_time + SPI_LL_CONF_BUF_SET_FIELD(conf_buffer[SPI_LL_USER1_REG_POS + SPI_LL_CONF_BUFFER_OFFSET], SPI_CS_HOLD_TIME, hold); +} + +/** + * Initialize the conf buffer: + * + * - init bitmap + * - save all register values into the rest of the conf buffer words + * + * @param hw Beginning address of the peripheral registers. + * @param conf_buffer Conf buffer to be updated. + */ +__attribute__((always_inline)) +static inline void spi_ll_init_conf_buffer(spi_dev_t *hw, uint32_t conf_buffer[SOC_SPI_SCT_BUFFER_NUM_MAX]) +{ + conf_buffer[SPI_LL_CONF_BITMAP_POS] = 0x7FFF | (SPI_LL_SCT_MAGIC_NUMBER << 28); + conf_buffer[SPI_LL_ADDR_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->addr.usr_addr_value; + conf_buffer[SPI_LL_CTRL_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->ctrl.val; + conf_buffer[SPI_LL_CLOCK_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->clock.val; + conf_buffer[SPI_LL_USER_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->user.val; + conf_buffer[SPI_LL_USER1_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->user1.val; + conf_buffer[SPI_LL_USER2_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->user2.val; + conf_buffer[SPI_LL_MS_DLEN_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->ms_dlen.val; + conf_buffer[SPI_LL_MISC_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->misc.val; + conf_buffer[SPI_LL_DIN_MODE_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->din_mode.val; + conf_buffer[SPI_LL_DIN_NUM_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->din_num.val; + conf_buffer[SPI_LL_DOUT_MODE_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->dout_mode.val; + conf_buffer[SPI_LL_DMA_CONF_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->dma_conf.val; + conf_buffer[SPI_LL_DMA_INT_ENA_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->dma_int_ena.val; + conf_buffer[SPI_LL_DMA_INT_CLR_REG_POS + SPI_LL_CONF_BUFFER_OFFSET] = hw->dma_int_clr.val; +} + +/** + * Enable/Disable the conf phase + * + * @param hw Beginning address of the peripheral registers. + * @param enable True: enable; False: disable + */ +static inline void spi_ll_conf_state_enable(spi_dev_t *hw, bool enable) +{ + hw->slave.usr_conf = enable; +} + +/** + * Set Segmented-Configure-Transfer required magic value + * + * @param hw Beginning address of the peripheral registers. + * @param magic_value magic value + */ +static inline void spi_ll_set_magic_number(spi_dev_t *hw, uint8_t magic_value) +{ + hw->slave.dma_seg_magic_value = magic_value; +} + +/** + * 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 diff --git a/components/soc/esp32/include/soc/system_intr.h b/components/soc/esp32/include/soc/system_intr.h index a681733c8d..9289296b49 100644 --- a/components/soc/esp32/include/soc/system_intr.h +++ b/components/soc/esp32/include/soc/system_intr.h @@ -5,9 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_FROM_CPU_INTR0_SOURCE #define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_FROM_CPU_INTR1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_FROM_CPU_INTR2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_FROM_CPU_INTR3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE diff --git a/components/soc/esp32c2/include/soc/system_intr.h b/components/soc/esp32c2/include/soc/system_intr.h index 9f7be40172..9289296b49 100644 --- a/components/soc/esp32c2/include/soc/system_intr.h +++ b/components/soc/esp32c2/include/soc/system_intr.h @@ -5,8 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_FROM_CPU_INTR0_SOURCE +#define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_FROM_CPU_INTR1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_FROM_CPU_INTR2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_FROM_CPU_INTR3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE diff --git a/components/soc/esp32c3/include/soc/system_intr.h b/components/soc/esp32c3/include/soc/system_intr.h index 9f7be40172..9289296b49 100644 --- a/components/soc/esp32c3/include/soc/system_intr.h +++ b/components/soc/esp32c3/include/soc/system_intr.h @@ -5,8 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_FROM_CPU_INTR0_SOURCE +#define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_FROM_CPU_INTR1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_FROM_CPU_INTR2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_FROM_CPU_INTR3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE diff --git a/components/soc/esp32c5/include/soc/system_intr.h b/components/soc/esp32c5/include/soc/system_intr.h index 9f7be40172..9289296b49 100644 --- a/components/soc/esp32c5/include/soc/system_intr.h +++ b/components/soc/esp32c5/include/soc/system_intr.h @@ -5,8 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_FROM_CPU_INTR0_SOURCE +#define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_FROM_CPU_INTR1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_FROM_CPU_INTR2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_FROM_CPU_INTR3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE diff --git a/components/soc/esp32c6/include/soc/system_intr.h b/components/soc/esp32c6/include/soc/system_intr.h index 9f7be40172..9289296b49 100644 --- a/components/soc/esp32c6/include/soc/system_intr.h +++ b/components/soc/esp32c6/include/soc/system_intr.h @@ -5,8 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_FROM_CPU_INTR0_SOURCE +#define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_FROM_CPU_INTR1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_FROM_CPU_INTR2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_FROM_CPU_INTR3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE diff --git a/components/soc/esp32c61/include/soc/system_intr.h b/components/soc/esp32c61/include/soc/system_intr.h index 9f7be40172..9289296b49 100644 --- a/components/soc/esp32c61/include/soc/system_intr.h +++ b/components/soc/esp32c61/include/soc/system_intr.h @@ -5,8 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_FROM_CPU_INTR0_SOURCE +#define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_FROM_CPU_INTR1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_FROM_CPU_INTR2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_FROM_CPU_INTR3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE diff --git a/components/soc/esp32h2/include/soc/system_intr.h b/components/soc/esp32h2/include/soc/system_intr.h index 9f7be40172..9289296b49 100644 --- a/components/soc/esp32h2/include/soc/system_intr.h +++ b/components/soc/esp32h2/include/soc/system_intr.h @@ -5,8 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_FROM_CPU_INTR0_SOURCE +#define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_FROM_CPU_INTR1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_FROM_CPU_INTR2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_FROM_CPU_INTR3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE diff --git a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in index 3e665b2312..47f36de09a 100644 --- a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in @@ -35,6 +35,10 @@ config SOC_RTC_MEM_SUPPORTED bool default y +config SOC_GPSPI_SUPPORTED + bool + default y + config SOC_I2C_SUPPORTED bool default y @@ -467,10 +471,6 @@ config SOC_SPI_MAXIMUM_BUFFER_SIZE int default 64 -config SOC_SPI_SUPPORT_DDRCLK - bool - default y - config SOC_SPI_SLAVE_SUPPORT_SEG_TRANS bool default y @@ -483,6 +483,10 @@ 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 diff --git a/components/soc/esp32h21/include/soc/clk_tree_defs.h b/components/soc/esp32h21/include/soc/clk_tree_defs.h index 00dd92cf19..b034ac071e 100644 --- a/components/soc/esp32h21/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h21/include/soc/clk_tree_defs.h @@ -237,13 +237,21 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of SPI */ -#define SOC_SPI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_PLL_F48M} +#if SOC_CLK_TREE_SUPPORTED +#define SOC_SPI_CLKS {SOC_MOD_CLK_RC_FAST, SOC_MOD_CLK_PLL_F48M, SOC_MOD_CLK_XTAL} +#else +#define SOC_SPI_CLKS {SOC_MOD_CLK_XTAL} +#endif /** * @brief Type of SPI clock source. */ typedef enum { +#if SOC_CLK_TREE_SUPPORTED SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_48M as SPI source clock */ +#else + SPI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as SPI source clock */ +#endif SPI_CLK_SRC_PLL_F48M = SOC_MOD_CLK_PLL_F48M, /*!< Select PLL_48M 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 */ diff --git a/components/soc/esp32h21/include/soc/soc.h b/components/soc/esp32h21/include/soc/soc.h index 3456ea4334..14bc1952ef 100644 --- a/components/soc/esp32h21/include/soc/soc.h +++ b/components/soc/esp32h21/include/soc/soc.h @@ -25,7 +25,6 @@ #define DR_REG_I2S_BASE(i) (DR_REG_I2S_BASE) // only one I2S on H21 #define DR_REG_TIMG_BASE(i) (DR_REG_TIMERG0_BASE + (i)*0x1000) #define DR_REG_SPI_MEM_BASE(i) (DR_REG_SPIMEM0_BASE + (i) * 0x1000) -#define DR_REG_SPI_BASE(i) (((i)==2) ? (DR_REG_SPI2_BASE) : (0)) // only one GPSPI #define DR_REG_I2C_BASE(i) (DR_REG_I2C_EXT0_BASE + (i) * 0x1000) //Registers Operation {{ diff --git a/components/soc/esp32h21/include/soc/soc_caps.h b/components/soc/esp32h21/include/soc/soc_caps.h index 5bf05ed09e..64dbc03d21 100644 --- a/components/soc/esp32h21/include/soc/soc_caps.h +++ b/components/soc/esp32h21/include/soc/soc_caps.h @@ -38,7 +38,7 @@ #define SOC_RTC_MEM_SUPPORTED 1 //TODO: [ESP32H21] IDF-11548 // #define SOC_I2S_SUPPORTED 1 //TODO: [ESP32H21] IDF-11606, IDF-11608 // #define SOC_SDM_SUPPORTED 1 //TODO: [ESP32H21] IDF-11573 -// #define SOC_GPSPI_SUPPORTED 1 //TODO: [ESP32H21] IDF-11583, IDF-11584, IDF-11587 +#define SOC_GPSPI_SUPPORTED 1 // #define SOC_LEDC_SUPPORTED 1 //TODO: [ESP32H21] IDF-11568 #define SOC_I2C_SUPPORTED 1 #define SOC_SYSTIMER_SUPPORTED 1 //TODO: [ESP32H21] IDF-11596, IDF-11598 @@ -382,17 +382,16 @@ #define SOC_SPI_PERIPH_NUM 2 #define SOC_SPI_PERIPH_CS_NUM(i) 6 #define SOC_SPI_MAX_CS_NUM 6 - -#define SOC_SPI_MAXIMUM_BUFFER_SIZE 64 - -#define SOC_SPI_SUPPORT_DDRCLK 1 +#define SOC_SPI_MAXIMUM_BUFFER_SIZE 64 #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-11587 +#define SOC_SPI_SUPPORT_SLAVE_HD_VER2 1 #define SOC_SPI_SUPPORT_CLK_XTAL 1 +#if SOC_CLK_TREE_SUPPORTED //TODO: [ESP32H21] IDF-11521 #define SOC_SPI_SUPPORT_CLK_PLL_F48M 1 #define SOC_SPI_SUPPORT_CLK_RC_FAST 1 +#endif // Peripheral supports DIO, DOUT, QIO, or QOUT // host_id = 0 -> SPI0/SPI1, host_id = 1 -> SPI2, @@ -404,8 +403,8 @@ #define SOC_SPI_SCT_BUFFER_NUM_MAX (1 + SOC_SPI_SCT_REG_NUM) //1-word-bitmap + 14-word-regs #define SOC_SPI_SCT_CONF_BITLEN_MAX 0x3FFFA //18 bits wide reg -#define SOC_MEMSPI_IS_INDEPENDENT 1 -#define SOC_SPI_MAX_PRE_DIVIDER 16 +#define SOC_MEMSPI_IS_INDEPENDENT 1 +#define SOC_SPI_MAX_PRE_DIVIDER 16 /*-------------------------- SPI MEM CAPS ---------------------------------------*/ #define SOC_SPI_MEM_SUPPORT_AUTO_WAIT_IDLE (1) diff --git a/components/soc/esp32h21/include/soc/spi_pins.h b/components/soc/esp32h21/include/soc/spi_pins.h index 631b645227..df3ae8f1c3 100644 --- a/components/soc/esp32h21/include/soc/spi_pins.h +++ b/components/soc/esp32h21/include/soc/spi_pins.h @@ -18,11 +18,11 @@ // GPSPI2 IOMUX PINs #define SPI2_FUNC_NUM 2 -#define SPI2_IOMUX_PIN_NUM_MISO 4 -#define SPI2_IOMUX_PIN_NUM_HD 1 #define SPI2_IOMUX_PIN_NUM_WP 0 +#define SPI2_IOMUX_PIN_NUM_HD 1 #define SPI2_IOMUX_PIN_NUM_CLK 2 #define SPI2_IOMUX_PIN_NUM_MOSI 3 +#define SPI2_IOMUX_PIN_NUM_MISO 4 #define SPI2_IOMUX_PIN_NUM_CS 12 #endif diff --git a/components/soc/esp32h21/include/soc/system_intr.h b/components/soc/esp32h21/include/soc/system_intr.h index 69134abba5..b1d0bf0939 100644 --- a/components/soc/esp32h21/include/soc/system_intr.h +++ b/components/soc/esp32h21/include/soc/system_intr.h @@ -5,8 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_CPU_INTR_FROM_CPU_0_SOURCE +#define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_CPU_INTR_FROM_CPU_1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_CPU_INTR_FROM_CPU_2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_CPU_INTR_FROM_CPU_3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_INTR_SOURCE diff --git a/components/soc/esp32h21/register/soc/pcr_struct.h b/components/soc/esp32h21/register/soc/pcr_struct.h index cc05d6726b..5cdad086d8 100644 --- a/components/soc/esp32h21/register/soc/pcr_struct.h +++ b/components/soc/esp32h21/register/soc/pcr_struct.h @@ -1059,7 +1059,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; diff --git a/components/soc/esp32h21/register/soc/spi_reg.h b/components/soc/esp32h21/register/soc/spi_reg.h index ebffcfb3c0..4da24d9072 100644 --- a/components/soc/esp32h21/register/soc/spi_reg.h +++ b/components/soc/esp32h21/register/soc/spi_reg.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -7,14 +7,17 @@ #include #include "soc/soc.h" + #ifdef __cplusplus extern "C" { #endif +#define DR_REG_SPI_BASE(i) (((i)==2) ? (DR_REG_GPSPI2_BASE) : (0)) // only one GPSPI + /** SPI_CMD_REG register * Command control register */ -#define SPI_CMD_REG (DR_REG_SPI_BASE + 0x0) +#define SPI_CMD_REG(i) (DR_REG_SPI_BASE(i) + 0x0) /** SPI_CONF_BITLEN : R/W; bitpos: [17:0]; default: 0; * Configures the SPI_CLK cycles of SPI CONF state. * Measurement unit: SPI_CLK clock cycle. @@ -50,7 +53,7 @@ extern "C" { /** SPI_ADDR_REG register * Address value register */ -#define SPI_ADDR_REG (DR_REG_SPI_BASE + 0x4) +#define SPI_ADDR_REG(i) (DR_REG_SPI_BASE(i) + 0x4) /** SPI_USR_ADDR_VALUE : R/W; bitpos: [31:0]; default: 0; * Configures the address to slave. * Can be configured in CONF state. @@ -63,7 +66,7 @@ extern "C" { /** SPI_CTRL_REG register * SPI control register */ -#define SPI_CTRL_REG (DR_REG_SPI_BASE + 0x8) +#define SPI_CTRL_REG(i) (DR_REG_SPI_BASE(i) + 0x8) /** SPI_DUMMY_OUT : R/W; bitpos: [3]; default: 0; * Configures whether or not to output the FSPI bus signals in DUMMY state. * 0: Not output @@ -232,7 +235,7 @@ extern "C" { /** SPI_CLOCK_REG register * SPI clock control register */ -#define SPI_CLOCK_REG (DR_REG_SPI_BASE + 0xc) +#define SPI_CLOCK_REG(i) (DR_REG_SPI_BASE(i) + 0xc) /** SPI_CLKCNT_L : R/W; bitpos: [5:0]; default: 3; * In master transfer, this field must be equal to SPI_CLKCNT_N. In slave mode, it * must be 0. Can be configured in CONF state. @@ -295,7 +298,7 @@ extern "C" { /** SPI_USER_REG register * SPI USER control register */ -#define SPI_USER_REG (DR_REG_SPI_BASE + 0x10) +#define SPI_USER_REG(i) (DR_REG_SPI_BASE(i) + 0x10) /** SPI_DOUTDIN : R/W; bitpos: [0]; default: 0; * Configures whether or not to enable full-duplex communication. * 0: Disable @@ -511,7 +514,7 @@ extern "C" { /** SPI_USER1_REG register * SPI USER control register 1 */ -#define SPI_USER1_REG (DR_REG_SPI_BASE + 0x14) +#define SPI_USER1_REG(i) (DR_REG_SPI_BASE(i) + 0x14) /** SPI_USR_DUMMY_CYCLELEN : R/W; bitpos: [7:0]; default: 7; * Configures the length of DUMMY state. * Measurement unit: SPI_CLK clock cycles. @@ -562,7 +565,7 @@ extern "C" { /** SPI_USER2_REG register * SPI USER control register 2 */ -#define SPI_USER2_REG (DR_REG_SPI_BASE + 0x18) +#define SPI_USER2_REG(i) (DR_REG_SPI_BASE(i) + 0x18) /** SPI_USR_COMMAND_VALUE : R/W; bitpos: [15:0]; default: 0; * Configures the command value. * Can be configured in CONF state. @@ -593,7 +596,7 @@ extern "C" { /** SPI_MS_DLEN_REG register * SPI data bit length control register */ -#define SPI_MS_DLEN_REG (DR_REG_SPI_BASE + 0x1c) +#define SPI_MS_DLEN_REG(i) (DR_REG_SPI_BASE(i) + 0x1c) /** SPI_MS_DATA_BITLEN : R/W; bitpos: [17:0]; default: 0; * Configures the data bit length of SPI transfer in DMA-controlled master transfer or * in CPU-controlled master transfer. Or configures the bit length of SPI RX transfer @@ -608,7 +611,7 @@ extern "C" { /** SPI_MISC_REG register * SPI misc register */ -#define SPI_MISC_REG (DR_REG_SPI_BASE + 0x20) +#define SPI_MISC_REG(i) (DR_REG_SPI_BASE(i) + 0x20) /** SPI_CS0_DIS : R/W; bitpos: [0]; default: 0; * Configures whether or not to disable SPI_CS$n pin. * 0: SPI_CS$n signal is from/to SPI_CS$n pin. @@ -773,7 +776,7 @@ extern "C" { /** SPI_DIN_MODE_REG register * SPI input delay mode configuration */ -#define SPI_DIN_MODE_REG (DR_REG_SPI_BASE + 0x24) +#define SPI_DIN_MODE_REG(i) (DR_REG_SPI_BASE(i) + 0x24) /** SPI_DIN0_MODE : R/W; bitpos: [1:0]; default: 0; * Configures the input mode for FSPID signal. * 0: Input without delay @@ -882,7 +885,7 @@ extern "C" { /** SPI_DIN_NUM_REG register * SPI input delay number configuration */ -#define SPI_DIN_NUM_REG (DR_REG_SPI_BASE + 0x28) +#define SPI_DIN_NUM_REG(i) (DR_REG_SPI_BASE(i) + 0x28) /** SPI_DIN0_NUM : R/W; bitpos: [1:0]; default: 0; * Configures the delays to input signal FSPID based on the setting of SPI_DIN0_MODE. * 0: Delayed by 1 clock cycle @@ -967,7 +970,7 @@ extern "C" { /** SPI_DOUT_MODE_REG register * SPI output delay mode configuration */ -#define SPI_DOUT_MODE_REG (DR_REG_SPI_BASE + 0x2c) +#define SPI_DOUT_MODE_REG(i) (DR_REG_SPI_BASE(i) + 0x2c) /** SPI_DOUT0_MODE : R/W; bitpos: [0]; default: 0; * Configures the output mode for FSPID signal. * 0: Output without delay @@ -1057,7 +1060,7 @@ extern "C" { /** SPI_DMA_CONF_REG register * SPI DMA control register */ -#define SPI_DMA_CONF_REG (DR_REG_SPI_BASE + 0x30) +#define SPI_DMA_CONF_REG(i) (DR_REG_SPI_BASE(i) + 0x30) /** SPI_DMA_OUTFIFO_EMPTY : RO; bitpos: [0]; default: 1; * Represents whether or not the DMA TX FIFO is ready for sending data. * 0: Ready @@ -1178,7 +1181,7 @@ extern "C" { /** SPI_DMA_INT_ENA_REG register * SPI interrupt enable register */ -#define SPI_DMA_INT_ENA_REG (DR_REG_SPI_BASE + 0x34) +#define SPI_DMA_INT_ENA_REG(i) (DR_REG_SPI_BASE(i) + 0x34) /** SPI_DMA_INFIFO_FULL_ERR_INT_ENA : R/W; bitpos: [0]; default: 0; * Write 1 to enable SPI_DMA_INFIFO_FULL_ERR_INT interrupt. */ @@ -1330,7 +1333,7 @@ extern "C" { /** SPI_DMA_INT_CLR_REG register * SPI interrupt clear register */ -#define SPI_DMA_INT_CLR_REG (DR_REG_SPI_BASE + 0x38) +#define SPI_DMA_INT_CLR_REG(i) (DR_REG_SPI_BASE(i) + 0x38) /** SPI_DMA_INFIFO_FULL_ERR_INT_CLR : WT; bitpos: [0]; default: 0; * Write 1 to clear SPI_DMA_INFIFO_FULL_ERR_INT interrupt. */ @@ -1482,7 +1485,7 @@ extern "C" { /** SPI_DMA_INT_RAW_REG register * SPI interrupt raw register */ -#define SPI_DMA_INT_RAW_REG (DR_REG_SPI_BASE + 0x3c) +#define SPI_DMA_INT_RAW_REG(i) (DR_REG_SPI_BASE(i) + 0x3c) /** SPI_DMA_INFIFO_FULL_ERR_INT_RAW : R/WTC/SS; bitpos: [0]; default: 0; * The raw interrupt status of SPI_DMA_INFIFO_FULL_ERR_INT interrupt. */ @@ -1638,7 +1641,7 @@ extern "C" { /** SPI_DMA_INT_ST_REG register * SPI interrupt status register */ -#define SPI_DMA_INT_ST_REG (DR_REG_SPI_BASE + 0x40) +#define SPI_DMA_INT_ST_REG(i) (DR_REG_SPI_BASE(i) + 0x40) /** SPI_DMA_INFIFO_FULL_ERR_INT_ST : RO; bitpos: [0]; default: 0; * The interrupt status of SPI_DMA_INFIFO_FULL_ERR_INT interrupt. */ @@ -1790,7 +1793,7 @@ extern "C" { /** SPI_DMA_INT_SET_REG register * SPI interrupt software set register */ -#define SPI_DMA_INT_SET_REG (DR_REG_SPI_BASE + 0x44) +#define SPI_DMA_INT_SET_REG(i) (DR_REG_SPI_BASE(i) + 0x44) /** SPI_DMA_INFIFO_FULL_ERR_INT_SET : WT; bitpos: [0]; default: 0; * Write 1 to set SPI_DMA_INFIFO_FULL_ERR_INT interrupt. */ @@ -1942,7 +1945,7 @@ extern "C" { /** SPI_W0_REG register * SPI CPU-controlled buffer0 */ -#define SPI_W0_REG (DR_REG_SPI_BASE + 0x98) +#define SPI_W0_REG(i) (DR_REG_SPI_BASE(i) + 0x98) /** SPI_BUF0 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -1954,7 +1957,7 @@ extern "C" { /** SPI_W1_REG register * SPI CPU-controlled buffer1 */ -#define SPI_W1_REG (DR_REG_SPI_BASE + 0x9c) +#define SPI_W1_REG(i) (DR_REG_SPI_BASE(i) + 0x9c) /** SPI_BUF1 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -1966,7 +1969,7 @@ extern "C" { /** SPI_W2_REG register * SPI CPU-controlled buffer2 */ -#define SPI_W2_REG (DR_REG_SPI_BASE + 0xa0) +#define SPI_W2_REG(i) (DR_REG_SPI_BASE(i) + 0xa0) /** SPI_BUF2 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -1978,7 +1981,7 @@ extern "C" { /** SPI_W3_REG register * SPI CPU-controlled buffer3 */ -#define SPI_W3_REG (DR_REG_SPI_BASE + 0xa4) +#define SPI_W3_REG(i) (DR_REG_SPI_BASE(i) + 0xa4) /** SPI_BUF3 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -1990,7 +1993,7 @@ extern "C" { /** SPI_W4_REG register * SPI CPU-controlled buffer4 */ -#define SPI_W4_REG (DR_REG_SPI_BASE + 0xa8) +#define SPI_W4_REG(i) (DR_REG_SPI_BASE(i) + 0xa8) /** SPI_BUF4 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2002,7 +2005,7 @@ extern "C" { /** SPI_W5_REG register * SPI CPU-controlled buffer5 */ -#define SPI_W5_REG (DR_REG_SPI_BASE + 0xac) +#define SPI_W5_REG(i) (DR_REG_SPI_BASE(i) + 0xac) /** SPI_BUF5 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2014,7 +2017,7 @@ extern "C" { /** SPI_W6_REG register * SPI CPU-controlled buffer6 */ -#define SPI_W6_REG (DR_REG_SPI_BASE + 0xb0) +#define SPI_W6_REG(i) (DR_REG_SPI_BASE(i) + 0xb0) /** SPI_BUF6 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2026,7 +2029,7 @@ extern "C" { /** SPI_W7_REG register * SPI CPU-controlled buffer7 */ -#define SPI_W7_REG (DR_REG_SPI_BASE + 0xb4) +#define SPI_W7_REG(i) (DR_REG_SPI_BASE(i) + 0xb4) /** SPI_BUF7 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2038,7 +2041,7 @@ extern "C" { /** SPI_W8_REG register * SPI CPU-controlled buffer8 */ -#define SPI_W8_REG (DR_REG_SPI_BASE + 0xb8) +#define SPI_W8_REG(i) (DR_REG_SPI_BASE(i) + 0xb8) /** SPI_BUF8 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2050,7 +2053,7 @@ extern "C" { /** SPI_W9_REG register * SPI CPU-controlled buffer9 */ -#define SPI_W9_REG (DR_REG_SPI_BASE + 0xbc) +#define SPI_W9_REG(i) (DR_REG_SPI_BASE(i) + 0xbc) /** SPI_BUF9 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2062,7 +2065,7 @@ extern "C" { /** SPI_W10_REG register * SPI CPU-controlled buffer10 */ -#define SPI_W10_REG (DR_REG_SPI_BASE + 0xc0) +#define SPI_W10_REG(i) (DR_REG_SPI_BASE(i) + 0xc0) /** SPI_BUF10 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2074,7 +2077,7 @@ extern "C" { /** SPI_W11_REG register * SPI CPU-controlled buffer11 */ -#define SPI_W11_REG (DR_REG_SPI_BASE + 0xc4) +#define SPI_W11_REG(i) (DR_REG_SPI_BASE(i) + 0xc4) /** SPI_BUF11 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2086,7 +2089,7 @@ extern "C" { /** SPI_W12_REG register * SPI CPU-controlled buffer12 */ -#define SPI_W12_REG (DR_REG_SPI_BASE + 0xc8) +#define SPI_W12_REG(i) (DR_REG_SPI_BASE(i) + 0xc8) /** SPI_BUF12 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2098,7 +2101,7 @@ extern "C" { /** SPI_W13_REG register * SPI CPU-controlled buffer13 */ -#define SPI_W13_REG (DR_REG_SPI_BASE + 0xcc) +#define SPI_W13_REG(i) (DR_REG_SPI_BASE(i) + 0xcc) /** SPI_BUF13 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2110,7 +2113,7 @@ extern "C" { /** SPI_W14_REG register * SPI CPU-controlled buffer14 */ -#define SPI_W14_REG (DR_REG_SPI_BASE + 0xd0) +#define SPI_W14_REG(i) (DR_REG_SPI_BASE(i) + 0xd0) /** SPI_BUF14 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2122,7 +2125,7 @@ extern "C" { /** SPI_W15_REG register * SPI CPU-controlled buffer15 */ -#define SPI_W15_REG (DR_REG_SPI_BASE + 0xd4) +#define SPI_W15_REG(i) (DR_REG_SPI_BASE(i) + 0xd4) /** SPI_BUF15 : R/W/SS; bitpos: [31:0]; default: 0; * 32-bit data buffer $n. */ @@ -2134,7 +2137,7 @@ extern "C" { /** SPI_SLAVE_REG register * SPI slave control register */ -#define SPI_SLAVE_REG (DR_REG_SPI_BASE + 0xe0) +#define SPI_SLAVE_REG(i) (DR_REG_SPI_BASE(i) + 0xe0) /** SPI_CLK_MODE : R/W; bitpos: [1:0]; default: 0; * Configures SPI clock mode. * 0: SPI clock is off when CS becomes inactive. @@ -2265,7 +2268,7 @@ extern "C" { /** SPI_SLAVE1_REG register * SPI slave control register 1 */ -#define SPI_SLAVE1_REG (DR_REG_SPI_BASE + 0xe4) +#define SPI_SLAVE1_REG(i) (DR_REG_SPI_BASE(i) + 0xe4) /** SPI_SLV_DATA_BITLEN : R/W/SS; bitpos: [17:0]; default: 0; * Configures the transferred data bit length in SPI slave full-/half-duplex modes. */ @@ -2291,7 +2294,7 @@ extern "C" { /** SPI_CLK_GATE_REG register * SPI module clock and register clock control */ -#define SPI_CLK_GATE_REG (DR_REG_SPI_BASE + 0xe8) +#define SPI_CLK_GATE_REG(i) (DR_REG_SPI_BASE(i) + 0xe8) /** SPI_CLK_EN : R/W; bitpos: [0]; default: 0; * Configures whether or not to enable clock gate. * 0: Disable @@ -2320,7 +2323,7 @@ extern "C" { /** SPI_DATE_REG register * Version control */ -#define SPI_DATE_REG (DR_REG_SPI_BASE + 0xf0) +#define SPI_DATE_REG(i) (DR_REG_SPI_BASE(i) + 0xf0) /** SPI_DATE : R/W; bitpos: [27:0]; default: 37761424; * Version control register. */ diff --git a/components/soc/esp32h21/spi_periph.c b/components/soc/esp32h21/spi_periph.c new file mode 100644 index 0000000000..65928c8df2 --- /dev/null +++ b/components/soc/esp32h21/spi_periph.c @@ -0,0 +1,85 @@ +/* + * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include "soc/spi_periph.h" + +/* + Bunch of constants for every SPI peripheral: GPIO signals, irqs, hw addr of registers etc +*/ +const spi_signal_conn_t spi_periph_signal[SOC_SPI_PERIPH_NUM] = { + { + // MSPI has dedicated iomux pins + }, { + .spiclk_out = FSPICLK_OUT_IDX, + .spiclk_in = FSPICLK_IN_IDX, + .spid_out = FSPID_OUT_IDX, + .spiq_out = FSPIQ_OUT_IDX, + .spiwp_out = FSPIWP_OUT_IDX, + .spihd_out = FSPIHD_OUT_IDX, + .spid_in = FSPID_IN_IDX, + .spiq_in = FSPIQ_IN_IDX, + .spiwp_in = FSPIWP_IN_IDX, + .spihd_in = FSPIHD_IN_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, + .spiq_iomux_pin = SPI2_IOMUX_PIN_NUM_MISO, + .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_GPSPI2_INTR_SOURCE, + .irq_dma = -1, + .hw = &GPSPI2, + .func = SPI2_FUNC_NUM, + } +}; + +/** + * Backup registers in Light sleep: (total cnt 29) + * + * cmd + * addr + * ctrl + * clock + * user + * user1 + * user2 + * ms_dlen + * misc + * dma_conf + * dma_int_ena + * data_buf[0-15] // slave driver only + * slave + * slave1 + */ +#define SPI_RETENTION_REGS_CNT 29 +static const uint32_t spi_regs_map[4] = {0x31ff, 0x33fffc0, 0x0, 0x0}; +#define SPI_REG_RETENTION_ENTRIES(num) { \ + [0] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_GPSPI_LINK(0), \ + DR_REG_SPI_BASE(num), DR_REG_SPI_BASE(num), \ + SPI_RETENTION_REGS_CNT, 0, 0, \ + spi_regs_map[0], spi_regs_map[1], \ + spi_regs_map[2], spi_regs_map[3]), \ + .owner = ENTRY(0) | ENTRY(2) }, \ + /* Additional interrupt setting is required by idf SPI drivers after register recovered */ \ + [1] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_GPSPI_LINK(1), \ + SPI_DMA_INT_SET_REG(num), \ + SPI_TRANS_DONE_INT_SET | SPI_DMA_SEG_TRANS_DONE_INT_SET | SPI_SLV_CMD7_INT_SET | SPI_SLV_CMD8_INT_SET , \ + UINT32_MAX, 1, 0), \ + .owner = ENTRY(0) | ENTRY(2) }, \ +} + +static const regdma_entries_config_t spi2_regs_retention[] = SPI_REG_RETENTION_ENTRIES(2); // '2' for GPSPI2 + +const spi_reg_retention_info_t spi_reg_retention_info[SOC_SPI_PERIPH_NUM - 1] = { // '-1' to except mspi + { + .module_id = SLEEP_RETENTION_MODULE_GPSPI2, + .entry_array = spi2_regs_retention, + .array_size = ARRAY_SIZE(spi2_regs_retention), + }, +}; diff --git a/components/soc/esp32h4/include/soc/system_intr.h b/components/soc/esp32h4/include/soc/system_intr.h index 33fed484b2..add4322dc0 100644 --- a/components/soc/esp32h4/include/soc/system_intr.h +++ b/components/soc/esp32h4/include/soc/system_intr.h @@ -5,9 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_CPU_INTR_FROM_CPU_0_SOURCE #define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_CPU_INTR_FROM_CPU_1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_CPU_INTR_FROM_CPU_2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_CPU_INTR_FROM_CPU_3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_INTR_SOURCE diff --git a/components/soc/esp32p4/include/soc/system_intr.h b/components/soc/esp32p4/include/soc/system_intr.h index a681733c8d..9289296b49 100644 --- a/components/soc/esp32p4/include/soc/system_intr.h +++ b/components/soc/esp32p4/include/soc/system_intr.h @@ -5,9 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_FROM_CPU_INTR0_SOURCE #define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_FROM_CPU_INTR1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_FROM_CPU_INTR2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_FROM_CPU_INTR3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE diff --git a/components/soc/esp32s2/include/soc/system_intr.h b/components/soc/esp32s2/include/soc/system_intr.h index 9f7be40172..9289296b49 100644 --- a/components/soc/esp32s2/include/soc/system_intr.h +++ b/components/soc/esp32s2/include/soc/system_intr.h @@ -5,8 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_FROM_CPU_INTR0_SOURCE +#define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_FROM_CPU_INTR1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_FROM_CPU_INTR2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_FROM_CPU_INTR3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE diff --git a/components/soc/esp32s3/include/soc/system_intr.h b/components/soc/esp32s3/include/soc/system_intr.h index a681733c8d..9289296b49 100644 --- a/components/soc/esp32s3/include/soc/system_intr.h +++ b/components/soc/esp32s3/include/soc/system_intr.h @@ -5,9 +5,13 @@ */ #pragma once +#include "soc/interrupts.h" + // Maps misc system interrupt to hardware interrupt names #define SYS_CPU_INTR_FROM_CPU_0_SOURCE ETS_FROM_CPU_INTR0_SOURCE #define SYS_CPU_INTR_FROM_CPU_1_SOURCE ETS_FROM_CPU_INTR1_SOURCE +#define SYS_CPU_INTR_FROM_CPU_2_SOURCE ETS_FROM_CPU_INTR2_SOURCE +#define SYS_CPU_INTR_FROM_CPU_3_SOURCE ETS_FROM_CPU_INTR3_SOURCE #define SYS_TG0_WDT_INTR_SOURCE ETS_TG0_WDT_LEVEL_INTR_SOURCE #define SYS_TG1_WDT_INTR_SOURCE ETS_TG1_WDT_LEVEL_INTR_SOURCE diff --git a/docs/docs_not_updated/esp32h21.txt b/docs/docs_not_updated/esp32h21.txt index 26e4c7b414..a7c151627f 100644 --- a/docs/docs_not_updated/esp32h21.txt +++ b/docs/docs_not_updated/esp32h21.txt @@ -91,7 +91,6 @@ api-reference/protocols/esp_sdio_slave_protocol.rst api-reference/protocols/esp_https_server.rst api-reference/protocols/esp_local_ctrl.rst api-reference/protocols/esp_tls.rst -api-reference/protocols/esp_spi_slave_protocol.rst api-reference/protocols/esp_http_client.rst api-reference/protocols/mqtt.rst api-reference/protocols/esp_http_server.rst @@ -151,7 +150,6 @@ api-reference/peripherals/usb_host.rst api-reference/peripherals/clk_tree.rst api-reference/peripherals/camera_driver.rst api-reference/peripherals/touch_element.rst -api-reference/peripherals/spi_master.rst api-reference/peripherals/adc_oneshot.rst api-reference/peripherals/twai.rst api-reference/peripherals/etm.rst @@ -161,7 +159,6 @@ api-reference/peripherals/i2c_slave_v1.rst api-reference/peripherals/adc_continuous.rst api-reference/peripherals/hmac.rst api-reference/peripherals/sdspi_host.rst -api-reference/peripherals/spi_slave_hd.rst api-reference/peripherals/vad.rst api-reference/peripherals/i2s.rst api-reference/peripherals/isp.rst @@ -180,7 +177,6 @@ api-reference/peripherals/adc_calibration.rst api-reference/peripherals/lp_i2s.rst api-reference/peripherals/ecdsa.rst api-reference/peripherals/dac.rst -api-reference/peripherals/spi_slave.rst api-reference/peripherals/spi_flash/index.rst api-reference/peripherals/spi_flash/spi_flash_concurrency.rst api-reference/peripherals/spi_flash/spi_flash_override_driver.rst diff --git a/docs/en/api-reference/peripherals/spi_master.rst b/docs/en/api-reference/peripherals/spi_master.rst index dcaafa32b9..6c002fa84f 100644 --- a/docs/en/api-reference/peripherals/spi_master.rst +++ b/docs/en/api-reference/peripherals/spi_master.rst @@ -481,12 +481,12 @@ GPIO Matrix and IO_MUX .. only:: not esp32 - {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7" , esp32c5="10", esp32c61="8"} - {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9" , esp32c5="6", esp32c61="6"} - {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8" , esp32c5="7", esp32c61="7"} - {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10", esp32c5="2", esp32c61="2"} - {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6" , esp32c5="4", esp32c61="3"} - {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11", esp32c5="5", esp32c61="4"} + {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7" , esp32c5="10", esp32c61="8", esp32h21="12"} + {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9" , esp32c5="6", esp32c61="6", esp32h21="2"} + {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8" , esp32c5="7", esp32c61="7", esp32h21="3"} + {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10", esp32c5="2", esp32c61="2", esp32h21="4"} + {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6" , esp32c5="4", esp32c61="3", esp32h21="1"} + {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11", esp32c5="5", esp32c61="4", esp32h21="0"} Most of the chip's peripheral signals have a 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. @@ -532,10 +532,10 @@ The main parameter that determines the transfer speed for large transactions is Transaction Duration ^^^^^^^^^^^^^^^^^^^^ -{IDF_TARGET_TRANS_TIME_INTR_DMA:default="N/A", esp32="28", esp32s2="23", esp32c3="28", esp32s3="26", esp32c2="42", esp32c6="34", esp32h2="58", esp32p4="44", esp32c5="24", esp32c61="32"} -{IDF_TARGET_TRANS_TIME_POLL_DMA:default="N/A", esp32="10", esp32s2="9", esp32c3="10", esp32s3="11", esp32c2="17", esp32c6="17", esp32h2="28", esp32p4="27", esp32c5="15", esp32c61="17"} -{IDF_TARGET_TRANS_TIME_INTR_CPU:default="N/A", esp32="25", esp32s2="22", esp32c3="27", esp32s3="24", esp32c2="40", esp32c6="32", esp32h2="54", esp32p4="26", esp32c5="22", esp32c61="29"} -{IDF_TARGET_TRANS_TIME_POLL_CPU:default="N/A", esp32="8", esp32s2="8", esp32c3="9", esp32s3="9", esp32c2="15", esp32c6="15", esp32h2="24", esp32p4="12", esp32c5="12", esp32c61="14"} +{IDF_TARGET_MAX_TRANS_TIME_INTR_DMA:default="N/A", esp32="28", esp32s2="23", esp32c3="28", esp32s3="26", esp32c2="42", esp32c6="34", esp32h2="58", esp32p4="44", esp32c5="24", esp32c61="32"} +{IDF_TARGET_MAX_TRANS_TIME_POLL_DMA:default="N/A", esp32="10", esp32s2="9", esp32c3="10", esp32s3="11", esp32c2="17", esp32c6="17", esp32h2="28", esp32p4="27", esp32c5="15", esp32c61="17"} +{IDF_TARGET_MAX_TRANS_TIME_INTR_CPU:default="N/A", esp32="25", esp32s2="22", esp32c3="27", esp32s3="24", esp32c2="40", esp32c6="32", esp32h2="54", esp32p4="26", esp32c5="22", esp32c61="29"} +{IDF_TARGET_MAX_TRANS_TIME_POLL_CPU:default="N/A", esp32="8", esp32s2="8", esp32c3="9", esp32s3="9", esp32c2="15", esp32c6="15", esp32h2="24", esp32p4="12", esp32c5="12", esp32c61="14"} Transaction duration includes setting up SPI peripheral registers, copying data to FIFOs or setting up DMA links, and the time for SPI transactions. @@ -547,10 +547,10 @@ If DMA is enabled, setting up the linked list requires about 2 µs per transacti The typical transaction duration for one byte of data is given below. -- Interrupt Transaction via DMA: {IDF_TARGET_TRANS_TIME_INTR_DMA} µs. -- Interrupt Transaction via CPU: {IDF_TARGET_TRANS_TIME_INTR_CPU} µs. -- Polling Transaction via DMA: {IDF_TARGET_TRANS_TIME_POLL_DMA} µs. -- Polling Transaction via CPU: {IDF_TARGET_TRANS_TIME_POLL_CPU} µs. +- Interrupt Transaction via DMA: {IDF_TARGET_MAX_TRANS_TIME_INTR_DMA} µs. +- Interrupt Transaction via CPU: {IDF_TARGET_MAX_TRANS_TIME_INTR_CPU} µs. +- Polling Transaction via DMA: {IDF_TARGET_MAX_TRANS_TIME_POLL_DMA} µs. +- Polling Transaction via CPU: {IDF_TARGET_MAX_TRANS_TIME_POLL_CPU} µs. Note that these data are tested with :ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM` enabled. SPI transaction related code are placed in the internal memory. If this option is turned off (for example, for internal memory optimization), the transaction duration may be affected. diff --git a/docs/en/api-reference/peripherals/spi_slave.rst b/docs/en/api-reference/peripherals/spi_slave.rst index cd84e5ef53..32d5337f28 100644 --- a/docs/en/api-reference/peripherals/spi_slave.rst +++ b/docs/en/api-reference/peripherals/spi_slave.rst @@ -154,12 +154,12 @@ GPIO Matrix and IO_MUX .. only:: not esp32 - {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7" , esp32c5="10", esp32c61="8"} - {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9" , esp32c5="6", esp32c61="6"} - {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8" , esp32c5="7", esp32c61="7"} - {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10", esp32c5="2", esp32c61="2"} - {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6" , esp32c5="4", esp32c61="3"} - {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11", esp32c5="5", esp32c61="4"} + {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7" , esp32c5="10", esp32c61="8", esp32h21="12"} + {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9" , esp32c5="6", esp32c61="6", esp32h21="2"} + {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8" , esp32c5="7", esp32c61="7", esp32h21="3"} + {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10", esp32c5="2", esp32c61="2", esp32h21="4"} + {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6" , esp32c5="4", esp32c61="3", esp32h21="1"} + {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11", esp32c5="5", esp32c61="4", esp32h21="0"} 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. diff --git a/docs/en/api-reference/protocols/esp_spi_slave_protocol.rst b/docs/en/api-reference/protocols/esp_spi_slave_protocol.rst index 5f6dc9985b..a4f0a64819 100644 --- a/docs/en/api-reference/protocols/esp_spi_slave_protocol.rst +++ b/docs/en/api-reference/protocols/esp_spi_slave_protocol.rst @@ -14,21 +14,31 @@ ESP SPI Slave HD (Half Duplex) Mode Protocol SPI Slave Capabilities of Espressif Chips ----------------------------------------- -+------------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C2 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-C5 | ESP32-C61 | -+------------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| SPI Slave HD | N | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | -+------------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| Tohost intr | | N | N | N | N | N | N | N | N | N | -+------------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| Frhost intr | | 2 \* | 2 \* | 2 \* | 2 \* | 2 \* | 2 \* | 2 \* | 2 \* | 2 \* | -+------------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| TX DMA | | Y | Y | Y | Y | Y | Y | Y | Y | Y | -+------------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| RX DMA | | Y | Y | Y | Y | Y | Y | Y | Y | Y | -+------------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| Shared registers | | 72 | 64 | 64 | 64 | 64 | 64 | 64 | 64 | 64 | -+------------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ ++---------+------------+-----------+-----------+------+------+----------------+ +| |SPI Slave HD|Tohost intr|Frhost intr|TX DMA|RX DMA|Shared registers| ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32 | N | | | | | | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-S2 | Y(v2) | N | 2 \* | Y | Y | 72 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-C3 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-S3 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-C2 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-C6 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-H2 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-P4 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-C5 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-C61| Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-H21| Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ Introduction ------------ diff --git a/docs/zh_CN/api-reference/peripherals/spi_master.rst b/docs/zh_CN/api-reference/peripherals/spi_master.rst index facc27c9f5..beb77711c6 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_master.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_master.rst @@ -481,12 +481,12 @@ GPIO 矩阵与 IO_MUX 管脚 .. only:: not esp32 - {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7" , esp32c5="10", esp32c61="8"} - {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9" , esp32c5="6", esp32c61="6"} - {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8" , esp32c5="7", esp32c61="7"} - {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10", esp32c5="2", esp32c61="2"} - {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6" , esp32c5="4", esp32c61="3"} - {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11", esp32c5="5", esp32c61="4"} + {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7" , esp32c5="10", esp32c61="8", esp32h21="12"} + {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9" , esp32c5="6", esp32c61="6", esp32h21="2"} + {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8" , esp32c5="7", esp32c61="7", esp32h21="3"} + {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10", esp32c5="2", esp32c61="2", esp32h21="4"} + {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6" , esp32c5="4", esp32c61="3", esp32h21="1"} + {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11", esp32c5="5", esp32c61="4", esp32h21="0"} 芯片的大多数外围信号都与之专用的 IO_MUX 管脚连接,但这些信号也可以通过较不直接的 GPIO 矩阵路由到任何其他可用的管脚。只要有一个信号是通过 GPIO 矩阵路由的,那么所有的信号都将通过它路由。 @@ -532,10 +532,10 @@ GPIO 矩阵与 IO_MUX 管脚 传输事务持续时间 ^^^^^^^^^^^^^^^^^^^^ -{IDF_TARGET_TRANS_TIME_INTR_DMA:default="N/A", esp32="28", esp32s2="23", esp32c3="28", esp32s3="26", esp32c2="42", esp32c6="34", esp32h2="58", esp32p4="44", esp32c5="24", esp32c61="32"} -{IDF_TARGET_TRANS_TIME_POLL_DMA:default="N/A", esp32="10", esp32s2="9", esp32c3="10", esp32s3="11", esp32c2="17", esp32c6="17", esp32h2="28", esp32p4="27", esp32c5="15", esp32c61="17"} -{IDF_TARGET_TRANS_TIME_INTR_CPU:default="N/A", esp32="25", esp32s2="22", esp32c3="27", esp32s3="24", esp32c2="40", esp32c6="32", esp32h2="54", esp32p4="26", esp32c5="22", esp32c61="29"} -{IDF_TARGET_TRANS_TIME_POLL_CPU:default="N/A", esp32="8", esp32s2="8", esp32c3="9", esp32s3="9", esp32c2="15", esp32c6="15", esp32h2="24", esp32p4="12", esp32c5="12", esp32c61="14"} +{IDF_TARGET_MAX_TRANS_TIME_INTR_DMA:default="N/A", esp32="28", esp32s2="23", esp32c3="28", esp32s3="26", esp32c2="42", esp32c6="34", esp32h2="58", esp32p4="44", esp32c5="24", esp32c61="32"} +{IDF_TARGET_MAX_TRANS_TIME_POLL_DMA:default="N/A", esp32="10", esp32s2="9", esp32c3="10", esp32s3="11", esp32c2="17", esp32c6="17", esp32h2="28", esp32p4="27", esp32c5="15", esp32c61="17"} +{IDF_TARGET_MAX_TRANS_TIME_INTR_CPU:default="N/A", esp32="25", esp32s2="22", esp32c3="27", esp32s3="24", esp32c2="40", esp32c6="32", esp32h2="54", esp32p4="26", esp32c5="22", esp32c61="29"} +{IDF_TARGET_MAX_TRANS_TIME_POLL_CPU:default="N/A", esp32="8", esp32s2="8", esp32c3="9", esp32s3="9", esp32c2="15", esp32c6="15", esp32h2="24", esp32p4="12", esp32c5="12", esp32c61="14"} 传输事务持续时间包括设置 SPI 外设寄存器,将数据复制到 FIFO 或设置 DMA 链接,以及 SPI 传输事务时间。 @@ -547,10 +547,10 @@ GPIO 矩阵与 IO_MUX 管脚 单个字节数据的典型传输事务持续时间如下。 -- 使用 DMA 的中断传输事务:{IDF_TARGET_TRANS_TIME_INTR_DMA} µs。 -- 使用 CPU 的中断传输事务:{IDF_TARGET_TRANS_TIME_INTR_CPU} µs。 -- 使用 DMA 的轮询传输事务:{IDF_TARGET_TRANS_TIME_POLL_DMA} µs。 -- 使用 CPU 的轮询传输事务:{IDF_TARGET_TRANS_TIME_POLL_CPU} µs。 +- 使用 DMA 的中断传输事务:{IDF_TARGET_MAX_TRANS_TIME_INTR_DMA} µs。 +- 使用 CPU 的中断传输事务:{IDF_TARGET_MAX_TRANS_TIME_INTR_CPU} µs。 +- 使用 DMA 的轮询传输事务:{IDF_TARGET_MAX_TRANS_TIME_POLL_DMA} µs。 +- 使用 CPU 的轮询传输事务:{IDF_TARGET_MAX_TRANS_TIME_POLL_CPU} µs。 请注意,以上数据测试时,:ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM` 选项处于启用状态,SPI 传输事务相关的代码放置在 IRAM 中。若关闭此选项(例如为了节省 IRAM),可能影响传输事务持续时间。 diff --git a/docs/zh_CN/api-reference/peripherals/spi_slave.rst b/docs/zh_CN/api-reference/peripherals/spi_slave.rst index 8ed13474bb..96a10e550d 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_slave.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_slave.rst @@ -154,12 +154,12 @@ GPIO 交换矩阵和 IO_MUX .. only:: not esp32 - {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7" , esp32c5="10", esp32c61="8"} - {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9" , esp32c5="6", esp32c61="6"} - {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8" , esp32c5="7", esp32c61="7"} - {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10", esp32c5="2", esp32c61="2"} - {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6" , esp32c5="4", esp32c61="3"} - {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11", esp32c5="5", esp32c61="4"} + {IDF_TARGET_SPI2_IOMUX_PIN_CS:default="N/A", esp32s2="10", esp32s3="10", esp32c2="10", esp32c3="10", esp32c6="16", esp32h2="1", esp32p4="7" , esp32c5="10", esp32c61="8", esp32h21="12"} + {IDF_TARGET_SPI2_IOMUX_PIN_CLK:default="N/A", esp32s2="12", esp32s3="12", esp32c2="6", esp32c3="6", esp32c6="6", esp32h2="4", esp32p4="9" , esp32c5="6", esp32c61="6", esp32h21="2"} + {IDF_TARGET_SPI2_IOMUX_PIN_MOSI:default="N/A", esp32s2="11" esp32s3="11", esp32c2="7" esp32c3="7", esp32c6="7", esp32h2="5", esp32p4="8" , esp32c5="7", esp32c61="7", esp32h21="3"} + {IDF_TARGET_SPI2_IOMUX_PIN_MISO:default="N/A", esp32s2="13" esp32s3="13", esp32c2="2" esp32c3="2", esp32c6="2", esp32h2="0", esp32p4="10", esp32c5="2", esp32c61="2", esp32h21="4"} + {IDF_TARGET_SPI2_IOMUX_PIN_HD:default="N/A", esp32s2="9" esp32s3="9", esp32c2="4" esp32c3="4", esp32c6="4", esp32h2="3", esp32p4="6" , esp32c5="4", esp32c61="3", esp32h21="1"} + {IDF_TARGET_SPI2_IOMUX_PIN_WP:default="N/A", esp32s2="14" esp32s3="14", esp32c2="5" esp32c3="5", esp32c6="5", esp32h2="2", esp32p4="11", esp32c5="5", esp32c61="4", esp32h21="0"} {IDF_TARGET_NAME} 的大多数外设信号都直接连接到其专用的 IO_MUX 管脚。不过,也可以使用 GPIO 交换矩阵,将信号路由到任何可用的其他管脚。如果通过 GPIO 交换矩阵路由了至少一个信号,则所有信号都将通过 GPIO 交换矩阵路由。 diff --git a/docs/zh_CN/api-reference/protocols/esp_serial_slave_link.rst b/docs/zh_CN/api-reference/protocols/esp_serial_slave_link.rst index 4ca40ea586..fa393d2fbe 100644 --- a/docs/zh_CN/api-reference/protocols/esp_serial_slave_link.rst +++ b/docs/zh_CN/api-reference/protocols/esp_serial_slave_link.rst @@ -6,7 +6,7 @@ ESP 串行从机链路 概述 ---- -乐鑫有多款芯片可用作从机的芯片。这些从机依赖于一些通用总线,并在总线上实现了各自的通信协议。 ``esp_serial_slave_link`` 组件能让主机通过总线驱动和相应的协议与 ESP 从机进行通信。 +乐鑫有多款芯片可用作从机。这些从机依赖于一些通用总线,并在总线上实现了各自的通信协议。 ``esp_serial_slave_link`` 组件能让主机通过总线驱动和相应的协议与 ESP 从机进行通信。 ``esp_serial_slave_link`` 设备初始化完成后,应用程序就能通过它与 ESP 从机方便地通信。 diff --git a/docs/zh_CN/api-reference/protocols/esp_spi_slave_protocol.rst b/docs/zh_CN/api-reference/protocols/esp_spi_slave_protocol.rst index f81f5b15a7..d7af6ae7a3 100644 --- a/docs/zh_CN/api-reference/protocols/esp_spi_slave_protocol.rst +++ b/docs/zh_CN/api-reference/protocols/esp_spi_slave_protocol.rst @@ -14,21 +14,31 @@ ESP SPI 从机 HD(半双工)模式协议 乐鑫芯片的 SPI 从机功能支持概况 --------------------------------- -+-------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| | ESP32 | ESP32-S2 | ESP32-C3 | ESP32-S3 | ESP32-C2 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-C5 | ESP32-C61 | -+-------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| SPI 从机 HD | N | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | Y (v2) | -+-------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| Tohost intr | | N | N | N | N | N | N | N | N | N | -+-------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| Frhost intr | | 2 * | 2 * | 2 * | 2 * | 2 * | 2 * | 2 \* | 2 \* | 2 \* | -+-------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| TX DMA | | Y | Y | Y | Y | Y | Y | Y | Y | Y | -+-------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| RX DMA | | Y | Y | Y | Y | Y | Y | Y | Y | Y | -+-------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ -| 共享寄存器 | | 72 | 64 | 64 | 64 | 64 | 64 | 64 | 64 | 64 | -+-------------+-------+----------+----------+----------+----------+----------+----------+----------+----------+-----------+ ++---------+------------+-----------+-----------+------+------+----------------+ +| |SPI Slave HD|Tohost intr|Frhost intr|TX DMA|RX DMA|Shared registers| ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32 | N | | | | | | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-S2 | Y(v2) | N | 2 \* | Y | Y | 72 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-C3 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-S3 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-C2 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-C6 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-H2 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-P4 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-C5 | Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-C61| Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ +|ESP32-H21| Y(v2) | N | 2 \* | Y | Y | 64 | ++---------+------------+-----------+-----------+------+------+----------------+ 概述 ---- diff --git a/examples/get-started/blink/README.md b/examples/get-started/blink/README.md index 5202bf99e9..3c43823977 100644 --- a/examples/get-started/blink/README.md +++ b/examples/get-started/blink/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | # Blink Example diff --git a/examples/peripherals/lcd/spi_lcd_touch/README.md b/examples/peripherals/lcd/spi_lcd_touch/README.md index 764ff2b43e..b984c0e5e2 100644 --- a/examples/peripherals/lcd/spi_lcd_touch/README.md +++ b/examples/peripherals/lcd/spi_lcd_touch/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | # SPI LCD and Touch Panel Example diff --git a/examples/peripherals/lcd/tjpgd/README.md b/examples/peripherals/lcd/tjpgd/README.md index eba501a6b4..d037c62190 100644 --- a/examples/peripherals/lcd/tjpgd/README.md +++ b/examples/peripherals/lcd/tjpgd/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | ## LCD tjpgd example diff --git a/examples/peripherals/spi_master/hd_eeprom/README.md b/examples/peripherals/spi_master/hd_eeprom/README.md index 90b0c09cac..4bb5ad1c11 100644 --- a/examples/peripherals/spi_master/hd_eeprom/README.md +++ b/examples/peripherals/spi_master/hd_eeprom/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | ## SPI master half duplex EEPROM example diff --git a/examples/peripherals/spi_master/lcd/README.md b/examples/peripherals/spi_master/lcd/README.md index eb8d47f23f..1ff6cb5768 100644 --- a/examples/peripherals/spi_master/lcd/README.md +++ b/examples/peripherals/spi_master/lcd/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | # SPI Host Driver Example diff --git a/examples/peripherals/spi_slave/README.md b/examples/peripherals/spi_slave/README.md index 9245cff3dd..44281db7d2 100644 --- a/examples/peripherals/spi_slave/README.md +++ b/examples/peripherals/spi_slave/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | ## SPI slave example diff --git a/examples/peripherals/spi_slave_hd/append_mode/master/README.md b/examples/peripherals/spi_slave_hd/append_mode/master/README.md index 37250b1fff..ea1cb7ec8f 100644 --- a/examples/peripherals/spi_slave_hd/append_mode/master/README.md +++ b/examples/peripherals/spi_slave_hd/append_mode/master/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | See README.md in the parent directory diff --git a/examples/peripherals/spi_slave_hd/append_mode/slave/README.md b/examples/peripherals/spi_slave_hd/append_mode/slave/README.md index 37250b1fff..ea1cb7ec8f 100644 --- a/examples/peripherals/spi_slave_hd/append_mode/slave/README.md +++ b/examples/peripherals/spi_slave_hd/append_mode/slave/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | See README.md in the parent directory diff --git a/examples/peripherals/spi_slave_hd/segment_mode/seg_master/README.md b/examples/peripherals/spi_slave_hd/segment_mode/seg_master/README.md index 37250b1fff..ea1cb7ec8f 100644 --- a/examples/peripherals/spi_slave_hd/segment_mode/seg_master/README.md +++ b/examples/peripherals/spi_slave_hd/segment_mode/seg_master/README.md @@ -1,4 +1,4 @@ -| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | See README.md in the parent directory diff --git a/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/README.md b/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/README.md index cc9654f295..ffceaeb158 100644 --- a/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/README.md +++ b/examples/peripherals/spi_slave_hd/segment_mode/seg_slave/README.md @@ -1,2 +1,2 @@ -| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | diff --git a/examples/storage/sd_card/sdspi/README.md b/examples/storage/sd_card/sdspi/README.md index b7904e805e..52dba04b62 100644 --- a/examples/storage/sd_card/sdspi/README.md +++ b/examples/storage/sd_card/sdspi/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | # SD Card example (SDSPI)