mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-02 20:24:32 +02:00
Merge branch 'feat/h21_spi_driver_support' into 'master'
feat(driver_spi): h21 spi driver support Closes IDF-11583 and IDF-11587 See merge request espressif/esp-idf!37442
This commit is contained in:
@@ -282,11 +282,18 @@ void spitest_gpio_input_sel(uint32_t gpio_num, int func, uint32_t signal_idx);
|
||||
|
||||
//Note this cs_num is the ID of the connected devices' ID, e.g. if 2 devices are connected to the bus,
|
||||
//then the cs_num of the 1st and 2nd devices are 0 and 1 respectively.
|
||||
void same_pin_func_sel(spi_bus_config_t bus, spi_device_interface_config_t dev, uint8_t cs_num);
|
||||
//Enable `soft_master` to connect to soft spi master instead of hardware master.
|
||||
void same_pin_func_sel(spi_bus_config_t bus, uint8_t cs_pin, uint8_t cs_dev_id, bool soft_master);
|
||||
|
||||
// Soft simulated spi master host for slave testing
|
||||
// TODO: `speed_hz` is not implemented yet, temp to max 500Hz
|
||||
// `speed_hz` max 500kHz
|
||||
// TODO: mode 0 only
|
||||
void spi_master_trans_impl_gpio(spi_bus_config_t bus, uint8_t cs_pin, uint8_t speed_hz, void *tx, void *rx, uint32_t len);
|
||||
void spi_master_trans_impl_gpio(spi_bus_config_t bus, uint8_t cs_pin, uint32_t speed_hz, uint8_t *tx, uint8_t *rx, uint32_t len, bool hold_cs);
|
||||
|
||||
// Send/Receive long buffer by soft spi master in segments to the slave_hd through its DMA, refer to `essl_spi_wrdma/essl_spi_rddma`
|
||||
void essl_sspi_hd_dma_trans_seg(spi_bus_config_t bus, uint8_t cs_pin, uint32_t speed_hz, bool is_rx, void *buffer, int len, int seg_len);
|
||||
|
||||
// Write/Read the shared buffer of the slave_hd by soft spi master, refer to `essl_spi_wrbuf/essl_spi_rdbuf`
|
||||
void essl_sspi_hd_buffer_trans(spi_bus_config_t bus, uint8_t cs_pin, uint32_t speed_hz, spi_command_t cmd, uint8_t addr, void *buffer, uint32_t len);
|
||||
|
||||
#endif //_TEST_COMMON_SPI_H_
|
||||
|
@@ -9,6 +9,7 @@
|
||||
#include "driver/gpio.h"
|
||||
#include "esp_private/gpio.h"
|
||||
#include "hal/gpio_hal.h"
|
||||
#include "hal/spi_ll.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
|
||||
int test_freq_default[] = TEST_FREQ_DEFAULT();
|
||||
@@ -232,49 +233,81 @@ void spitest_gpio_input_sel(uint32_t gpio_num, int func, uint32_t signal_idx)
|
||||
esp_rom_gpio_connect_in_signal(gpio_num, signal_idx, 0);
|
||||
}
|
||||
|
||||
//Note this cs_dev_id is the ID of the connected devices' ID, e.g. if 2 devices are connected to the bus,
|
||||
//then the cs_dev_id of the 1st and 2nd devices are 0 and 1 respectively.
|
||||
void same_pin_func_sel(spi_bus_config_t bus, spi_device_interface_config_t dev, uint8_t cs_dev_id)
|
||||
void same_pin_func_sel(spi_bus_config_t bus, uint8_t cs_pin, uint8_t cs_dev_id, bool soft_master)
|
||||
{
|
||||
spitest_gpio_output_sel(bus.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
|
||||
spitest_gpio_output_sel(bus.mosi_io_num, FUNC_GPIO, soft_master ? SIG_GPIO_OUT_IDX : spi_periph_signal[TEST_SPI_HOST].spid_out);
|
||||
spitest_gpio_input_sel(bus.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spid_in);
|
||||
|
||||
spitest_gpio_output_sel(bus.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
|
||||
spitest_gpio_input_sel(bus.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiq_in);
|
||||
spitest_gpio_input_sel(bus.miso_io_num, FUNC_GPIO, soft_master ? SIG_GPIO_OUT_IDX : spi_periph_signal[TEST_SPI_HOST].spiq_in);
|
||||
|
||||
spitest_gpio_output_sel(dev.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[cs_dev_id]);
|
||||
spitest_gpio_input_sel(dev.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spics_in);
|
||||
gpio_set_level(cs_pin, 1); //ensure CS is inactive when select to soft_master and before transaction start
|
||||
spitest_gpio_output_sel(cs_pin, FUNC_GPIO, soft_master ? SIG_GPIO_OUT_IDX : spi_periph_signal[TEST_SPI_HOST].spics_out[cs_dev_id]);
|
||||
spitest_gpio_input_sel(cs_pin, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spics_in);
|
||||
|
||||
spitest_gpio_output_sel(bus.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
|
||||
spitest_gpio_output_sel(bus.sclk_io_num, FUNC_GPIO, soft_master ? SIG_GPIO_OUT_IDX : spi_periph_signal[TEST_SPI_HOST].spiclk_out);
|
||||
spitest_gpio_input_sel(bus.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiclk_in);
|
||||
}
|
||||
|
||||
void spi_master_trans_impl_gpio(spi_bus_config_t bus, uint8_t cs_pin, uint8_t speed_hz, void *tx, void *rx, uint32_t len)
|
||||
#define GPIO_MAX_FREQ 500*1000 //max of soft spi clock at delay(0)
|
||||
void spi_master_trans_impl_gpio(spi_bus_config_t bus, uint8_t cs_pin, uint32_t speed_hz, uint8_t *tx, uint8_t *rx, uint32_t len, bool hold_cs)
|
||||
{
|
||||
uint8_t *u8_tx = tx, *u8_rx = rx;
|
||||
gpio_set_level(cs_pin, 1); //ensure CS is inactive before transaction start
|
||||
esp_rom_gpio_connect_out_signal(cs_pin, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_out_signal(bus.sclk_io_num, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_out_signal(bus.mosi_io_num, SIG_GPIO_OUT_IDX, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(bus.miso_io_num, SIG_GPIO_OUT_IDX, 0);
|
||||
gpio_dev_t *hw = GPIO_LL_GET_HW(0);
|
||||
uint32_t half_duty_us = speed_hz ? ((GPIO_MAX_FREQ + speed_hz / 2) / speed_hz / 2) : 0;
|
||||
|
||||
gpio_set_level(cs_pin, 0);
|
||||
vTaskDelay(1); // cs_ena_pre_trans
|
||||
gpio_ll_set_level(hw, cs_pin, 0);
|
||||
for (uint32_t index = 0; index < len; index ++) {
|
||||
uint8_t rx_data = 0;
|
||||
for (uint8_t bit = 0x80; bit > 0; bit >>= 1) {
|
||||
// mode 0, output data first
|
||||
gpio_set_level(bus.mosi_io_num, (u8_tx) ? (u8_tx[index] & bit) : 0);
|
||||
vTaskDelay(1);
|
||||
gpio_set_level(bus.sclk_io_num, 1);
|
||||
gpio_ll_set_level(hw, bus.mosi_io_num, (tx) ? (tx[index] & bit) : 0);
|
||||
esp_rom_delay_us(half_duty_us);
|
||||
rx_data <<= 1;
|
||||
rx_data |= gpio_get_level(bus.miso_io_num);
|
||||
vTaskDelay(1);
|
||||
gpio_set_level(bus.sclk_io_num, 0);
|
||||
gpio_ll_set_level(hw, bus.sclk_io_num, 1);
|
||||
esp_rom_delay_us(half_duty_us);
|
||||
gpio_ll_set_level(hw, bus.sclk_io_num, 0);
|
||||
}
|
||||
if (u8_rx) {
|
||||
u8_rx[index] = rx_data;
|
||||
if (rx) {
|
||||
rx[index] = rx_data;
|
||||
}
|
||||
}
|
||||
gpio_set_level(cs_pin, 1);
|
||||
if (!hold_cs) {
|
||||
gpio_ll_set_level(hw, cs_pin, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#if SOC_SPI_SUPPORT_SLAVE_HD_VER2
|
||||
void essl_sspi_hd_dma_trans_seg(spi_bus_config_t bus, uint8_t cs_pin, uint32_t speed_hz, bool is_rx, void *buffer, int len, int seg_len)
|
||||
{
|
||||
uint8_t cmd_addr_dummy[3] = {0, 0, 0};
|
||||
uint8_t *tx = is_rx ? NULL : buffer;
|
||||
uint8_t *rx = is_rx ? buffer : NULL;
|
||||
|
||||
seg_len = (seg_len > 0) ? seg_len : len;
|
||||
cmd_addr_dummy[0] = spi_ll_get_slave_hd_base_command(is_rx ? SPI_CMD_HD_RDDMA : SPI_CMD_HD_WRDMA);
|
||||
while (len > 0) {
|
||||
spi_master_trans_impl_gpio(bus, cs_pin, speed_hz, cmd_addr_dummy, NULL, sizeof(cmd_addr_dummy), true);
|
||||
|
||||
int send_len = (seg_len <= len) ? seg_len : len;
|
||||
spi_master_trans_impl_gpio(bus, cs_pin, speed_hz, tx, rx, send_len, false);
|
||||
len -= send_len;
|
||||
tx += tx ? send_len : 0;
|
||||
rx += rx ? send_len : 0;
|
||||
}
|
||||
|
||||
cmd_addr_dummy[0] = spi_ll_get_slave_hd_base_command(is_rx ? SPI_CMD_HD_INT0 : SPI_CMD_HD_WR_END);
|
||||
spi_master_trans_impl_gpio(bus, cs_pin, speed_hz, cmd_addr_dummy, NULL, sizeof(cmd_addr_dummy), false);
|
||||
}
|
||||
|
||||
void essl_sspi_hd_buffer_trans(spi_bus_config_t bus, uint8_t cs_pin, uint32_t speed_hz, spi_command_t cmd, uint8_t addr, void *buffer, uint32_t len)
|
||||
{
|
||||
uint8_t cmd_addr_dummy[3] = {0, addr, 0};
|
||||
cmd_addr_dummy[0] = spi_ll_get_slave_hd_base_command(cmd);
|
||||
uint8_t *tx = (cmd == SPI_CMD_HD_RDBUF) ? NULL : buffer;
|
||||
uint8_t *rx = (cmd == SPI_CMD_HD_RDBUF) ? buffer : NULL;
|
||||
|
||||
spi_master_trans_impl_gpio(bus, cs_pin, speed_hz, cmd_addr_dummy, NULL, sizeof(cmd_addr_dummy), true);
|
||||
spi_master_trans_impl_gpio(bus, cs_pin, speed_hz, tx, rx, len, false);
|
||||
}
|
||||
#endif //SOC_SPI_SUPPORT_SLAVE_HD_VER2
|
||||
|
@@ -15,4 +15,4 @@ from pytest_embedded_idf.utils import idf_parametrize
|
||||
)
|
||||
@idf_parametrize('target', ['esp32'], indirect=['target'])
|
||||
def test_touch_sensor_v1(dut: Dut) -> None:
|
||||
dut.run_all_single_board_cases(timeout=60)
|
||||
dut.run_all_single_board_cases(timeout=60, reset=True)
|
||||
|
@@ -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 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
@@ -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;
|
||||
|
@@ -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
|
||||
|
@@ -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 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
@@ -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);
|
||||
@@ -896,10 +901,7 @@ void test_cmd_addr(spi_slave_task_context_t *slave_context, bool lsb_first)
|
||||
TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &spi));
|
||||
|
||||
//connecting pins to two peripherals breaks the output, fix it.
|
||||
spitest_gpio_output_sel(buscfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
|
||||
spitest_gpio_output_sel(buscfg.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
|
||||
spitest_gpio_output_sel(devcfg.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
|
||||
spitest_gpio_output_sel(buscfg.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
|
||||
same_pin_func_sel(buscfg, devcfg.spics_io_num, 0, false);
|
||||
|
||||
for (int i = 0; i < 8; i++) {
|
||||
//prepare slave tx data
|
||||
@@ -1084,10 +1086,7 @@ TEST_CASE("SPI master variable dummy test", "[spi]")
|
||||
spi_slave_interface_config_t slave_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slave_cfg, SPI_DMA_DISABLED));
|
||||
|
||||
spitest_gpio_output_sel(bus_cfg.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_out);
|
||||
spitest_gpio_output_sel(bus_cfg.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out);
|
||||
spitest_gpio_output_sel(dev_cfg.spics_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spics_out[0]);
|
||||
spitest_gpio_output_sel(bus_cfg.sclk_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spiclk_out);
|
||||
same_pin_func_sel(bus_cfg, dev_cfg.spics_io_num, 0, false);
|
||||
|
||||
uint8_t data_to_send[] = {0x12, 0x34, 0x56, 0x78};
|
||||
|
||||
@@ -1130,7 +1129,7 @@ TEST_CASE("SPI master hd dma TX without RX test", "[spi]")
|
||||
spi_slave_interface_config_t slave_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slave_cfg, SPI_DMA_CH_AUTO));
|
||||
|
||||
same_pin_func_sel(bus_cfg, dev_cfg, 0);
|
||||
same_pin_func_sel(bus_cfg, dev_cfg.spics_io_num, 0, false);
|
||||
|
||||
uint32_t buf_size = 32;
|
||||
uint8_t *mst_send_buf = spi_bus_dma_memory_alloc(TEST_SPI_HOST, buf_size, 0);
|
||||
@@ -1463,7 +1462,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 +1480,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 +1500,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 +1518,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 +1829,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 +1959,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
|
||||
|
@@ -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
|
||||
|
@@ -75,7 +75,7 @@ TEST_CASE("SPI Single Board Test SIO", "[spi]")
|
||||
spi_slave_interface_config_t slv_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slv_cfg, SPI_DMA_DISABLED));
|
||||
|
||||
same_pin_func_sel(bus_cfg, dev_cfg, 0);
|
||||
same_pin_func_sel(bus_cfg, dev_cfg.spics_io_num, 0, false);
|
||||
inner_connect(bus_cfg);
|
||||
|
||||
WORD_ALIGNED_ATTR uint8_t master_rx_buffer[320];
|
||||
@@ -178,7 +178,7 @@ void test_sio_master_trans(bool sio_master_in)
|
||||
uint8_t *master_tx_max = heap_caps_calloc(TRANS_LEN * 2, 1, MALLOC_CAP_DMA);
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(master_tx_max, "malloc failed, exit.\n");
|
||||
|
||||
// write somethin to a long buffer for test long transmission
|
||||
// write something to a long buffer for test long transmission
|
||||
for (uint16_t i = 0; i < TRANS_LEN; i++) {
|
||||
master_tx_max[i] = i;
|
||||
master_tx_max[TRANS_LEN * 2 - i - 1] = i;
|
||||
@@ -252,7 +252,7 @@ void test_sio_slave_emulate(bool sio_master_in)
|
||||
uint8_t *slave_tx_max = heap_caps_calloc(TRANS_LEN * 2, 1, MALLOC_CAP_DMA);
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(slave_tx_max, "malloc failed, exit.\n");
|
||||
|
||||
// write somethin to a long buffer for test long transmission
|
||||
// write something to a long buffer for test long transmission
|
||||
for (uint16_t i = 0; i < TRANS_LEN; i++) {
|
||||
slave_tx_max[i] = i;
|
||||
slave_tx_max[TRANS_LEN * 2 - i - 1] = i;
|
||||
|
@@ -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 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
@@ -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
|
||||
};
|
||||
|
||||
|
@@ -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 |
|
||||
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
@@ -24,13 +24,6 @@
|
||||
#include "esp_log.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
|
||||
#if (TEST_SPI_PERIPH_NUM >= 2)
|
||||
//These will only be enabled on chips with 2 or more SPI peripherals
|
||||
|
||||
#ifndef CONFIG_SPIRAM
|
||||
//This test should be removed once the timing test is merged.
|
||||
|
||||
static spi_device_handle_t spi;
|
||||
static WORD_ALIGNED_ATTR uint8_t master_txbuf[320];
|
||||
static WORD_ALIGNED_ATTR uint8_t master_rxbuf[320];
|
||||
static WORD_ALIGNED_ATTR uint8_t slave_txbuf[320];
|
||||
@@ -39,6 +32,12 @@ static WORD_ALIGNED_ATTR uint8_t slave_rxbuf[320];
|
||||
static const uint8_t master_send[] = { 0x93, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0xaa, 0xcc, 0xff, 0xee, 0x55, 0x77, 0x88, 0x43 };
|
||||
static const uint8_t slave_send[] = { 0xaa, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, 0x13, 0x57, 0x9b, 0xdf, 0x24, 0x68, 0xac, 0xe0 };
|
||||
|
||||
#if (TEST_SPI_PERIPH_NUM >= 2)
|
||||
//These will only be enabled on chips with 2 or more SPI peripherals
|
||||
#ifndef CONFIG_SPIRAM
|
||||
//This test should be removed once the timing test is merged.
|
||||
|
||||
static spi_device_handle_t spi;
|
||||
static void custom_setup(void)
|
||||
{
|
||||
//Initialize buffers
|
||||
@@ -74,7 +73,7 @@ static void custom_setup(void)
|
||||
TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO));
|
||||
|
||||
//Do internal connections
|
||||
same_pin_func_sel(buscfg, devcfg, 0);
|
||||
same_pin_func_sel(buscfg, devcfg.spics_io_num, 0, false);
|
||||
}
|
||||
|
||||
static void custom_teardown(void)
|
||||
@@ -145,7 +144,7 @@ TEST_CASE("Test slave rx no_dma overwrite when length below/over config", "[spi]
|
||||
TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &buscfg, &slvcfg, SPI_DMA_DISABLED));
|
||||
|
||||
//initialize master and slave on the same pins break some of the output configs, fix them
|
||||
same_pin_func_sel(buscfg, devcfg, 0);
|
||||
same_pin_func_sel(buscfg, devcfg.spics_io_num, 0, false);
|
||||
|
||||
uint8_t master_tx[TEST_SLV_RX_BUF_LEN], slave_rx[TEST_SLV_RX_BUF_LEN];
|
||||
for (uint8_t i = 0; i < TEST_SLV_RX_BUF_LEN; i++) {
|
||||
@@ -250,10 +249,16 @@ TEST_CASE("test fullduplex slave with only TX direction", "[spi]")
|
||||
|
||||
ESP_LOGI(SLAVE_TAG, "test passed.");
|
||||
}
|
||||
#endif // !CONFIG_SPIRAM
|
||||
#endif // #if (TEST_SPI_PERIPH_NUM >= 2)
|
||||
|
||||
TEST_CASE("test slave send unaligned", "[spi]")
|
||||
{
|
||||
custom_setup();
|
||||
spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
buscfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS;
|
||||
spi_slave_interface_config_t slvcfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO));
|
||||
same_pin_func_sel(buscfg, slvcfg.spics_io_num, 0, true);
|
||||
|
||||
memcpy(master_txbuf, master_send, sizeof(master_send));
|
||||
memcpy(slave_txbuf, slave_send, sizeof(slave_send));
|
||||
@@ -272,164 +277,29 @@ TEST_CASE("test slave send unaligned", "[spi]")
|
||||
memset(master_rxbuf, 0x66, sizeof(master_rxbuf));
|
||||
memset(slave_rxbuf, 0x66, sizeof(slave_rxbuf));
|
||||
|
||||
//mount slave trans
|
||||
TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &slave_t, portMAX_DELAY));
|
||||
|
||||
//send
|
||||
spi_transaction_t t = {};
|
||||
t.length = 32 * (i + 1);
|
||||
if (t.length != 0) {
|
||||
t.tx_buffer = master_txbuf + i;
|
||||
t.rx_buffer = master_rxbuf + i;
|
||||
}
|
||||
spi_device_transmit(spi, (spi_transaction_t *)&t);
|
||||
|
||||
//start master trans
|
||||
spi_master_trans_impl_gpio(buscfg, slvcfg.spics_io_num, 0, master_txbuf + i, master_rxbuf + i, 4 * (i + 1), false);
|
||||
//wait for end
|
||||
TEST_ESP_OK(spi_slave_get_trans_result(TEST_SLAVE_HOST, &out, portMAX_DELAY));
|
||||
|
||||
//show result
|
||||
ESP_LOGI(SLAVE_TAG, "trans_len: %d", slave_t.trans_len);
|
||||
ESP_LOG_BUFFER_HEX("master tx", t.tx_buffer, t.length / 8);
|
||||
ESP_LOG_BUFFER_HEX("master rx", t.rx_buffer, t.length / 8);
|
||||
ESP_LOG_BUFFER_HEX("master tx", master_txbuf + i, 4 * (i + 1));
|
||||
ESP_LOG_BUFFER_HEX("master rx", master_rxbuf + i, 4 * (i + 1));
|
||||
ESP_LOG_BUFFER_HEX("slave tx", slave_t.tx_buffer, (slave_t.trans_len + 7) / 8);
|
||||
ESP_LOG_BUFFER_HEX("slave rx", slave_t.rx_buffer, (slave_t.trans_len + 7) / 8);
|
||||
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(t.tx_buffer, slave_t.rx_buffer, t.length / 8);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(slave_t.tx_buffer, t.rx_buffer, t.length / 8);
|
||||
TEST_ASSERT_EQUAL(t.length, slave_t.trans_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(master_txbuf + i, slave_t.rx_buffer, 4 * (i + 1));
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(slave_t.tx_buffer, master_rxbuf + i, 4 * (i + 1));
|
||||
TEST_ASSERT_EQUAL(32 * (i + 1), slave_t.trans_len);
|
||||
}
|
||||
|
||||
custom_teardown();
|
||||
|
||||
spi_slave_free(TEST_SLAVE_HOST);
|
||||
ESP_LOGI(SLAVE_TAG, "test passed.");
|
||||
}
|
||||
|
||||
#endif // !CONFIG_SPIRAM
|
||||
|
||||
#endif // #if (TEST_SPI_PERIPH_NUM >= 2)
|
||||
|
||||
#if (TEST_SPI_PERIPH_NUM == 1)
|
||||
//These tests are for chips which only have 1 SPI controller
|
||||
/********************************************************************************
|
||||
* Test By Master & Slave (2 boards)
|
||||
*
|
||||
* Master (C3, C2, H2) && Slave (C3, C2, H2):
|
||||
* PIN | Master | Slave |
|
||||
* ----| --------- | --------- |
|
||||
* CS | 10 | 10 |
|
||||
* CLK | 6 | 6 |
|
||||
* MOSI| 7 | 7 |
|
||||
* MISO| 2 | 2 |
|
||||
* GND | GND | GND |
|
||||
*
|
||||
********************************************************************************/
|
||||
#define BUF_SIZE 320
|
||||
|
||||
static void unaligned_test_master(void)
|
||||
{
|
||||
spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &buscfg, 0));
|
||||
|
||||
spi_device_handle_t spi;
|
||||
spi_device_interface_config_t devcfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
|
||||
devcfg.clock_speed_hz = 4 * 1000 * 1000;
|
||||
devcfg.queue_size = 7;
|
||||
TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &devcfg, &spi));
|
||||
|
||||
unity_send_signal("Master ready");
|
||||
|
||||
uint8_t *master_send_buf = heap_caps_malloc(BUF_SIZE, MALLOC_CAP_DMA);
|
||||
uint8_t *master_recv_buf = heap_caps_calloc(BUF_SIZE, 1, MALLOC_CAP_DMA);
|
||||
//This buffer is used for 2-board test and should be assigned totally the same as the ``test_slave_loop`` does.
|
||||
uint8_t *slave_send_buf = heap_caps_malloc(BUF_SIZE, MALLOC_CAP_DMA);
|
||||
srand(199);
|
||||
for (int i = 0; i < BUF_SIZE; i++) {
|
||||
master_send_buf[i] = rand();
|
||||
}
|
||||
srand(299);
|
||||
for (int i = 0; i < BUF_SIZE; i++) {
|
||||
slave_send_buf[i] = rand();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uint32_t length_in_bytes = 4 * (i + 1);
|
||||
spi_transaction_t t = {
|
||||
.tx_buffer = master_send_buf + i,
|
||||
.rx_buffer = master_recv_buf,
|
||||
.length = length_in_bytes * 8,
|
||||
};
|
||||
|
||||
vTaskDelay(50);
|
||||
unity_wait_for_signal("Slave ready");
|
||||
TEST_ESP_OK(spi_device_transmit(spi, (spi_transaction_t *)&t));
|
||||
|
||||
//show result
|
||||
ESP_LOG_BUFFER_HEX("master tx:", master_send_buf + i, length_in_bytes);
|
||||
ESP_LOG_BUFFER_HEX("master rx:", master_recv_buf, length_in_bytes);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(slave_send_buf + i, master_recv_buf, length_in_bytes);
|
||||
|
||||
//clean
|
||||
memset(master_recv_buf, 0x00, BUF_SIZE);
|
||||
}
|
||||
|
||||
free(master_send_buf);
|
||||
free(master_recv_buf);
|
||||
free(slave_send_buf);
|
||||
TEST_ESP_OK(spi_bus_remove_device(spi));
|
||||
TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST));
|
||||
}
|
||||
|
||||
static void unaligned_test_slave(void)
|
||||
{
|
||||
unity_wait_for_signal("Master ready");
|
||||
spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
spi_slave_interface_config_t slvcfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_CH_AUTO));
|
||||
|
||||
uint8_t *slave_send_buf = heap_caps_malloc(BUF_SIZE, MALLOC_CAP_DMA);
|
||||
uint8_t *slave_recv_buf = heap_caps_calloc(BUF_SIZE, 1, MALLOC_CAP_DMA);
|
||||
//This buffer is used for 2-board test and should be assigned totally the same as the ``test_slave_loop`` does.
|
||||
uint8_t *master_send_buf = heap_caps_malloc(BUF_SIZE, MALLOC_CAP_DMA);
|
||||
srand(199);
|
||||
for (int i = 0; i < BUF_SIZE; i++) {
|
||||
master_send_buf[i] = rand();
|
||||
}
|
||||
srand(299);
|
||||
for (int i = 0; i < BUF_SIZE; i++) {
|
||||
slave_send_buf[i] = rand();
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
uint32_t mst_length_in_bytes = 4 * (i + 1);
|
||||
spi_slave_transaction_t slave_t = {
|
||||
.tx_buffer = slave_send_buf + i,
|
||||
.rx_buffer = slave_recv_buf,
|
||||
.length = 32 * 8,
|
||||
};
|
||||
|
||||
unity_send_signal("Slave ready");
|
||||
TEST_ESP_OK(spi_slave_transmit(TEST_SPI_HOST, &slave_t, portMAX_DELAY));
|
||||
|
||||
//show result
|
||||
ESP_LOGI(SLAVE_TAG, "trans_len: %d", slave_t.trans_len);
|
||||
ESP_LOG_BUFFER_HEX("slave tx:", slave_send_buf + i, mst_length_in_bytes);
|
||||
ESP_LOG_BUFFER_HEX("slave rx:", slave_recv_buf, mst_length_in_bytes);
|
||||
|
||||
TEST_ASSERT_EQUAL(mst_length_in_bytes * 8, slave_t.trans_len);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(master_send_buf + i, slave_recv_buf, mst_length_in_bytes);
|
||||
|
||||
//clean
|
||||
memset(slave_recv_buf, 0x00, BUF_SIZE);
|
||||
}
|
||||
|
||||
free(slave_send_buf);
|
||||
free(slave_recv_buf);
|
||||
free(master_send_buf);
|
||||
TEST_ESP_OK(spi_slave_free(TEST_SPI_HOST));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("SPI_Slave_Unaligned_Test", "[spi_ms][timeout=120]", unaligned_test_master, unaligned_test_slave);
|
||||
#endif //#if (TEST_SPI_PERIPH_NUM == 1)
|
||||
|
||||
#if CONFIG_SPI_SLAVE_ISR_IN_IRAM
|
||||
#define TEST_IRAM_TRANS_NUM 8
|
||||
#define TEST_TRANS_LEN 64
|
||||
@@ -782,6 +652,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
|
||||
@@ -805,15 +676,14 @@ TEST_CASE("test_spi_slave_sleep_retention", "[spi]")
|
||||
buscfg.flags = (allow_pd) ? SPICOMMON_BUSFLAG_SLP_ALLOW_PD : 0;
|
||||
buscfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS;
|
||||
spi_slave_interface_config_t slvcfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &buscfg, &slvcfg, SPI_DMA_DISABLED));
|
||||
gpio_pullup_en(slvcfg.spics_io_num);
|
||||
vTaskDelay(1);
|
||||
TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &buscfg, &slvcfg, SPI_DMA_DISABLED));
|
||||
same_pin_func_sel(buscfg, slvcfg.spics_io_num, 0, true);
|
||||
|
||||
for (uint8_t cnt = 0; cnt < 3; cnt ++) {
|
||||
printf("Going into sleep with power %s ...\n", (buscfg.flags & SPICOMMON_BUSFLAG_SLP_ALLOW_PD) ? "down" : "hold");
|
||||
TEST_ESP_OK(spi_slave_disable(TEST_SPI_HOST));
|
||||
TEST_ESP_OK(spi_slave_disable(TEST_SLAVE_HOST));
|
||||
TEST_ESP_OK(esp_light_sleep_start());
|
||||
TEST_ESP_OK(spi_slave_enable(TEST_SPI_HOST));
|
||||
TEST_ESP_OK(spi_slave_enable(TEST_SLAVE_HOST));
|
||||
printf("Waked up!\n");
|
||||
|
||||
// check if the sleep happened as expected
|
||||
@@ -826,15 +696,15 @@ TEST_CASE("test_spi_slave_sleep_retention", "[spi]")
|
||||
mst_send[11] = cnt + 'A';
|
||||
memset(mst_rexcv, 0, sizeof(mst_rexcv));
|
||||
memset(slv_rexcv, 0, sizeof(slv_rexcv));
|
||||
TEST_ESP_OK(spi_slave_queue_trans(TEST_SPI_HOST, &trans_cfg, portMAX_DELAY));
|
||||
spi_master_trans_impl_gpio(buscfg, slvcfg.spics_io_num, 0, mst_send, mst_rexcv, sizeof(mst_send));
|
||||
TEST_ESP_OK(spi_slave_get_trans_result(TEST_SPI_HOST, &ret_trans, portMAX_DELAY));
|
||||
TEST_ESP_OK(spi_slave_queue_trans(TEST_SLAVE_HOST, &trans_cfg, portMAX_DELAY));
|
||||
spi_master_trans_impl_gpio(buscfg, slvcfg.spics_io_num, 0, mst_send, mst_rexcv, sizeof(mst_send), 0);
|
||||
TEST_ESP_OK(spi_slave_get_trans_result(TEST_SLAVE_HOST, &ret_trans, portMAX_DELAY));
|
||||
|
||||
spitest_cmp_or_dump(slv_send, mst_rexcv, sizeof(mst_rexcv));
|
||||
spitest_cmp_or_dump(mst_send, slv_rexcv, sizeof(slv_rexcv));
|
||||
}
|
||||
|
||||
TEST_ESP_OK(spi_slave_free(TEST_SPI_HOST));
|
||||
TEST_ESP_OK(spi_slave_free(TEST_SLAVE_HOST));
|
||||
}
|
||||
|
||||
esp_sleep_set_sleep_context(NULL);
|
||||
@@ -842,3 +712,4 @@ TEST_CASE("test_spi_slave_sleep_retention", "[spi]")
|
||||
TEST_ESP_OK(sleep_cpu_configure(false));
|
||||
#endif
|
||||
}
|
||||
#endif //SOC_LIGHT_SLEEP_SUPPORTED
|
||||
|
@@ -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 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
@@ -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,8 +19,6 @@
|
||||
#include "esp_private/sleep_cpu.h"
|
||||
#include "esp_private/esp_sleep_internal.h"
|
||||
#include "esp_private/esp_pmu.h"
|
||||
|
||||
#if (TEST_SPI_PERIPH_NUM >= 2) //These will be only enabled on chips with 2 or more SPI peripherals
|
||||
#include "esp_rom_gpio.h"
|
||||
|
||||
#define TEST_BUFFER_SIZE 256 ///< buffer size of each wrdma buffer in fifo mode
|
||||
@@ -42,65 +40,6 @@ typedef struct {
|
||||
spi_slave_hd_data_t rx_data;
|
||||
} testhd_context_t;
|
||||
|
||||
static uint32_t get_hd_flags(void)
|
||||
{
|
||||
#if !defined(SLAVE_SUPPORT_QIO)
|
||||
return 0;
|
||||
#endif
|
||||
int flag_id = rand() % 5;
|
||||
ESP_LOGI("io mode", "%d", flag_id);
|
||||
|
||||
switch (flag_id) {
|
||||
case 1:
|
||||
return SPI_TRANS_MODE_DIO;
|
||||
case 2:
|
||||
return SPI_TRANS_MODE_DIO | SPI_TRANS_MODE_DIOQIO_ADDR;
|
||||
case 3:
|
||||
return SPI_TRANS_MODE_QIO;
|
||||
case 4:
|
||||
return SPI_TRANS_MODE_QIO | SPI_TRANS_MODE_DIOQIO_ADDR;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void config_single_board_test_pin(void)
|
||||
{
|
||||
esp_rom_gpio_connect_out_signal(PIN_NUM_MOSI, spi_periph_signal[TEST_SPI_HOST].spid_out, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(PIN_NUM_MOSI, spi_periph_signal[TEST_SLAVE_HOST].spid_in, 0);
|
||||
|
||||
esp_rom_gpio_connect_out_signal(PIN_NUM_MISO, spi_periph_signal[TEST_SLAVE_HOST].spiq_out, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(PIN_NUM_MISO, spi_periph_signal[TEST_SPI_HOST].spiq_in, 0);
|
||||
|
||||
esp_rom_gpio_connect_out_signal(PIN_NUM_CS, spi_periph_signal[TEST_SPI_HOST].spics_out[0], 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(PIN_NUM_CS, spi_periph_signal[TEST_SLAVE_HOST].spics_in, 0);
|
||||
|
||||
esp_rom_gpio_connect_out_signal(PIN_NUM_CLK, spi_periph_signal[TEST_SPI_HOST].spiclk_out, 0, 0);
|
||||
esp_rom_gpio_connect_in_signal(PIN_NUM_CLK, spi_periph_signal[TEST_SLAVE_HOST].spiclk_in, 0);
|
||||
}
|
||||
|
||||
static void init_master_hd(spi_device_handle_t* spi, const spitest_param_set_t* config, int freq)
|
||||
{
|
||||
spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
bus_cfg.max_transfer_sz = TEST_DMA_MAX_SIZE * 30;
|
||||
bus_cfg.quadhd_io_num = PIN_NUM_HD;
|
||||
bus_cfg.quadwp_io_num = PIN_NUM_WP;
|
||||
#if defined(TEST_MASTER_GPIO_MATRIX) && CONFIG_IDF_TARGET_ESP32S2
|
||||
bus_cfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS;
|
||||
#endif
|
||||
|
||||
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, SPI_DMA_CH_AUTO));
|
||||
spi_device_interface_config_t dev_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
|
||||
dev_cfg.flags = SPI_DEVICE_HALFDUPLEX;
|
||||
dev_cfg.command_bits = 8;
|
||||
dev_cfg.address_bits = 8;
|
||||
dev_cfg.dummy_bits = 8;
|
||||
dev_cfg.clock_speed_hz = freq;
|
||||
dev_cfg.mode = config->mode;
|
||||
dev_cfg.input_delay_ns = config->slave_tv_ns;
|
||||
TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, spi));
|
||||
}
|
||||
|
||||
static void init_slave_hd(int mode, bool append_mode, const spi_slave_hd_callback_config_t* callback)
|
||||
{
|
||||
spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
@@ -123,6 +62,29 @@ static void init_slave_hd(int mode, bool append_mode, const spi_slave_hd_callbac
|
||||
TEST_ESP_OK(spi_slave_hd_init(TEST_SLAVE_HOST, &bus_cfg, &slave_hd_cfg));
|
||||
}
|
||||
|
||||
#if (TEST_SPI_PERIPH_NUM >= 2) //These will be only enabled on chips with 2 or more SPI peripherals
|
||||
static void init_master_hd(spi_device_handle_t* spi, const spitest_param_set_t* config, int freq)
|
||||
{
|
||||
spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
bus_cfg.max_transfer_sz = TEST_DMA_MAX_SIZE * 30;
|
||||
bus_cfg.quadhd_io_num = PIN_NUM_HD;
|
||||
bus_cfg.quadwp_io_num = PIN_NUM_WP;
|
||||
#if defined(TEST_MASTER_GPIO_MATRIX) && CONFIG_IDF_TARGET_ESP32S2
|
||||
bus_cfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS;
|
||||
#endif
|
||||
|
||||
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, SPI_DMA_CH_AUTO));
|
||||
spi_device_interface_config_t dev_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
|
||||
dev_cfg.flags = SPI_DEVICE_HALFDUPLEX;
|
||||
dev_cfg.command_bits = 8;
|
||||
dev_cfg.address_bits = 8;
|
||||
dev_cfg.dummy_bits = 8;
|
||||
dev_cfg.clock_speed_hz = freq;
|
||||
dev_cfg.mode = config->mode;
|
||||
dev_cfg.input_delay_ns = config->slave_tv_ns;
|
||||
TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, spi));
|
||||
}
|
||||
|
||||
static void test_hd_init(void** arg)
|
||||
{
|
||||
TEST_ASSERT(*arg == NULL);
|
||||
@@ -206,7 +168,9 @@ static void test_hd_start(spi_device_handle_t *spi, int freq, const spitest_para
|
||||
init_slave_hd(cfg->mode, 0, &callback);
|
||||
|
||||
//when test with single board via same set of mosi, miso, clk and cs pins.
|
||||
config_single_board_test_pin();
|
||||
spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
spi_slave_hd_slot_config_t slave_hd_cfg = SPI_SLOT_TEST_DEFAULT_CONFIG();
|
||||
same_pin_func_sel(bus_cfg, slave_hd_cfg.spics_io_num, 0, false);
|
||||
|
||||
wait_wrbuf_sig(ctx, 0);
|
||||
wait_rdbuf_sig(ctx, 0);
|
||||
@@ -256,6 +220,28 @@ void check_no_signal(testhd_context_t* context)
|
||||
check_no_tx(context);
|
||||
}
|
||||
|
||||
static uint32_t get_hd_flags(void)
|
||||
{
|
||||
#if !defined(SLAVE_SUPPORT_QIO)
|
||||
return 0;
|
||||
#endif
|
||||
int flag_id = rand() % 5;
|
||||
ESP_LOGI("io mode", "%d", flag_id);
|
||||
|
||||
switch (flag_id) {
|
||||
case 1:
|
||||
return SPI_TRANS_MODE_DIO;
|
||||
case 2:
|
||||
return SPI_TRANS_MODE_DIO | SPI_TRANS_MODE_DIOQIO_ADDR;
|
||||
case 3:
|
||||
return SPI_TRANS_MODE_QIO;
|
||||
case 4:
|
||||
return SPI_TRANS_MODE_QIO | SPI_TRANS_MODE_DIOQIO_ADDR;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void test_wrdma(testhd_context_t* ctx, const spitest_param_set_t *cfg, spi_device_handle_t spi)
|
||||
{
|
||||
int pos = rand() % TEST_DMA_MAX_SIZE;
|
||||
@@ -459,15 +445,13 @@ static const ptest_func_t hd_test_func = {
|
||||
TEST_SINGLE_BOARD(name, test_set, "[spi][timeout=120]", &hd_test_func)
|
||||
|
||||
static int test_freq_hd[] = {
|
||||
// 100*1000,
|
||||
// 10 * 1000 * 1000, //maximum freq MISO stable before next latch edge
|
||||
500 * 1000,
|
||||
10 * 1000 * 1000, //maximum freq MISO stable before next latch edge
|
||||
20 * 1000 * 1000, //maximum freq MISO stable before next latch edge
|
||||
// 40 * 1000 * 1000, //maximum freq MISO stable before next latch edge
|
||||
0,
|
||||
};
|
||||
|
||||
#define TEST_HD_IN_CONTINUOUS_MODE true
|
||||
|
||||
static spitest_param_set_t hd_conf[] = {
|
||||
{
|
||||
.pset_name = "MODE0",
|
||||
@@ -507,6 +491,7 @@ static spitest_param_set_t hd_conf[] = {
|
||||
},
|
||||
};
|
||||
TEST_SPI_HD(HD, hd_conf);
|
||||
#endif //#if (TEST_SPI_PERIPH_NUM >= 2)
|
||||
|
||||
/*
|
||||
* When the previous transaction of master exceeds the length of slave prepared too long, the
|
||||
@@ -517,20 +502,15 @@ TEST_SPI_HD(HD, hd_conf);
|
||||
*/
|
||||
TEST_CASE("test spi slave hd segment mode, master too long", "[spi][spi_slv_hd]")
|
||||
{
|
||||
spi_device_handle_t spi;
|
||||
spitest_param_set_t *cfg = &hd_conf[0];
|
||||
int freq = 100 * 1000; // the frequency should be small enough for the slave to prepare new trans
|
||||
|
||||
init_master_hd(&spi, cfg, freq);
|
||||
|
||||
//no callback needed
|
||||
init_slave_hd(cfg->mode, 0, NULL);
|
||||
init_slave_hd(0, false, NULL);
|
||||
|
||||
//Use GPIO matrix to connect signal of master and slave via same set of pins on one board.
|
||||
config_single_board_test_pin();
|
||||
spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
spi_slave_hd_slot_config_t slave_hd_cfg = SPI_SLOT_TEST_DEFAULT_CONFIG();
|
||||
same_pin_func_sel(bus_cfg, slave_hd_cfg.spics_io_num, 0, true);
|
||||
|
||||
const int send_buf_size = 1024;
|
||||
|
||||
WORD_ALIGNED_ATTR uint8_t* slave_send_buf = malloc(send_buf_size * 2);
|
||||
WORD_ALIGNED_ATTR uint8_t* master_send_buf = malloc(send_buf_size * 2);
|
||||
WORD_ALIGNED_ATTR uint8_t* slave_recv_buf = malloc(send_buf_size * 2);
|
||||
@@ -578,11 +558,11 @@ TEST_CASE("test spi slave hd segment mode, master too long", "[spi][spi_slv_hd]"
|
||||
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &slave_trans[i], portMAX_DELAY));
|
||||
}
|
||||
|
||||
essl_spi_wrdma(spi, master_send_buf, send_buf_size, -1, 0);
|
||||
essl_spi_wrdma(spi, master_send_buf + send_buf_size, send_buf_size, 5, 0);
|
||||
essl_sspi_hd_dma_trans_seg(bus_cfg, slave_hd_cfg.spics_io_num, 0, false, master_send_buf, send_buf_size, -1);
|
||||
essl_sspi_hd_dma_trans_seg(bus_cfg, slave_hd_cfg.spics_io_num, 0, false, master_send_buf + send_buf_size, send_buf_size, 5);
|
||||
|
||||
essl_spi_rddma(spi, master_recv_buf, send_buf_size, -1, 0);
|
||||
essl_spi_rddma(spi, master_recv_buf + send_buf_size, send_buf_size, 5, 0);
|
||||
essl_sspi_hd_dma_trans_seg(bus_cfg, slave_hd_cfg.spics_io_num, 0, true, master_recv_buf, send_buf_size, -1);
|
||||
essl_sspi_hd_dma_trans_seg(bus_cfg, slave_hd_cfg.spics_io_num, 0, true, master_recv_buf + send_buf_size, send_buf_size, 5);
|
||||
|
||||
for (int i = 0; i < 2; i ++) {
|
||||
spi_slave_hd_data_t *ret_trans;
|
||||
@@ -590,7 +570,6 @@ TEST_CASE("test spi slave hd segment mode, master too long", "[spi][spi_slv_hd]"
|
||||
TEST_ASSERT(ret_trans == &slave_trans[i]);
|
||||
TEST_ASSERT_EQUAL(slave_trans[i].len, ret_trans->trans_len);
|
||||
}
|
||||
|
||||
for (int i = 2; i < 4; i ++) {
|
||||
spi_slave_hd_data_t *ret_trans;
|
||||
TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &ret_trans, portMAX_DELAY));
|
||||
@@ -608,149 +587,9 @@ TEST_CASE("test spi slave hd segment mode, master too long", "[spi][spi_slv_hd]"
|
||||
free(master_send_buf);
|
||||
free(slave_send_buf);
|
||||
spi_slave_hd_deinit(TEST_SLAVE_HOST);
|
||||
master_free_device_bus(spi);
|
||||
ESP_LOGI(SLAVE_TAG, "test passed.");
|
||||
}
|
||||
|
||||
#endif //#if (TEST_SPI_PERIPH_NUM >= 2)
|
||||
|
||||
#if (TEST_SPI_PERIPH_NUM == 1)
|
||||
//These tests are for chips which only have 1 SPI controller
|
||||
/********************************************************************************
|
||||
* Test By Master & Slave (2 boards)
|
||||
*
|
||||
* Master (C3, C2, H2) && Slave (C3, C2, H2):
|
||||
* PIN | Master | Slave |
|
||||
* ----| --------- | --------- |
|
||||
* CS | 10 | 10 |
|
||||
* CLK | 6 | 6 |
|
||||
* MOSI| 7 | 7 |
|
||||
* MISO| 2 | 2 |
|
||||
* GND | GND | GND |
|
||||
*
|
||||
********************************************************************************/
|
||||
|
||||
static void hd_master(void)
|
||||
{
|
||||
spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_bus_initialize(TEST_SPI_HOST, &bus_cfg, SPI_DMA_CH_AUTO));
|
||||
|
||||
spi_device_handle_t spi;
|
||||
spi_device_interface_config_t dev_cfg = SPI_DEVICE_TEST_DEFAULT_CONFIG();
|
||||
dev_cfg.flags = SPI_DEVICE_HALFDUPLEX;
|
||||
dev_cfg.command_bits = 8;
|
||||
dev_cfg.address_bits = 8;
|
||||
dev_cfg.dummy_bits = 8;
|
||||
dev_cfg.clock_speed_hz = 100 * 1000;
|
||||
TEST_ESP_OK(spi_bus_add_device(TEST_SPI_HOST, &dev_cfg, &spi));
|
||||
|
||||
const int send_buf_size = 1024;
|
||||
|
||||
WORD_ALIGNED_ATTR uint8_t *master_send_buf = malloc(send_buf_size * 2);
|
||||
WORD_ALIGNED_ATTR uint8_t *master_recv_buf = calloc(1, send_buf_size * 2);
|
||||
//This buffer is used for 2-board test and should be assigned totally the same as the ``hd_slave`` does.
|
||||
WORD_ALIGNED_ATTR uint8_t *slave_send_buf = malloc(send_buf_size * 2);
|
||||
test_fill_random_to_buffers_dualboard(199, master_send_buf, slave_send_buf, send_buf_size * 2);
|
||||
|
||||
//This is the same as the ``hd_slave`` sets.
|
||||
int trans_len[] = {5, send_buf_size};
|
||||
|
||||
unity_send_signal("master ready");
|
||||
unity_wait_for_signal("slave ready");
|
||||
essl_spi_wrdma(spi, master_send_buf, send_buf_size, -1, 0);
|
||||
|
||||
unity_wait_for_signal("slave ready");
|
||||
essl_spi_wrdma(spi, master_send_buf + send_buf_size, send_buf_size, 5, 0);
|
||||
|
||||
unity_wait_for_signal("slave ready");
|
||||
essl_spi_rddma(spi, master_recv_buf, send_buf_size, -1, 0);
|
||||
spitest_cmp_or_dump(slave_send_buf, master_recv_buf, trans_len[0]);
|
||||
|
||||
unity_wait_for_signal("slave ready");
|
||||
essl_spi_rddma(spi, master_recv_buf + send_buf_size, send_buf_size, 5, 0);
|
||||
spitest_cmp_or_dump(slave_send_buf + send_buf_size, master_recv_buf + send_buf_size, trans_len[1]);
|
||||
|
||||
free(master_recv_buf);
|
||||
free(master_send_buf);
|
||||
free(slave_send_buf);
|
||||
|
||||
master_free_device_bus(spi);
|
||||
}
|
||||
|
||||
static void hd_slave(void)
|
||||
{
|
||||
spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
bus_cfg.max_transfer_sz = 14000 * 30;
|
||||
|
||||
spi_slave_hd_slot_config_t slave_hd_cfg = SPI_SLOT_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_slave_hd_init(TEST_SLAVE_HOST, &bus_cfg, &slave_hd_cfg));
|
||||
|
||||
unity_wait_for_signal("master ready");
|
||||
const int send_buf_size = 1024;
|
||||
|
||||
WORD_ALIGNED_ATTR uint8_t *slave_send_buf = malloc(send_buf_size * 2);
|
||||
WORD_ALIGNED_ATTR uint8_t *slave_recv_buf = calloc(1, send_buf_size * 2);
|
||||
//This buffer is used for 2-board test and should be assigned totally the same as the ``hd_master`` does.
|
||||
WORD_ALIGNED_ATTR uint8_t *master_send_buf = malloc(send_buf_size * 2);
|
||||
test_fill_random_to_buffers_dualboard(199, master_send_buf, slave_send_buf, send_buf_size * 2);
|
||||
|
||||
//make the first transaction shorter than the actual trans length of the master, so that the second one will be loaded while the master is still doing the first transaction.
|
||||
int trans_len[] = {5, send_buf_size};
|
||||
spi_slave_hd_data_t slave_trans[4] = {
|
||||
//recv, the buffer size should be aligned to 4
|
||||
{
|
||||
.data = slave_recv_buf,
|
||||
.len = (trans_len[0] + 3) & (~3),
|
||||
},
|
||||
{
|
||||
.data = slave_recv_buf + send_buf_size,
|
||||
.len = (trans_len[1] + 3) & (~3),
|
||||
},
|
||||
//send
|
||||
{
|
||||
.data = slave_send_buf,
|
||||
.len = trans_len[0],
|
||||
},
|
||||
{
|
||||
.data = slave_send_buf + send_buf_size,
|
||||
.len = trans_len[1],
|
||||
},
|
||||
};
|
||||
|
||||
for (int i = 0; i < 2; i ++) {
|
||||
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_RX, &slave_trans[i], portMAX_DELAY));
|
||||
unity_send_signal("slave ready");
|
||||
}
|
||||
for (int i = 2; i < 4; i ++) {
|
||||
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &slave_trans[i], portMAX_DELAY));
|
||||
unity_send_signal("slave ready");
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i ++) {
|
||||
spi_slave_hd_data_t *ret_trans;
|
||||
TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_RX, &ret_trans, portMAX_DELAY));
|
||||
TEST_ASSERT(ret_trans == &slave_trans[i]);
|
||||
TEST_ASSERT_EQUAL(slave_trans[i].len, ret_trans->trans_len);
|
||||
}
|
||||
|
||||
for (int i = 2; i < 4; i ++) {
|
||||
spi_slave_hd_data_t *ret_trans;
|
||||
TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &ret_trans, portMAX_DELAY));
|
||||
TEST_ASSERT(ret_trans == &slave_trans[i]);
|
||||
}
|
||||
|
||||
spitest_cmp_or_dump(master_send_buf, slave_recv_buf, trans_len[0]);
|
||||
spitest_cmp_or_dump(master_send_buf + send_buf_size, slave_recv_buf + send_buf_size, trans_len[1]);
|
||||
|
||||
free(slave_recv_buf);
|
||||
free(slave_send_buf);
|
||||
free(master_send_buf);
|
||||
|
||||
spi_slave_hd_deinit(TEST_SLAVE_HOST);
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("SPI Slave HD: segment mode, master sends too long", "[spi_ms][test_env=generic_multi_device]", hd_master, hd_slave);
|
||||
#endif //#if (TEST_SPI_PERIPH_NUM == 1)
|
||||
|
||||
/**
|
||||
* TODO IDF-5483
|
||||
**/
|
||||
@@ -1063,6 +902,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]")
|
||||
@@ -1075,12 +915,9 @@ TEST_CASE("test_spi_slave_hd_sleep_retention", "[spi]")
|
||||
esp_sleep_context_t sleep_ctx;
|
||||
esp_sleep_set_sleep_context(&sleep_ctx);
|
||||
|
||||
uint32_t slave_hd_cmd[2][2] = {{SPI_LL_BASE_CMD_HD_WRDMA, SPI_LL_BASE_CMD_HD_WR_END}, {SPI_LL_BASE_CMD_HD_RDDMA, SPI_LL_BASE_CMD_HD_INT0}};
|
||||
uint32_t slave_share_sig = TEST_SLP_BUF_VAL;
|
||||
uint32_t slave_share_sig = TEST_SLP_BUF_VAL, read_share_sig;
|
||||
uint8_t slv_send[14] = "I'm slave x\n", slv_rexcv[14];
|
||||
uint8_t mst_txbuff[17] = " I'm master x\n", mst_rxbuff[17]; //more than 3 byte to hold cmd,addrs,dummy
|
||||
uint8_t share_sig_buff[7] = {0}; // cmd + addr + dummy + uint32_t
|
||||
uint8_t *mst_send = &mst_txbuff[3], *mst_rexcv = &mst_rxbuff[3];
|
||||
uint8_t mst_send[14] = "I'm master x\n", mst_rexcv[14];
|
||||
spi_slave_hd_data_t *ret_trans, tx_data = {
|
||||
.data = slv_send,
|
||||
.len = sizeof(slv_send),
|
||||
@@ -1097,7 +934,7 @@ TEST_CASE("test_spi_slave_hd_sleep_retention", "[spi]")
|
||||
bus_cfg.flags |= SPICOMMON_BUSFLAG_GPIO_PINS;
|
||||
spi_slave_hd_slot_config_t slave_hd_cfg = SPI_SLOT_TEST_DEFAULT_CONFIG();
|
||||
TEST_ESP_OK(spi_slave_hd_init(TEST_SLAVE_HOST, &bus_cfg, &slave_hd_cfg));
|
||||
gpio_pullup_en(slave_hd_cfg.spics_io_num);
|
||||
same_pin_func_sel(bus_cfg, slave_hd_cfg.spics_io_num, 0, true);
|
||||
vTaskDelay(1);
|
||||
|
||||
for (uint8_t cnt = 0; cnt < 3; cnt ++) {
|
||||
@@ -1121,12 +958,8 @@ TEST_CASE("test_spi_slave_hd_sleep_retention", "[spi]")
|
||||
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_RX, &rx_data, portMAX_DELAY));
|
||||
|
||||
// tx rx transaction
|
||||
mst_txbuff[0] = slave_hd_cmd[0][0];
|
||||
spi_master_trans_impl_gpio(bus_cfg, slave_hd_cfg.spics_io_num, 0, mst_txbuff, NULL, sizeof(mst_txbuff));
|
||||
spi_master_trans_impl_gpio(bus_cfg, slave_hd_cfg.spics_io_num, 0, &slave_hd_cmd[0][1], NULL, 3);
|
||||
mst_rxbuff[0] = slave_hd_cmd[1][0];
|
||||
spi_master_trans_impl_gpio(bus_cfg, slave_hd_cfg.spics_io_num, 0, mst_rxbuff, mst_rxbuff, sizeof(mst_rxbuff));
|
||||
spi_master_trans_impl_gpio(bus_cfg, slave_hd_cfg.spics_io_num, 0, &slave_hd_cmd[1][1], NULL, 3);
|
||||
essl_sspi_hd_dma_trans_seg(bus_cfg, slave_hd_cfg.spics_io_num, 0, false, mst_send, sizeof(mst_send), -1);
|
||||
essl_sspi_hd_dma_trans_seg(bus_cfg, slave_hd_cfg.spics_io_num, 0, true, mst_rexcv, sizeof(mst_rexcv), -1);
|
||||
|
||||
// check trans result
|
||||
TEST_ESP_OK(spi_slave_hd_get_trans_res(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &ret_trans, portMAX_DELAY));
|
||||
@@ -1139,12 +972,10 @@ TEST_CASE("test_spi_slave_hd_sleep_retention", "[spi]")
|
||||
// test slave hd share registers
|
||||
slave_share_sig += cnt;
|
||||
spi_slave_hd_write_buffer(TEST_SLAVE_HOST, TEST_SLP_BUF_ID, (uint8_t *)&slave_share_sig, sizeof(uint32_t));
|
||||
memset(share_sig_buff, 0, sizeof(share_sig_buff));
|
||||
share_sig_buff[0] = SPI_LL_BASE_CMD_HD_RDBUF; // cmd
|
||||
share_sig_buff[1] = TEST_SLP_BUF_ID; // addr
|
||||
spi_master_trans_impl_gpio(bus_cfg, slave_hd_cfg.spics_io_num, 0, share_sig_buff, share_sig_buff, sizeof(share_sig_buff));
|
||||
printf("slave reg %lX\n", *((uint32_t *)&share_sig_buff[3]));
|
||||
TEST_ASSERT_EQUAL_UINT32(slave_share_sig, *((uint32_t *)&share_sig_buff[3]));
|
||||
read_share_sig = 0;
|
||||
essl_sspi_hd_buffer_trans(bus_cfg, slave_hd_cfg.spics_io_num, 0, SPI_CMD_HD_RDBUF, TEST_SLP_BUF_ID, &read_share_sig, sizeof(uint32_t));
|
||||
printf("slave reg %lX\n", read_share_sig);
|
||||
TEST_ASSERT_EQUAL_UINT32(slave_share_sig, read_share_sig);
|
||||
}
|
||||
spi_slave_hd_deinit(TEST_SLAVE_HOST);
|
||||
}
|
||||
@@ -1166,10 +997,8 @@ TEST_CASE("test_spi_slave_hd_append_sleep_retention", "[spi]")
|
||||
esp_sleep_context_t sleep_ctx;
|
||||
esp_sleep_set_sleep_context(&sleep_ctx);
|
||||
|
||||
uint32_t slave_hd_cmd[2][2] = {{SPI_LL_BASE_CMD_HD_WRDMA, SPI_LL_BASE_CMD_HD_WR_END}, {SPI_LL_BASE_CMD_HD_RDDMA, SPI_LL_BASE_CMD_HD_INT0}};
|
||||
uint8_t slv_rexcv[14], slv_send[TEST_SLP_TRANS_NUM][14] = {{"I'm append x\n"}, {"I'm append x\n"}, {"I'm append x\n"}};
|
||||
uint8_t mst_txbuff[17] = " I'm master x\n", mst_rxbuff[17]; //more than 3 byte to hold cmd,addrs,dummy
|
||||
uint8_t *mst_send = &mst_txbuff[3], *mst_rexcv = &mst_rxbuff[3];
|
||||
uint8_t mst_send[14] = "I'm master x\n", mst_rexcv[14];
|
||||
spi_slave_hd_data_t *ret_trans, tx_data[TEST_SLP_TRANS_NUM], rx_data = {
|
||||
.data = slv_rexcv,
|
||||
.len = sizeof(slv_rexcv),
|
||||
@@ -1183,7 +1012,7 @@ TEST_CASE("test_spi_slave_hd_append_sleep_retention", "[spi]")
|
||||
spi_slave_hd_slot_config_t slave_hd_cfg = SPI_SLOT_TEST_DEFAULT_CONFIG();
|
||||
slave_hd_cfg.flags |= SPI_SLAVE_HD_APPEND_MODE;
|
||||
TEST_ESP_OK(spi_slave_hd_init(TEST_SLAVE_HOST, &bus_cfg, &slave_hd_cfg));
|
||||
gpio_pullup_en(slave_hd_cfg.spics_io_num);
|
||||
same_pin_func_sel(bus_cfg, slave_hd_cfg.spics_io_num, 0, true);
|
||||
vTaskDelay(1);
|
||||
|
||||
for (uint8_t i = 0; i < 2; i++) {
|
||||
@@ -1216,12 +1045,8 @@ TEST_CASE("test_spi_slave_hd_append_sleep_retention", "[spi]")
|
||||
memset(slv_rexcv, 0, sizeof(slv_rexcv));
|
||||
|
||||
// tx rx append transaction
|
||||
mst_txbuff[0] = slave_hd_cmd[0][0];
|
||||
spi_master_trans_impl_gpio(bus_cfg, slave_hd_cfg.spics_io_num, 0, mst_txbuff, NULL, sizeof(mst_txbuff));
|
||||
spi_master_trans_impl_gpio(bus_cfg, slave_hd_cfg.spics_io_num, 0, &slave_hd_cmd[0][1], NULL, 3);
|
||||
mst_rxbuff[0] = slave_hd_cmd[1][0];
|
||||
spi_master_trans_impl_gpio(bus_cfg, slave_hd_cfg.spics_io_num, 0, mst_rxbuff, mst_rxbuff, sizeof(mst_rxbuff));
|
||||
spi_master_trans_impl_gpio(bus_cfg, slave_hd_cfg.spics_io_num, 0, &slave_hd_cmd[1][1], NULL, 3);
|
||||
essl_sspi_hd_dma_trans_seg(bus_cfg, slave_hd_cfg.spics_io_num, 0, false, mst_send, sizeof(mst_send), -1);
|
||||
essl_sspi_hd_dma_trans_seg(bus_cfg, slave_hd_cfg.spics_io_num, 0, true, mst_rexcv, sizeof(mst_rexcv), -1);
|
||||
|
||||
// check append trans result
|
||||
TEST_ESP_OK(spi_slave_hd_get_append_trans_res(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_TX, &ret_trans, portMAX_DELAY));
|
||||
@@ -1238,3 +1063,4 @@ TEST_CASE("test_spi_slave_hd_append_sleep_retention", "[spi]")
|
||||
TEST_ESP_OK(sleep_cpu_configure(false));
|
||||
#endif
|
||||
}
|
||||
#endif //SOC_LIGHT_SLEEP_SUPPORTED
|
||||
|
@@ -2,6 +2,7 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
import pytest
|
||||
from pytest_embedded_idf.utils import idf_parametrize
|
||||
|
||||
# If `test_env` is define, should not run on generic runner
|
||||
|
||||
|
||||
@@ -16,7 +17,7 @@ def test_slave_hd_single_dev(case_tester) -> None: # type: ignore
|
||||
for case in case_tester.test_menu:
|
||||
if 'test_env' in case.attributes:
|
||||
continue
|
||||
case_tester.run_normal_case(case=case, reset=True)
|
||||
case_tester.run_normal_case(case=case, reset=True, timeout=180)
|
||||
|
||||
|
||||
# if `test_env` not defined, will run on `generic_multi_device` by default
|
||||
|
@@ -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}
|
||||
|
@@ -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;
|
||||
|
@@ -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.
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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);
|
||||
|
@@ -1,17 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -26,7 +24,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//NOTE: These macros are changed on ESP32-C2 for build. MODIFY these when bringup flash.
|
||||
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )
|
||||
|
||||
|
@@ -1,17 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2020-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -28,7 +26,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//NOTE: These macros are changed on c3 for build. MODIFY these when bringup flash.
|
||||
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )
|
||||
|
||||
|
@@ -1,17 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -28,7 +26,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//NOTE: These macros are changed on c3 for build. MODIFY these when bringup flash.
|
||||
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )
|
||||
|
||||
|
@@ -1,17 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -28,7 +26,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//NOTE: These macros are changed on c3 for build. MODIFY these when bringup flash.
|
||||
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )
|
||||
|
||||
|
@@ -1,17 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -28,7 +26,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//NOTE: These macros are changed on c3 for build. MODIFY these when bringup flash.
|
||||
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )
|
||||
|
||||
|
@@ -1,17 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -28,7 +26,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//NOTE: These macros are changed on h2 for build. MODIFY these when bringup flash.
|
||||
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )
|
||||
|
||||
|
431
components/hal/esp32h21/include/hal/gpspi_flash_ll.h
Normal file
431
components/hal/esp32h21/include/hal/gpspi_flash_ll.h
Normal file
@@ -0,0 +1,431 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
******************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "soc/spi_periph.h"
|
||||
#include "soc/spi_struct.h"
|
||||
#include "hal/spi_types.h"
|
||||
#include "hal/spi_flash_types.h"
|
||||
#include <sys/param.h> // For MIN/MAX
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "hal/misc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )
|
||||
|
||||
typedef typeof(GPSPI2.clock.val) gpspi_flash_ll_clock_reg_t;
|
||||
#define GPSPI_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ (32) // (register default)0: XTAL_CLK
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Control
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Reset peripheral registers before configuration and starting control
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_reset(spi_dev_t *dev)
|
||||
{
|
||||
dev->user.val = 0;
|
||||
dev->ctrl.val = 0;
|
||||
|
||||
dev->clk_gate.clk_en = 1;
|
||||
dev->clk_gate.mst_clk_active = 1;
|
||||
dev->clk_gate.mst_clk_sel = 1;
|
||||
|
||||
dev->dma_conf.val = 0;
|
||||
dev->dma_conf.slv_tx_seg_trans_clr_en = 1;
|
||||
dev->dma_conf.slv_rx_seg_trans_clr_en = 1;
|
||||
dev->dma_conf.dma_slv_seg_trans_en = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the previous operation is done.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*
|
||||
* @return true if last command is done, otherwise false.
|
||||
*/
|
||||
static inline bool gpspi_flash_ll_cmd_is_done(const spi_dev_t *dev)
|
||||
{
|
||||
return (dev->cmd.usr == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the read data from the buffer after ``gpspi_flash_ll_read`` is done.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param buffer Buffer to hold the output data
|
||||
* @param read_len Length to get out of the buffer
|
||||
*/
|
||||
static inline void gpspi_flash_ll_get_buffer_data(spi_dev_t *dev, void *buffer, uint32_t read_len)
|
||||
{
|
||||
if (((intptr_t)buffer % 4 == 0) && (read_len % 4 == 0)) {
|
||||
// If everything is word-aligned, do a faster memcpy
|
||||
memcpy(buffer, (void *)dev->data_buf, read_len);
|
||||
} else {
|
||||
// Otherwise, slow(er) path copies word by word
|
||||
int copy_len = read_len;
|
||||
for (int i = 0; i < (read_len + 3) / 4; i++) {
|
||||
int word_len = MIN(sizeof(uint32_t), copy_len);
|
||||
uint32_t word = dev->data_buf[i].buf;
|
||||
memcpy(buffer, &word, word_len);
|
||||
buffer = (void *)((intptr_t)buffer + word_len);
|
||||
copy_len -= word_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Write a word to the data buffer.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param word Data to write at address 0.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_write_word(spi_dev_t *dev, uint32_t word)
|
||||
{
|
||||
dev->data_buf[0].buf = word;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data to be written in the data buffer.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param buffer Buffer holding the data
|
||||
* @param length Length of data in bytes.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_buffer_data(spi_dev_t *dev, const void *buffer, uint32_t length)
|
||||
{
|
||||
// Load data registers, word at a time
|
||||
int num_words = (length + 3) / 4;
|
||||
for (int i = 0; i < num_words; i++) {
|
||||
uint32_t word = 0;
|
||||
uint32_t word_len = MIN(length, sizeof(word));
|
||||
memcpy(&word, buffer, word_len);
|
||||
dev->data_buf[i].buf = word;
|
||||
length -= word_len;
|
||||
buffer = (void *)((intptr_t)buffer + word_len);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger a user defined transaction. All phases, including command, address, dummy, and the data phases,
|
||||
* should be configured before this is called.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param pe_ops Is page program/erase operation or not. (not used in gpspi)
|
||||
*/
|
||||
static inline void gpspi_flash_ll_user_start(spi_dev_t *dev, bool pe_ops)
|
||||
{
|
||||
dev->cmd.update = 1;
|
||||
while (dev->cmd.update);
|
||||
dev->cmd.usr = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* In user mode, it is set to indicate that program/erase operation will be triggered.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_pe_bit(spi_dev_t *dev)
|
||||
{
|
||||
// Not supported on GPSPI
|
||||
}
|
||||
|
||||
/**
|
||||
* Set HD pin high when flash work at spi mode.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_hold_pol(spi_dev_t *dev, uint32_t pol_val)
|
||||
{
|
||||
dev->ctrl.hold_pol = pol_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether the host is idle to perform new commands.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*
|
||||
* @return true if the host is idle, otherwise false
|
||||
*/
|
||||
static inline bool gpspi_flash_ll_host_idle(const spi_dev_t *dev)
|
||||
{
|
||||
return dev->cmd.usr == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set phases for user-defined transaction to read
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_read_phase(spi_dev_t *dev)
|
||||
{
|
||||
typeof(dev->user) user = {
|
||||
.usr_mosi = 0,
|
||||
.usr_miso = 1,
|
||||
.usr_addr = 1,
|
||||
.usr_command = 1,
|
||||
};
|
||||
dev->user.val = user.val;
|
||||
}
|
||||
/*------------------------------------------------------------------------------
|
||||
* Configs
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Select which pin to use for the flash
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param pin Pin ID to use, 0-2. Set to other values to disable all the CS pins.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_cs_pin(spi_dev_t *dev, int pin)
|
||||
{
|
||||
dev->misc.cs0_dis = (pin == 0) ? 0 : 1;
|
||||
dev->misc.cs1_dis = (pin == 1) ? 0 : 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the read io mode.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param read_mode I/O mode to use in the following transactions.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_read_mode(spi_dev_t *dev, esp_flash_io_mode_t read_mode)
|
||||
{
|
||||
typeof(dev->ctrl) ctrl;
|
||||
ctrl.val = dev->ctrl.val;
|
||||
typeof(dev->user) user;
|
||||
user.val = dev->user.val;
|
||||
|
||||
ctrl.val &= ~(SPI_FCMD_QUAD_M | SPI_FADDR_QUAD_M | SPI_FREAD_QUAD_M | SPI_FCMD_DUAL_M | SPI_FADDR_DUAL_M | SPI_FREAD_DUAL_M);
|
||||
user.val &= ~(SPI_FWRITE_QUAD_M | SPI_FWRITE_DUAL_M);
|
||||
|
||||
switch (read_mode) {
|
||||
case SPI_FLASH_FASTRD:
|
||||
//the default option
|
||||
case SPI_FLASH_SLOWRD:
|
||||
break;
|
||||
case SPI_FLASH_QIO:
|
||||
ctrl.fread_quad = 1;
|
||||
ctrl.faddr_quad = 1;
|
||||
user.fwrite_quad = 1;
|
||||
break;
|
||||
case SPI_FLASH_QOUT:
|
||||
ctrl.fread_quad = 1;
|
||||
user.fwrite_quad = 1;
|
||||
break;
|
||||
case SPI_FLASH_DIO:
|
||||
ctrl.fread_dual = 1;
|
||||
ctrl.faddr_dual = 1;
|
||||
user.fwrite_dual = 1;
|
||||
break;
|
||||
case SPI_FLASH_DOUT:
|
||||
ctrl.fread_dual = 1;
|
||||
user.fwrite_dual = 1;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
dev->ctrl.val = ctrl.val;
|
||||
dev->user.val = user.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set clock frequency to work at.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param clock_val pointer to the clock value to set
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_clock(spi_dev_t *dev, gpspi_flash_ll_clock_reg_t *clock_val)
|
||||
{
|
||||
dev->clock.val = *clock_val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the input length, in bits.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param bitlen Length of input, in bits.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_miso_bitlen(spi_dev_t *dev, uint32_t bitlen)
|
||||
{
|
||||
dev->user.usr_miso = bitlen > 0;
|
||||
if (bitlen) {
|
||||
dev->ms_dlen.ms_data_bitlen = bitlen - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the output length, in bits (not including command, address and dummy
|
||||
* phases)
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param bitlen Length of output, in bits.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_mosi_bitlen(spi_dev_t *dev, uint32_t bitlen)
|
||||
{
|
||||
dev->user.usr_mosi = bitlen > 0;
|
||||
if (bitlen) {
|
||||
dev->ms_dlen.ms_data_bitlen = bitlen - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the command.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param command Command to send
|
||||
* @param bitlen Length of the command
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_command(spi_dev_t *dev, uint8_t command, uint32_t bitlen)
|
||||
{
|
||||
dev->user.usr_command = 1;
|
||||
typeof(dev->user2) user2 = {
|
||||
.usr_command_value = command,
|
||||
.usr_command_bitlen = (bitlen - 1),
|
||||
};
|
||||
dev->user2.val = user2.val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the address length that is set in register, in bits.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
*
|
||||
*/
|
||||
static inline int gpspi_flash_ll_get_addr_bitlen(spi_dev_t *dev)
|
||||
{
|
||||
return dev->user.usr_addr ? dev->user1.usr_addr_bitlen + 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address length to send, in bits. Should be called before commands that requires the address e.g. erase sector, read, write...
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param bitlen Length of the address, in bits
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_addr_bitlen(spi_dev_t *dev, uint32_t bitlen)
|
||||
{
|
||||
dev->user1.usr_addr_bitlen = (bitlen - 1);
|
||||
dev->user.usr_addr = bitlen ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address to send in user mode. Should be called before commands that requires the address e.g. erase sector, read, write...
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param addr Address to send
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_usr_address(spi_dev_t *dev, uint32_t addr, uint32_t bitlen)
|
||||
{
|
||||
// The blank region should be all ones
|
||||
uint32_t padding_ones = (bitlen == 32 ? 0 : UINT32_MAX >> bitlen);
|
||||
dev->addr.val = (addr << (32 - bitlen)) | padding_ones;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the address to send. Should be called before commands that requires the address e.g. erase sector, read, write...
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param addr Address to send
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_address(spi_dev_t *dev, uint32_t addr)
|
||||
{
|
||||
dev->addr.val = addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the length of dummy cycles.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param dummy_n Cycles of dummy phases
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_dummy(spi_dev_t *dev, uint32_t dummy_n)
|
||||
{
|
||||
dev->user.usr_dummy = dummy_n ? 1 : 0;
|
||||
if (dummy_n > 0) {
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user1, usr_dummy_cyclelen, dummy_n - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set D/Q output level during dummy phase
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param out_en whether to enable IO output for dummy phase
|
||||
* @param out_level dummy output level
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_dummy_out(spi_dev_t *dev, uint32_t out_en, uint32_t out_lev)
|
||||
{
|
||||
dev->ctrl.dummy_out = out_en;
|
||||
dev->ctrl.q_pol = out_lev;
|
||||
dev->ctrl.d_pol = out_lev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set extra hold time of CS after the clocks.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param hold_n Cycles of clocks before CS is inactive
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_hold(spi_dev_t *dev, uint32_t hold_n)
|
||||
{
|
||||
dev->user.cs_hold = (hold_n > 0 ? 1 : 0);
|
||||
if (hold_n > 0) {
|
||||
dev->user1.cs_hold_time = hold_n - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the delay of SPI clocks before the first SPI clock after the CS active edge.
|
||||
*
|
||||
* @param dev Beginning address of the peripheral registers.
|
||||
* @param cs_setup_time Delay of SPI clocks after the CS active edge, 0 to disable the setup phase.
|
||||
*/
|
||||
static inline void gpspi_flash_ll_set_cs_setup(spi_dev_t *dev, uint32_t cs_setup_time)
|
||||
{
|
||||
dev->user.cs_setup = (cs_setup_time > 0 ? 1 : 0);
|
||||
if (cs_setup_time > 0) {
|
||||
dev->user1.cs_setup_time = cs_setup_time - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate spi_flash clock frequency division parameters for register.
|
||||
*
|
||||
* @param clkdiv frequency division factor
|
||||
*
|
||||
* @return Register setting for the given clock division factor.
|
||||
*/
|
||||
static inline uint32_t gpspi_flash_ll_calculate_clock_reg(uint8_t clkdiv)
|
||||
{
|
||||
uint32_t div_parameter;
|
||||
// See comments of `clock` in `spi_struct.h`
|
||||
if (clkdiv == 1) {
|
||||
div_parameter = (1 << 31);
|
||||
} else {
|
||||
div_parameter = ((clkdiv - 1) | (((clkdiv / 2 - 1) & 0xff) << 6) | (((clkdiv - 1) & 0xff) << 12));
|
||||
}
|
||||
return div_parameter;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -1,42 +1,38 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "spimem_flash_ll.h"
|
||||
|
||||
//TODO: [ESP32H21] IDF-11609, inherit from h2, need to add gpspi functions
|
||||
#include "gpspi_flash_ll.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define spi_flash_ll_calculate_clock_reg(host_id, clock_div) (((host_id)<=SPI1_HOST) ? spimem_flash_ll_calculate_clock_reg(clock_div) \
|
||||
: 0)
|
||||
: gpspi_flash_ll_calculate_clock_reg(clock_div))
|
||||
|
||||
#define spi_flash_ll_get_source_clock_freq_mhz(host_id) (((host_id)<=SPI1_HOST) ? spimem_flash_ll_get_source_freq_mhz() : 0)
|
||||
#define spi_flash_ll_get_source_clock_freq_mhz(host_id) (((host_id)<=SPI1_HOST) ? spimem_flash_ll_get_source_freq_mhz() : GPSPI_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ)
|
||||
|
||||
#define spi_flash_ll_get_hw(host_id) (((host_id)<=SPI1_HOST ? (spi_dev_t*) spimem_flash_ll_get_hw(host_id) \
|
||||
: 0))
|
||||
: gpspi_flash_ll_get_hw(host_id)))
|
||||
|
||||
#define spi_flash_ll_hw_get_id(dev) ({int dev_id = spimem_flash_ll_hw_get_id(dev); \
|
||||
if (dev_id < 0) {\
|
||||
dev_id = 0;\
|
||||
dev_id = gpspi_flash_ll_hw_get_id(dev);\
|
||||
}\
|
||||
dev_id; \
|
||||
})
|
||||
// Since ESP32-H2, WB_mode is available, we extend 8 bits to occupy `Continuous Read Mode` bits.
|
||||
// WB_mode is available, we extend 8 bits to occupy `Continuous Read Mode` bits.
|
||||
#define SPI_FLASH_LL_CONTINUOUS_MODE_BIT_NUMS (8)
|
||||
|
||||
typedef union {
|
||||
|
1591
components/hal/esp32h21/include/hal/spi_ll.h
Normal file
1591
components/hal/esp32h21/include/hal/spi_ll.h
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
*/
|
||||
@@ -521,11 +521,8 @@ static inline void spimem_flash_ll_set_mosi_bitlen(spi_mem_dev_t *dev, uint32_t
|
||||
static inline void spimem_flash_ll_set_command(spi_mem_dev_t *dev, uint32_t command, uint32_t bitlen)
|
||||
{
|
||||
dev->user.usr_command = 1;
|
||||
typeof(dev->user2) user2 = {
|
||||
.usr_command_value = command,
|
||||
.usr_command_bitlen = (bitlen - 1),
|
||||
};
|
||||
dev->user2.val = user2.val;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_value, command);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->user2, usr_command_bitlen, (bitlen - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -560,7 +557,7 @@ static inline void spimem_flash_ll_set_addr_bitlen(spi_mem_dev_t *dev, uint32_t
|
||||
static inline void spimem_flash_ll_set_extra_address(spi_mem_dev_t *dev, uint32_t extra_addr)
|
||||
{
|
||||
dev->cache_fctrl.usr_addr_4byte = 0;
|
||||
dev->rd_status.wb_mode = extra_addr;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(dev->rd_status, wb_mode, extra_addr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -6,12 +6,10 @@
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -30,7 +28,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//NOTE: These macros are changed on h4 for build. MODIFY these when bringup flash.
|
||||
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )
|
||||
|
||||
|
@@ -1,17 +1,15 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in soc/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
@@ -28,9 +26,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//NOTE: These macros are changed on c3 for build. MODIFY these when bringup flash.
|
||||
#define gpspi_flash_ll_get_hw(host_id) ( ((host_id)==SPI2_HOST) ? &GPSPI2 : ({abort();(spi_dev_t*)0;}) )
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : -1 )
|
||||
#define gpspi_flash_ll_get_hw(host_id) (((host_id)==SPI2_HOST ? &GPSPI2 \
|
||||
: ((host_id)==SPI3_HOST ? &GPSPI3 \
|
||||
: ({abort();(spi_dev_t*)0;}))))
|
||||
|
||||
#define gpspi_flash_ll_hw_get_id(dev) ( ((dev) == (void*)&GPSPI2) ? SPI2_HOST : (\
|
||||
((dev) == (void*)&GPSPI3) ? SPI3_HOST : (\
|
||||
-1 \
|
||||
)) )
|
||||
|
||||
typedef typeof(GPSPI2.clock.val) gpspi_flash_ll_clock_reg_t;
|
||||
#define GPSPI_FLASH_LL_PERIPHERAL_FREQUENCY_MHZ (80)
|
||||
|
@@ -6,12 +6,10 @@
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in hal/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@@ -6,12 +6,10 @@
|
||||
|
||||
/*******************************************************************************
|
||||
* NOTICE
|
||||
* The Lowlevel layer for SPI Flash
|
||||
* The ll is not public api, don't use in application code.
|
||||
* See readme.md in hal/include/hal/readme.md
|
||||
******************************************************************************/
|
||||
|
||||
// The Lowlevel layer for SPI Flash
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@@ -23,29 +23,29 @@ static const char *TAG = "flash_hal";
|
||||
|
||||
static uint32_t get_flash_clock_divider(const spi_flash_hal_config_t *cfg)
|
||||
{
|
||||
const int clk_source = cfg->clock_src_freq;
|
||||
const int clk_freq_mhz = cfg->freq_mhz;
|
||||
const int src_freq_mhz = cfg->clock_src_freq;
|
||||
const int cfg_freq_mhz = cfg->freq_mhz;
|
||||
// On ESP32, ESP32-S2, ESP32-C3, we allow specific frequency 26.666MHz
|
||||
// If user passes freq_mhz like 26 or 27, it's allowed to use integer divider 3.
|
||||
// However on other chips or on other frequency, we only allow user pass frequency which
|
||||
// can be integer divided. If no, the following strategy is round up the division and
|
||||
// round down flash frequency to keep it safe.
|
||||
int best_div = 0;
|
||||
if (clk_source < clk_freq_mhz) {
|
||||
HAL_LOGE(TAG, "Target frequency %dMHz higher than supported.", clk_freq_mhz);
|
||||
if (src_freq_mhz < cfg_freq_mhz) {
|
||||
HAL_LOGE(TAG, "Target frequency %dMHz higher than src %dMHz.", cfg_freq_mhz, src_freq_mhz);
|
||||
abort();
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32C3
|
||||
if (clk_freq_mhz == 26 || clk_freq_mhz == 27) {
|
||||
if (cfg_freq_mhz == 26 || cfg_freq_mhz == 27) {
|
||||
best_div = 3;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
/* Do not use float/double as the FPU may not have been initialized yet on startup.
|
||||
* The values are in MHz, so for sure we won't have an overflow by adding them. */
|
||||
best_div = (clk_source + clk_freq_mhz - 1) / clk_freq_mhz;
|
||||
best_div = (src_freq_mhz + cfg_freq_mhz - 1) / cfg_freq_mhz;
|
||||
/* Perform a division that returns both quotient and remainder */
|
||||
const div_t res = div(clk_source, clk_freq_mhz);
|
||||
const div_t res = div(src_freq_mhz, cfg_freq_mhz);
|
||||
if (res.rem != 0) {
|
||||
HAL_LOGW(TAG, "Flash clock frequency round down to %d", res.quot);
|
||||
}
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 */
|
||||
|
@@ -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 {{
|
||||
|
@@ -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)
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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 <stdint.h>
|
||||
#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.
|
||||
*/
|
||||
|
85
components/soc/esp32h21/spi_periph.c
Normal file
85
components/soc/esp32h21/spi_periph.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#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),
|
||||
},
|
||||
};
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -88,7 +88,7 @@
|
||||
#define HSPI_PIN_NUM_WP FSPI_PIN_NUM_WP
|
||||
#define HSPI_PIN_NUM_CS FSPI_PIN_NUM_CS
|
||||
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||
#elif CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32H21
|
||||
|
||||
#define FSPI_PIN_NUM_MOSI 5
|
||||
#define FSPI_PIN_NUM_MISO 0
|
||||
|
@@ -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
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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.
|
||||
|
||||
|
@@ -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
|
||||
------------
|
||||
|
@@ -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),可能影响传输事务持续时间。
|
||||
|
||||
|
@@ -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 交换矩阵路由。
|
||||
|
||||
|
@@ -6,7 +6,7 @@ ESP 串行从机链路
|
||||
概述
|
||||
----
|
||||
|
||||
乐鑫有多款芯片可用作从机的芯片。这些从机依赖于一些通用总线,并在总线上实现了各自的通信协议。 ``esp_serial_slave_link`` 组件能让主机通过总线驱动和相应的协议与 ESP 从机进行通信。
|
||||
乐鑫有多款芯片可用作从机。这些从机依赖于一些通用总线,并在总线上实现了各自的通信协议。 ``esp_serial_slave_link`` 组件能让主机通过总线驱动和相应的协议与 ESP 从机进行通信。
|
||||
|
||||
``esp_serial_slave_link`` 设备初始化完成后,应用程序就能通过它与 ESP 从机方便地通信。
|
||||
|
||||
|
@@ -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 |
|
||||
+---------+------------+-----------+-----------+------+------+----------------+
|
||||
|
||||
概述
|
||||
----
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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
|
||||
|
@@ -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 |
|
||||
| ----------------- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- |
|
||||
|
@@ -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)
|
||||
|
||||
|
Reference in New Issue
Block a user