feat(driver_spi): support gpio reserved check

This commit is contained in:
wanckl
2025-04-25 20:55:20 +08:00
parent a952037d82
commit 4c11e81fd9
8 changed files with 240 additions and 272 deletions

View File

@ -97,26 +97,31 @@ typedef spi_common_dma_t spi_dma_chan_t;
*/
typedef struct {
union {
int mosi_io_num; ///< GPIO pin for Master Out Slave In (=spi_d) signal, or -1 if not used.
int data0_io_num; ///< GPIO pin for spi data0 signal in quad/octal mode, or -1 if not used.
struct {
union {
int mosi_io_num; ///< [0] GPIO pin for Master Out Slave In (=spi_d) signal, or -1 if not used.
int data0_io_num; ///< [0] GPIO pin for spi data0 signal in dual/quad/octal mode, or -1 if not used.
};
union {
int miso_io_num; ///< [1] GPIO pin for Master In Slave Out (=spi_q) signal, or -1 if not used.
int data1_io_num; ///< [1] GPIO pin for spi data1 signal in dual/quad/octal mode, or -1 if not used.
};
int sclk_io_num; ///< [2] GPIO pin for SPI Clock signal, or -1 if not used.
union {
int quadwp_io_num; ///< [3] GPIO pin for WP (Write Protect) signal, or -1 if not used.
int data2_io_num; ///< [3] GPIO pin for spi data2 signal in quad/octal mode, or -1 if not used.
};
union {
int quadhd_io_num; ///< [4] GPIO pin for HD (Hold) signal, or -1 if not used.
int data3_io_num; ///< [4] GPIO pin for spi data3 signal in quad/octal mode, or -1 if not used.
};
int data4_io_num; ///< [5] GPIO pin for spi data4 signal in octal mode, or -1 if not used.
int data5_io_num; ///< [6] GPIO pin for spi data5 signal in octal mode, or -1 if not used.
int data6_io_num; ///< [7] GPIO pin for spi data6 signal in octal mode, or -1 if not used.
int data7_io_num; ///< [8] GPIO pin for spi data7 signal in octal mode, or -1 if not used.
};
int iocfg[9]; ///< GPIO config in array format follow the above order.
};
union {
int miso_io_num; ///< GPIO pin for Master In Slave Out (=spi_q) signal, or -1 if not used.
int data1_io_num; ///< GPIO pin for spi data1 signal in quad/octal mode, or -1 if not used.
};
int sclk_io_num; ///< GPIO pin for SPI Clock signal, or -1 if not used.
union {
int quadwp_io_num; ///< GPIO pin for WP (Write Protect) signal, or -1 if not used.
int data2_io_num; ///< GPIO pin for spi data2 signal in quad/octal mode, or -1 if not used.
};
union {
int quadhd_io_num; ///< GPIO pin for HD (Hold) signal, or -1 if not used.
int data3_io_num; ///< GPIO pin for spi data3 signal in quad/octal mode, or -1 if not used.
};
int data4_io_num; ///< GPIO pin for spi data4 signal in octal mode, or -1 if not used.
int data5_io_num; ///< GPIO pin for spi data5 signal in octal mode, or -1 if not used.
int data6_io_num; ///< GPIO pin for spi data6 signal in octal mode, or -1 if not used.
int data7_io_num; ///< GPIO pin for spi data7 signal in octal mode, or -1 if not used.
bool data_io_default_level; ///< Output data IO default level when no transaction.
int max_transfer_sz; ///< Maximum transfer size, in bytes. Defaults to 4092 if 0 when DMA enabled, or to `SOC_SPI_MAXIMUM_BUFFER_SIZE` if DMA is disabled.
uint32_t flags; ///< Abilities of bus to be checked by the driver. Or-ed value of ``SPICOMMON_BUSFLAG_*`` flags.

View File

@ -53,6 +53,7 @@ typedef enum {
/// Attributes of an SPI bus
typedef struct {
spi_bus_config_t bus_cfg; ///< Config used to initialize the bus
uint64_t gpio_reserve; ///< reserved output gpio bit mask
uint32_t flags; ///< Flags (attributes) of the bus
int max_transfer_sz; ///< Maximum length of bytes available to send
bool dma_enabled; ///< To enable DMA or not
@ -156,49 +157,44 @@ esp_err_t spicommon_dma_chan_free(spi_dma_ctx_t *dma_ctx);
* - ``SPICOMMON_BUSFLAG_QUAD``: Combination of ``SPICOMMON_BUSFLAG_DUAL`` and ``SPICOMMON_BUSFLAG_WPHD``.
* - ``SPICOMMON_BUSFLAG_IO4_IO7``: The bus has spi data4 ~ spi data7 connected.
* - ``SPICOMMON_BUSFLAG_OCTAL``: Combination of ``SPICOMMON_BUSFLAG_QUAL`` and ``SPICOMMON_BUSFLAG_IO4_IO7``.
* @param[out] io_reserved Output the reserved gpio map
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_OK on success
*/
esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, uint32_t flags, uint32_t *flags_o);
esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, uint32_t flags, uint32_t *flags_o, uint64_t *io_reserved);
/**
* @brief Free the IO used by a SPI peripheral
*
* @param bus_cfg Bus config struct which defines which pins to be used.
* @param io_reserved Bitmap indicate which pin is reserved
*
* @return
* - ESP_ERR_INVALID_ARG if parameter is invalid
* - ESP_OK on success
*/
esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg);
esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg, uint64_t *io_reserved);
/**
* @brief Initialize a Chip Select pin for a specific SPI peripheral
*
* @param host SPI peripheral
* @param cs_io_num GPIO pin to route
* @param cs_num CS id to route
* @param cs_id Hardware CS id to route
* @param force_gpio_matrix If true, CS will always be routed through the GPIO matrix. If false,
* if the GPIO number allows it, the routing will happen through the IO_mux.
* @param[out] io_reserved Output the reserved gpio map
*/
void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, int force_gpio_matrix);
void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_id, int force_gpio_matrix, uint64_t *io_reserved);
/**
* @brief Free a chip select line
*
* @param cs_gpio_num CS gpio num to free
* @param io_reserved Bitmap indicate which pin is reserved
*/
void spicommon_cs_free_io(int cs_gpio_num);
/**
* @brief Check whether all pins used by a host are through IOMUX.
*
* @param host SPI peripheral
*
* @return false if any pins are through the GPIO matrix, otherwise true.
*/
bool spicommon_bus_using_iomux(spi_host_device_t host);
void spicommon_cs_free_io(int cs_gpio_num, uint64_t *io_reserved);
/**
* @brief Get the IRQ source for a specific SPI host
@ -298,8 +294,7 @@ const spi_dma_ctx_t* spi_bus_get_dma_ctx(spi_host_device_t host_id);
* @param arg The argument to call the destructor
* @return Always ESP_OK.
*/
esp_err_t spi_bus_register_destroy_func(spi_host_device_t host_id,
spi_destroy_func_t f, void *arg);
esp_err_t spi_bus_register_destroy_func(spi_host_device_t host_id, spi_destroy_func_t f, void *arg);
#ifdef __cplusplus
}

View File

@ -17,6 +17,7 @@
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_private/gpio.h"
#include "esp_private/esp_gpio_reserve.h"
#include "esp_private/periph_ctrl.h"
#include "esp_private/spi_common_internal.h"
#include "esp_private/spi_share_hw_ctrl.h"
@ -24,7 +25,6 @@
#include "esp_private/sleep_retention.h"
#include "esp_dma_utils.h"
#include "hal/spi_hal.h"
#include "hal/gpio_hal.h"
#if CONFIG_IDF_TARGET_ESP32
#include "soc/dport_reg.h"
#endif
@ -41,9 +41,9 @@
#define SPI_COMMON_MALLOC_CAPS (MALLOC_CAP_DEFAULT)
#endif
static const char *SPI_TAG = "spi";
static const char *SPI_TAG = "spi_common";
#define SPI_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE(a, ret_val, SPI_TAG, str)
#define SPI_CHECK(a, str, ret_val, ...) ESP_RETURN_ON_FALSE(a, ret_val, SPI_TAG, str, ##__VA_ARGS__)
#define SPI_CHECK_PIN(pin_num, pin_name, check_output) if (check_output) { \
SPI_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(pin_num), pin_name" not valid", ESP_ERR_INVALID_ARG); \
} else { \
@ -56,8 +56,6 @@ static const char *SPI_TAG = "spi";
}, \
}
#define FUNC_GPIO PIN_FUNC_GPIO
typedef struct {
int host_id;
_lock_t mutex; // mutex for controller
@ -80,6 +78,29 @@ static __attribute__((constructor)) void spi_bus_lock_init_main_bus(void)
}
#endif
esp_err_t spicommon_bus_alloc(spi_host_device_t host_id, const char *name)
{
SPI_CHECK(spicommon_periph_claim(host_id, name), "host already in use", ESP_ERR_INVALID_STATE);
spicommon_bus_context_t *ctx = heap_caps_calloc(1, sizeof(spicommon_bus_context_t), SPI_COMMON_MALLOC_CAPS);
if (!ctx) {
spicommon_periph_free(host_id);
return ESP_ERR_NO_MEM;
}
ctx->host_id = host_id;
bus_ctx[host_id] = ctx;
return ESP_OK;
}
esp_err_t spicommon_bus_free(spi_host_device_t host_id)
{
assert(bus_ctx[host_id]);
spicommon_periph_free(host_id);
free(bus_ctx[host_id]);
bus_ctx[host_id] = NULL;
return ESP_OK;
}
#if SOC_GDMA_SUPPORTED
//NOTE!! If both A and B are not defined, '#if (A==B)' is true, because GCC use 0 stand for undefined symbol
#if defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI)
@ -454,8 +475,8 @@ static void bus_iomux_pins_set_oct(spi_host_device_t host, const spi_bus_config_
bus_config->sclk_io_num, bus_config->data4_io_num, bus_config->data5_io_num, bus_config->data6_io_num, bus_config->data7_io_num
};
int io_signals[] = {spi_periph_signal[host].spid_in, spi_periph_signal[host].spiq_in, spi_periph_signal[host].spiwp_in,
spi_periph_signal[host].spihd_in, spi_periph_signal[host].spiclk_in, spi_periph_signal[host].spid4_out,
spi_periph_signal[host].spid5_out, spi_periph_signal[host].spid6_out, spi_periph_signal[host].spid7_out
spi_periph_signal[host].spihd_in, spi_periph_signal[host].spiclk_in, spi_periph_signal[host].spid4_in,
spi_periph_signal[host].spid5_in, spi_periph_signal[host].spid6_in, spi_periph_signal[host].spid7_in
};
for (size_t i = 0; i < sizeof(io_nums) / sizeof(io_nums[0]); i++) {
if (io_nums[i] > 0) {
@ -491,15 +512,28 @@ static void bus_iomux_pins_set_quad(spi_host_device_t host, const spi_bus_config
}
}
static void bus_iomux_pins_set(spi_host_device_t host, const spi_bus_config_t* bus_config)
// check if the GPIO is already used by others
static void s_spi_common_gpio_check_reserve(gpio_num_t gpio_num)
{
#if SOC_SPI_SUPPORT_OCT
if ((bus_config->flags & SPICOMMON_BUSFLAG_OCTAL) == SPICOMMON_BUSFLAG_OCTAL) {
bus_iomux_pins_set_oct(host, bus_config);
return;
uint64_t orig_occupied_map = esp_gpio_reserve(BIT64(gpio_num));
if (orig_occupied_map & BIT64(gpio_num)) {
ESP_LOGW(SPI_TAG, "GPIO %d is conflict with others and be overwritten", gpio_num);
}
#endif
bus_iomux_pins_set_quad(host, bus_config);
}
static void s_spi_common_bus_via_gpio(gpio_num_t gpio_num, int in_sig, int out_sig, uint64_t *io_mask)
{
if (in_sig != -1) {
gpio_input_enable(gpio_num);
esp_rom_gpio_connect_in_signal(gpio_num, in_sig, false);
}
if (out_sig != -1) {
// For gpio_matrix, reserve output pins, see 'esp_gpio_reserve.h'
*io_mask |= BIT64(gpio_num);
s_spi_common_gpio_check_reserve(gpio_num);
esp_rom_gpio_connect_out_signal(gpio_num, out_sig, false, false);
}
gpio_func_sel(gpio_num, PIN_FUNC_GPIO);
}
/*
@ -507,7 +541,7 @@ Do the common stuff to hook up a SPI host to a bus defined by a bunch of GPIO pi
bus config struct and it'll set up the GPIO matrix and enable the device. If a pin is set to non-negative value,
it should be able to be initialized.
*/
esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, uint32_t flags, uint32_t* flags_o)
esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_config_t *bus_config, uint32_t flags, uint32_t* flags_o, uint64_t *io_reserved)
{
#if SOC_SPI_SUPPORT_OCT
// In the driver of previous version, spi data4 ~ spi data7 are not in spi_bus_config_t struct. So the new-added pins come as 0
@ -521,55 +555,33 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
#endif //SOC_SPI_SUPPORT_OCT
uint32_t temp_flag = 0;
bool miso_need_output;
bool mosi_need_output;
bool sclk_need_output;
if ((flags & SPICOMMON_BUSFLAG_MASTER) != 0) {
//initial for master
miso_need_output = ((flags & SPICOMMON_BUSFLAG_DUAL) != 0) ? true : false;
mosi_need_output = true;
sclk_need_output = true;
} else {
//initial for slave
miso_need_output = true;
mosi_need_output = ((flags & SPICOMMON_BUSFLAG_DUAL) != 0) ? true : false;
sclk_need_output = false;
}
const bool wp_need_output = true;
const bool hd_need_output = true;
uint64_t gpio_reserv = 0;
//check pin capabilities
if (bus_config->sclk_io_num >= 0) {
temp_flag |= SPICOMMON_BUSFLAG_SCLK;
SPI_CHECK_PIN(bus_config->sclk_io_num, "sclk", sclk_need_output);
SPI_CHECK_PIN(bus_config->sclk_io_num, "sclk", (flags & SPICOMMON_BUSFLAG_MASTER));
}
if (bus_config->quadwp_io_num >= 0) {
SPI_CHECK_PIN(bus_config->quadwp_io_num, "wp", wp_need_output);
SPI_CHECK_PIN(bus_config->quadwp_io_num, "wp", true);
}
if (bus_config->quadhd_io_num >= 0) {
SPI_CHECK_PIN(bus_config->quadhd_io_num, "hd", hd_need_output);
SPI_CHECK_PIN(bus_config->quadhd_io_num, "hd", true);
}
#if SOC_SPI_SUPPORT_OCT
const bool io4_need_output = true;
const bool io5_need_output = true;
const bool io6_need_output = true;
const bool io7_need_output = true;
// set flags for OCTAL mode according to the existence of spi data4 ~ spi data7
if (io4_7_enabled) {
temp_flag |= SPICOMMON_BUSFLAG_IO4_IO7;
if (bus_config->data4_io_num >= 0) {
SPI_CHECK_PIN(bus_config->data4_io_num, "spi data4", io4_need_output);
SPI_CHECK_PIN(bus_config->data4_io_num, "spi data4", true);
}
if (bus_config->data5_io_num >= 0) {
SPI_CHECK_PIN(bus_config->data5_io_num, "spi data5", io5_need_output);
SPI_CHECK_PIN(bus_config->data5_io_num, "spi data5", true);
}
if (bus_config->data6_io_num >= 0) {
SPI_CHECK_PIN(bus_config->data6_io_num, "spi data6", io6_need_output);
SPI_CHECK_PIN(bus_config->data6_io_num, "spi data6", true);
}
if (bus_config->data7_io_num >= 0) {
SPI_CHECK_PIN(bus_config->data7_io_num, "spi data7", io7_need_output);
SPI_CHECK_PIN(bus_config->data7_io_num, "spi data7", true);
}
}
#endif //SOC_SPI_SUPPORT_OCT
@ -580,11 +592,11 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
}
if (bus_config->mosi_io_num >= 0) {
temp_flag |= SPICOMMON_BUSFLAG_MOSI;
SPI_CHECK_PIN(bus_config->mosi_io_num, "mosi", mosi_need_output);
SPI_CHECK_PIN(bus_config->mosi_io_num, "mosi", (flags & SPICOMMON_BUSFLAG_MASTER) || (temp_flag & SPICOMMON_BUSFLAG_DUAL));
}
if (bus_config->miso_io_num >= 0) {
temp_flag |= SPICOMMON_BUSFLAG_MISO;
SPI_CHECK_PIN(bus_config->miso_io_num, "miso", miso_need_output);
SPI_CHECK_PIN(bus_config->miso_io_num, "miso", !(flags & SPICOMMON_BUSFLAG_MASTER) || (temp_flag & SPICOMMON_BUSFLAG_DUAL));
}
//set flags for DUAL mode according to output-capability of MOSI and MISO pins.
if ((bus_config->mosi_io_num < 0 || GPIO_IS_VALID_OUTPUT_GPIO(bus_config->mosi_io_num)) &&
@ -629,91 +641,64 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
ESP_LOGE(SPI_TAG, "spi data4 ~ spi data7 are required.");
}
#endif
SPI_CHECK(missing_flag == 0, "not all required capabilities satisfied.", ESP_ERR_INVALID_ARG);
SPI_CHECK(false, "not all required capabilities satisfied.", ESP_ERR_INVALID_ARG);
}
ESP_LOGD(SPI_TAG, "SPI%d use %s.", host + 1, use_iomux ? "iomux pins" : "gpio matrix");
if (use_iomux) {
//All SPI iomux pin selections resolve to 1, so we put that here instead of trying to figure
//out which FUNC_GPIOx_xSPIxx to grab; they all are defined to 1 anyway.
ESP_LOGD(SPI_TAG, "SPI%d use iomux pins.", host + 1);
bus_iomux_pins_set(host, bus_config);
//out which PIN_FUNC_GPIOx_xSPIxx to grab; they all are defined to 1 anyway.
for (uint8_t i = 0; i < sizeof(bus_config->iocfg) / sizeof(bus_config->iocfg[0]); i++) {
if (!(flags & SPICOMMON_BUSFLAG_OCTAL) && (i >= 4)) {
break;
}
// For iomux, reserve all configured pins
if (GPIO_IS_VALID_GPIO(bus_config->iocfg[i])) {
gpio_reserv |= BIT64(bus_config->iocfg[i]);
s_spi_common_gpio_check_reserve(bus_config->iocfg[i]);
}
}
bus_iomux_pins_set_quad(host, bus_config);
#if SOC_SPI_SUPPORT_OCT
if (flags & SPICOMMON_BUSFLAG_OCTAL) {
bus_iomux_pins_set_oct(host, bus_config);
}
#endif
} else {
//Use GPIO matrix
ESP_LOGD(SPI_TAG, "SPI%d use gpio matrix.", host + 1);
if (bus_config->mosi_io_num >= 0) {
if (mosi_need_output || (temp_flag & SPICOMMON_BUSFLAG_DUAL)) {
gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT_OUTPUT);
esp_rom_gpio_connect_out_signal(bus_config->mosi_io_num, spi_periph_signal[host].spid_out, false, false);
} else {
gpio_set_direction(bus_config->mosi_io_num, GPIO_MODE_INPUT);
}
esp_rom_gpio_connect_in_signal(bus_config->mosi_io_num, spi_periph_signal[host].spid_in, false);
#if CONFIG_IDF_TARGET_ESP32S2
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->mosi_io_num]);
#endif
gpio_func_sel(bus_config->mosi_io_num, FUNC_GPIO);
int in_sig = (!(flags & SPICOMMON_BUSFLAG_MASTER) || (temp_flag & SPICOMMON_BUSFLAG_DUAL)) ? spi_periph_signal[host].spid_in : -1;
int out_sig = ((flags & SPICOMMON_BUSFLAG_MASTER) || (temp_flag & SPICOMMON_BUSFLAG_DUAL)) ? spi_periph_signal[host].spid_out : -1;
s_spi_common_bus_via_gpio(bus_config->mosi_io_num, in_sig, out_sig, &gpio_reserv);
}
if (bus_config->miso_io_num >= 0) {
if (miso_need_output || (temp_flag & SPICOMMON_BUSFLAG_DUAL)) {
gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT_OUTPUT);
esp_rom_gpio_connect_out_signal(bus_config->miso_io_num, spi_periph_signal[host].spiq_out, false, false);
} else {
gpio_set_direction(bus_config->miso_io_num, GPIO_MODE_INPUT);
}
esp_rom_gpio_connect_in_signal(bus_config->miso_io_num, spi_periph_signal[host].spiq_in, false);
#if CONFIG_IDF_TARGET_ESP32S2
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->miso_io_num]);
#endif
gpio_func_sel(bus_config->miso_io_num, FUNC_GPIO);
}
if (bus_config->quadwp_io_num >= 0) {
gpio_set_direction(bus_config->quadwp_io_num, GPIO_MODE_INPUT_OUTPUT);
esp_rom_gpio_connect_out_signal(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_out, false, false);
esp_rom_gpio_connect_in_signal(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in, false);
#if CONFIG_IDF_TARGET_ESP32S2
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->quadwp_io_num]);
#endif
gpio_func_sel(bus_config->quadwp_io_num, FUNC_GPIO);
}
if (bus_config->quadhd_io_num >= 0) {
gpio_set_direction(bus_config->quadhd_io_num, GPIO_MODE_INPUT_OUTPUT);
esp_rom_gpio_connect_out_signal(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_out, false, false);
esp_rom_gpio_connect_in_signal(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in, false);
#if CONFIG_IDF_TARGET_ESP32S2
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->quadhd_io_num]);
#endif
gpio_func_sel(bus_config->quadhd_io_num, FUNC_GPIO);
int in_sig = ((flags & SPICOMMON_BUSFLAG_MASTER) || (temp_flag & SPICOMMON_BUSFLAG_DUAL)) ? spi_periph_signal[host].spiq_in : -1;
int out_sig = (!(flags & SPICOMMON_BUSFLAG_MASTER) || (temp_flag & SPICOMMON_BUSFLAG_DUAL)) ? spi_periph_signal[host].spiq_out : -1;
s_spi_common_bus_via_gpio(bus_config->miso_io_num, in_sig, out_sig, &gpio_reserv);
}
if (bus_config->sclk_io_num >= 0) {
if (sclk_need_output) {
gpio_set_direction(bus_config->sclk_io_num, GPIO_MODE_INPUT_OUTPUT);
esp_rom_gpio_connect_out_signal(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_out, false, false);
} else {
gpio_set_direction(bus_config->sclk_io_num, GPIO_MODE_INPUT);
}
esp_rom_gpio_connect_in_signal(bus_config->sclk_io_num, spi_periph_signal[host].spiclk_in, false);
#if CONFIG_IDF_TARGET_ESP32S2
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[bus_config->sclk_io_num]);
#endif
gpio_func_sel(bus_config->sclk_io_num, FUNC_GPIO);
int in_sig = (flags & SPICOMMON_BUSFLAG_MASTER) ? -1 : spi_periph_signal[host].spiclk_in;
int out_sig = (flags & SPICOMMON_BUSFLAG_MASTER) ? spi_periph_signal[host].spiclk_out : -1;
s_spi_common_bus_via_gpio(bus_config->sclk_io_num, in_sig, out_sig, &gpio_reserv);
}
if (bus_config->quadwp_io_num >= 0) {
s_spi_common_bus_via_gpio(bus_config->quadwp_io_num, spi_periph_signal[host].spiwp_in, spi_periph_signal[host].spiwp_out, &gpio_reserv);
}
if (bus_config->quadhd_io_num >= 0) {
s_spi_common_bus_via_gpio(bus_config->quadhd_io_num, spi_periph_signal[host].spihd_in, spi_periph_signal[host].spihd_out, &gpio_reserv);
}
#if SOC_SPI_SUPPORT_OCT
if ((flags & SPICOMMON_BUSFLAG_OCTAL) == SPICOMMON_BUSFLAG_OCTAL) {
if (flags & SPICOMMON_BUSFLAG_OCTAL) {
int io_nums[] = {bus_config->data4_io_num, bus_config->data5_io_num, bus_config->data6_io_num, bus_config->data7_io_num};
uint8_t io_signals[4][2] = {{spi_periph_signal[host].spid4_out, spi_periph_signal[host].spid4_in},
uint8_t io_signals[4][2] = {
{spi_periph_signal[host].spid4_out, spi_periph_signal[host].spid4_in},
{spi_periph_signal[host].spid5_out, spi_periph_signal[host].spid5_in},
{spi_periph_signal[host].spid6_out, spi_periph_signal[host].spid6_in},
{spi_periph_signal[host].spid7_out, spi_periph_signal[host].spid7_in}
};
for (size_t i = 0; i < sizeof(io_nums) / sizeof(io_nums[0]); i++) {
if (io_nums[i] >= 0) {
gpio_set_direction(io_nums[i], GPIO_MODE_INPUT_OUTPUT);
esp_rom_gpio_connect_out_signal(io_nums[i], io_signals[i][0], false, false);
esp_rom_gpio_connect_in_signal(io_nums[i], io_signals[i][1], false);
#if CONFIG_IDF_TARGET_ESP32S2
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[io_nums[i]]);
#endif
gpio_func_sel(io_nums[i], FUNC_GPIO);
s_spi_common_bus_via_gpio(io_nums[i], io_signals[i][1], io_signals[i][0], &gpio_reserv);
}
}
}
@ -723,64 +708,64 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
if (flags_o) {
*flags_o = temp_flag;
}
if (io_reserved) {
*io_reserved |= gpio_reserv;
}
return ESP_OK;
}
esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg)
esp_err_t spicommon_bus_free_io_cfg(const spi_bus_config_t *bus_cfg, uint64_t *io_reserved)
{
int pin_array[] = {
bus_cfg->mosi_io_num,
bus_cfg->miso_io_num,
bus_cfg->sclk_io_num,
bus_cfg->quadwp_io_num,
bus_cfg->quadhd_io_num,
};
for (int i = 0; i < sizeof(pin_array) / sizeof(int); i ++) {
const int io = pin_array[i];
if (GPIO_IS_VALID_GPIO(io)) {
gpio_reset_pin(io);
for (uint8_t i = 0; i < sizeof(bus_cfg->iocfg) / sizeof(bus_cfg->iocfg[0]); i++) {
#if !SOC_SPI_SUPPORT_OCT
if (i > 4) {
break;
}
#endif
if (GPIO_IS_VALID_GPIO(bus_cfg->iocfg[i]) && (*io_reserved & BIT64(bus_cfg->iocfg[i]))) {
*io_reserved &= ~BIT64(bus_cfg->iocfg[i]);
gpio_output_disable(bus_cfg->iocfg[i]);
esp_gpio_revoke(BIT64(bus_cfg->iocfg[i]));
}
}
return ESP_OK;
}
void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num, int force_gpio_matrix)
void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_id, int force_gpio_matrix, uint64_t *io_reserved)
{
if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_num == 0) {
uint64_t out_mask = 0;
if (!force_gpio_matrix && cs_io_num == spi_periph_signal[host].spics0_iomux_pin && cs_id == 0) {
out_mask |= BIT64(cs_io_num);
s_spi_common_gpio_check_reserve(cs_io_num);
//The cs0s for all SPI peripherals map to pin mux source 1, so we use that instead of a define.
gpio_iomux_input(cs_io_num, spi_periph_signal[host].func, spi_periph_signal[host].spics_in);
gpio_iomux_output(cs_io_num, spi_periph_signal[host].func);
} else {
//Use GPIO matrix
if (GPIO_IS_VALID_OUTPUT_GPIO(cs_io_num)) {
gpio_set_direction(cs_io_num, GPIO_MODE_INPUT_OUTPUT);
esp_rom_gpio_connect_out_signal(cs_io_num, spi_periph_signal[host].spics_out[cs_num], false, false);
} else {
gpio_set_direction(cs_io_num, GPIO_MODE_INPUT);
out_mask |= BIT64(cs_io_num);
s_spi_common_gpio_check_reserve(cs_io_num);
esp_rom_gpio_connect_out_signal(cs_io_num, spi_periph_signal[host].spics_out[cs_id], false, false);
}
if (cs_num == 0) {
// cs_id 0 is always used by slave for input
if (cs_id == 0) {
gpio_input_enable(cs_io_num);
esp_rom_gpio_connect_in_signal(cs_io_num, spi_periph_signal[host].spics_in, false);
}
#if CONFIG_IDF_TARGET_ESP32S2
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[cs_io_num]);
#endif
gpio_func_sel(cs_io_num, FUNC_GPIO);
gpio_func_sel(cs_io_num, PIN_FUNC_GPIO);
}
if (io_reserved) {
*io_reserved |= out_mask;
}
}
void spicommon_cs_free_io(int cs_gpio_num)
void spicommon_cs_free_io(int cs_gpio_num, uint64_t *io_reserved)
{
assert(GPIO_IS_VALID_GPIO(cs_gpio_num));
gpio_reset_pin(cs_gpio_num);
}
bool spicommon_bus_using_iomux(spi_host_device_t host)
{
CHECK_IOMUX_PIN(host, spid);
CHECK_IOMUX_PIN(host, spiq);
CHECK_IOMUX_PIN(host, spiwp);
CHECK_IOMUX_PIN(host, spihd);
return true;
if (GPIO_IS_VALID_GPIO(cs_gpio_num) && (*io_reserved & BIT64(cs_gpio_num))) {
*io_reserved &= ~BIT64(cs_gpio_num);
gpio_output_disable(cs_gpio_num);
esp_gpio_revoke(BIT64(cs_gpio_num));
}
}
spi_bus_lock_handle_t spi_bus_lock_get_by_id(spi_host_device_t host_id)
@ -802,9 +787,6 @@ static esp_err_t s_bus_create_sleep_retention_cb(void *arg)
esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t *bus_config, spi_dma_chan_t dma_chan)
{
esp_err_t err = ESP_OK;
spicommon_bus_context_t *ctx = NULL;
spi_bus_attr_t *bus_attr = NULL;
SPI_CHECK(is_valid_host(host_id), "invalid host_id", ESP_ERR_INVALID_ARG);
SPI_CHECK(bus_ctx[host_id] == NULL, "SPI bus already initialized.", ESP_ERR_INVALID_STATE);
#ifdef CONFIG_IDF_TARGET_ESP32
@ -822,18 +804,9 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t *
SPI_CHECK((bus_config->data_io_default_level == 0), "no support changing io default level ", ESP_ERR_INVALID_ARG);
#endif
bool spi_chan_claimed = spicommon_periph_claim(host_id, "spi master");
SPI_CHECK(spi_chan_claimed, "host_id already in use", ESP_ERR_INVALID_STATE);
//clean and initialize the context
ctx = (spicommon_bus_context_t *)heap_caps_calloc(1, sizeof(spicommon_bus_context_t), SPI_COMMON_MALLOC_CAPS);
if (!ctx) {
err = ESP_ERR_NO_MEM;
goto cleanup;
}
bus_ctx[host_id] = ctx;
ctx->host_id = host_id;
bus_attr = &ctx->bus_attr;
ESP_RETURN_ON_ERROR(spicommon_bus_alloc(host_id, "spi master"), SPI_TAG, "alloc host failed");
spi_bus_attr_t *bus_attr = (spi_bus_attr_t *)spi_bus_get_attr(host_id);
spicommon_bus_context_t *ctx = __containerof(bus_attr, spicommon_bus_context_t, bus_attr);
bus_attr->bus_cfg = *bus_config;
if (dma_chan != SPI_DMA_DISABLED) {
@ -908,7 +881,7 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t *
}
#endif //CONFIG_PM_ENABLE
err = spicommon_bus_initialize_io(host_id, bus_config, SPICOMMON_BUSFLAG_MASTER | bus_config->flags, &bus_attr->flags);
err = spicommon_bus_initialize_io(host_id, bus_config, SPICOMMON_BUSFLAG_MASTER | bus_config->flags, &bus_attr->flags, &bus_attr->gpio_reserve);
if (err != ESP_OK) {
goto cleanup;
}
@ -930,9 +903,7 @@ cleanup:
ctx->dma_ctx = NULL;
}
}
spicommon_periph_free(host_id);
free(bus_ctx[host_id]);
bus_ctx[host_id] = NULL;
spicommon_bus_free(host_id);
return err;
}
@ -979,7 +950,7 @@ esp_err_t spi_bus_free(spi_host_device_t host_id)
return err;
}
}
spicommon_bus_free_io_cfg(&bus_attr->bus_cfg);
spicommon_bus_free_io_cfg(&bus_attr->bus_cfg, &bus_attr->gpio_reserve);
#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
const periph_retention_module_t retention_id = spi_reg_retention_info[host_id - 1].module_id;
@ -1006,9 +977,7 @@ esp_err_t spi_bus_free(spi_host_device_t host_id)
spicommon_dma_chan_free(ctx->dma_ctx);
ctx->dma_ctx = NULL;
}
spicommon_periph_free(host_id);
free(ctx);
bus_ctx[host_id] = NULL;
spicommon_bus_free(host_id);
return err;
}

View File

@ -527,7 +527,7 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
//Set CS pin, CS options
if (dev_config->spics_io_num >= 0) {
spicommon_cs_initialize(host_id, dev_config->spics_io_num, freecs, use_gpio);
spicommon_cs_initialize(host_id, dev_config->spics_io_num, freecs, use_gpio, (uint64_t *)&bus_attr->gpio_reserve);
}
//save a pointer to device in spi_host_t
@ -605,8 +605,9 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle)
//return
int spics_io_num = handle->cfg.spics_io_num;
const spi_bus_attr_t* bus_attr = handle->host->bus_attr;
if (spics_io_num >= 0) {
spicommon_cs_free_io(spics_io_num);
spicommon_cs_free_io(spics_io_num, (uint64_t *)&bus_attr->gpio_reserve);
}
//Kill queues

View File

@ -61,6 +61,7 @@ typedef struct {
typedef struct {
int id;
_Atomic spi_bus_fsm_t fsm;
uint64_t gpio_reserve;
spi_bus_config_t bus_config;
spi_dma_ctx_t *dma_ctx;
spi_slave_interface_config_t cfg;
@ -145,7 +146,6 @@ static esp_err_t s_spi_create_sleep_retention_cb(void *arg)
esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *bus_config, const spi_slave_interface_config_t *slave_config, spi_dma_chan_t dma_chan)
{
bool spi_chan_claimed;
esp_err_t ret = ESP_OK;
esp_err_t err;
SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG);
@ -167,16 +167,13 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
SPI_CHECK(slave_config->post_trans_cb != NULL, "use feature flag 'SPI_SLAVE_NO_RETURN_RESULT' but no post_trans_cb function sets", ESP_ERR_INVALID_ARG);
}
spi_chan_claimed = spicommon_periph_claim(host, "spi slave");
SPI_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
SPI_CHECK(spicommon_periph_claim(host, "spi slave"), "host already in use", ESP_ERR_INVALID_STATE);
// spi_slave_t contains atomic variable, memory must be allocated from internal memory
spihost[host] = heap_caps_malloc(sizeof(spi_slave_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
spihost[host] = heap_caps_calloc(1, sizeof(spi_slave_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (spihost[host] == NULL) {
ret = ESP_ERR_NO_MEM;
goto cleanup;
}
memset(spihost[host], 0, sizeof(spi_slave_t));
memcpy(&spihost[host]->cfg, slave_config, sizeof(spi_slave_interface_config_t));
memcpy(&spihost[host]->bus_config, bus_config, sizeof(spi_bus_config_t));
spihost[host]->id = host;
@ -210,13 +207,13 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
spihost[host]->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE;
}
err = spicommon_bus_initialize_io(host, bus_config, SPICOMMON_BUSFLAG_SLAVE | bus_config->flags, &spihost[host]->flags);
err = spicommon_bus_initialize_io(host, bus_config, SPICOMMON_BUSFLAG_SLAVE | bus_config->flags, &spihost[host]->flags, &spihost[host]->gpio_reserve);
if (err != ESP_OK) {
ret = err;
goto cleanup;
}
if (slave_config->spics_io_num >= 0) {
spicommon_cs_initialize(host, slave_config->spics_io_num, 0, !bus_is_iomux(spihost[host]));
spicommon_cs_initialize(host, slave_config->spics_io_num, 0, !bus_is_iomux(spihost[host]), &spihost[host]->gpio_reserve);
// check and save where cs line really route through
spihost[host]->cs_iomux = (slave_config->spics_io_num == spi_periph_signal[host].spics0_iomux_pin) && bus_is_iomux(spihost[host]);
spihost[host]->cs_in_signal = spi_periph_signal[host].spics_in;
@ -334,7 +331,10 @@ esp_err_t spi_slave_free(spi_host_device_t host)
free(spihost[host]->dma_ctx->dmadesc_rx);
spicommon_dma_chan_free(spihost[host]->dma_ctx);
}
spicommon_bus_free_io_cfg(&spihost[host]->bus_config);
spicommon_bus_free_io_cfg(&spihost[host]->bus_config, &spihost[host]->gpio_reserve);
if (spihost[host]->cfg.spics_io_num >= 0) {
spicommon_cs_free_io(spihost[host]->cfg.spics_io_num, &spihost[host]->gpio_reserve);
}
esp_intr_free(spihost[host]->intr);
#if SOC_SPI_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP

View File

@ -44,6 +44,9 @@ typedef struct {
typedef struct {
spi_host_device_t host_id;
spi_bus_config_t bus_config;
int cs_io_num;
uint64_t gpio_reserve;
_Atomic spi_bus_fsm_t fsm;
spi_dma_ctx_t *dma_ctx;
uint16_t internal_mem_align_size;
@ -100,7 +103,6 @@ static esp_err_t s_spi_create_sleep_retention_cb(void *arg)
esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *bus_config, const spi_slave_hd_slot_config_t *config)
{
bool spi_chan_claimed;
bool append_mode = (config->flags & SPI_SLAVE_HD_APPEND_MODE);
esp_err_t ret = ESP_OK;
@ -115,9 +117,8 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b
SPIHD_CHECK((bus_config->intr_flags & ESP_INTR_FLAG_IRAM) == 0, "ESP_INTR_FLAG_IRAM should be disabled when CONFIG_SPI_SLAVE_ISR_IN_IRAM is not set.", ESP_ERR_INVALID_ARG);
#endif
spi_chan_claimed = spicommon_periph_claim(host_id, "slave_hd");
SPIHD_CHECK(spi_chan_claimed, "host already in use", ESP_ERR_INVALID_STATE);
SPIHD_CHECK(spicommon_periph_claim(host_id, "slave_hd"), "host already in use", ESP_ERR_INVALID_STATE);
// spi_slave_hd_slot_t contains atomic variable, memory must be allocated from internal memory
spi_slave_hd_slot_t *host = heap_caps_calloc(1, sizeof(spi_slave_hd_slot_t), MALLOC_CAP_INTERNAL);
if (host == NULL) {
ret = ESP_ERR_NO_MEM;
@ -128,6 +129,8 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b
host->int_spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED;
host->append_mode = append_mode;
atomic_store(&host->fsm, SPI_BUS_FSM_ENABLED);
memcpy(&host->bus_config, bus_config, sizeof(spi_bus_config_t));
host->cs_io_num = config->spics_io_num;
ret = spicommon_dma_chan_alloc(host_id, config->dma_chan, &host->dma_ctx);
if (ret != ESP_OK) {
@ -169,12 +172,11 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b
host->internal_mem_align_size = 4;
#endif
ret = spicommon_bus_initialize_io(host_id, bus_config, SPICOMMON_BUSFLAG_SLAVE | bus_config->flags, &host->flags);
ret = spicommon_bus_initialize_io(host_id, bus_config, SPICOMMON_BUSFLAG_SLAVE | bus_config->flags, &host->flags, &host->gpio_reserve);
if (ret != ESP_OK) {
goto cleanup;
}
gpio_set_direction(config->spics_io_num, GPIO_MODE_INPUT);
spicommon_cs_initialize(host_id, config->spics_io_num, 0, !(bus_config->flags & SPICOMMON_BUSFLAG_NATIVE_PINS));
spicommon_cs_initialize(host_id, config->spics_io_num, 0, !(bus_config->flags & SPICOMMON_BUSFLAG_NATIVE_PINS), &host->gpio_reserve);
spi_slave_hd_hal_config_t hal_config = {
.host_id = host_id,
@ -347,6 +349,8 @@ esp_err_t spi_slave_hd_deinit(spi_host_device_t host_id)
}
#endif
spicommon_bus_free_io_cfg(&host->bus_config, &host->gpio_reserve);
spicommon_cs_free_io(host->cs_io_num, &host->gpio_reserve);
spicommon_periph_free(host_id);
free(host->dma_ctx->dmadesc_tx);
free(host->dma_ctx->dmadesc_rx);

View File

@ -164,7 +164,7 @@ TEST_CASE("SPI Master clk_source and divider accuracy", "[spi]")
int real_freq_khz;
spi_device_get_actual_freq(handle, &real_freq_khz);
// (byte_len * 8 / real_freq_hz) * 1000 000, (unit)us
int trans_cost_us_predict = (float)TEST_CLK_BYTE_LEN * 8 * 1000 / real_freq_khz;
int trans_cost_us_predict = (float)TEST_CLK_BYTE_LEN * 8 * 1000 / real_freq_khz + IDF_TARGET_MAX_TRANS_TIME_POLL_DMA;
// transaction and measure time
start = esp_timer_get_time();
@ -481,9 +481,9 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
ESP_LOGI(TAG, "test 4 iomux output pins...");
@ -492,9 +492,9 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
ESP_LOGI(TAG, "test 6 output pins...");
@ -504,9 +504,9 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
ESP_LOGI(TAG, "test 4 output pins...");
@ -516,9 +516,9 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
#if TEST_SOC_HAS_INPUT_ONLY_PINS //There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
@ -528,7 +528,7 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = INPUT_ONLY_PIN, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
ESP_LOGI(TAG, "test slave 5 output pins and MISO on input-only pin...");
@ -537,7 +537,7 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = INPUT_ONLY_PIN, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
ESP_LOGI(TAG, "test master 3 output pins and MOSI on input-only pin...");
@ -547,7 +547,7 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = INPUT_ONLY_PIN, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
ESP_LOGI(TAG, "test slave 3 output pins and MISO on input-only pin...");
@ -556,7 +556,7 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = INPUT_ONLY_PIN, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ESP_OK(spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
TEST_ASSERT_EQUAL_HEX32(flags_expected, flags_o);
//There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
#endif //#if TEST_SOC_HAS_INPUT_ONLY_PINS
@ -568,8 +568,8 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
ESP_LOGI(TAG, "check native flag for 4 output pins...");
flags_expected = SPICOMMON_BUSFLAG_IOMUX_PINS;
@ -578,8 +578,8 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
#if TEST_SOC_HAS_INPUT_ONLY_PINS //There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
ESP_LOGI(TAG, "check dual flag for master 5 output pins and MISO/MOSI on input-only pin...");
@ -588,14 +588,14 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = INPUT_ONLY_PIN, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
cfg = (spi_bus_config_t) {
.mosi_io_num = INPUT_ONLY_PIN, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
ESP_LOGI(TAG, "check dual flag for master 3 output pins and MISO/MOSI on input-only pin...");
flags_expected = SPICOMMON_BUSFLAG_DUAL | SPICOMMON_BUSFLAG_GPIO_PINS;
@ -603,14 +603,14 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = INPUT_ONLY_PIN, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
cfg = (spi_bus_config_t) {
.mosi_io_num = INPUT_ONLY_PIN, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = -1,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
//There is no input-only pin on esp32c3 and esp32s3, so this test could be ignored.
#endif //#if TEST_SOC_HAS_INPUT_ONLY_PINS
@ -620,8 +620,8 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = -1, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
ESP_LOGI(TAG, "check mosi flag...");
flags_expected = SPICOMMON_BUSFLAG_MOSI;
@ -629,8 +629,8 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = -1, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
ESP_LOGI(TAG, "check miso flag...");
flags_expected = SPICOMMON_BUSFLAG_MISO;
@ -638,8 +638,8 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = -1, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
ESP_LOGI(TAG, "check quad flag...");
flags_expected = SPICOMMON_BUSFLAG_QUAD;
@ -647,14 +647,14 @@ TEST_CASE("spi bus setting with different pin configs", "[spi]")
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = -1, .quadwp_io_num = spi_periph_signal[TEST_SPI_HOST].spiwp_iomux_pin,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
cfg = (spi_bus_config_t) {
.mosi_io_num = spi_periph_signal[TEST_SPI_HOST].spid_iomux_pin, .miso_io_num = spi_periph_signal[TEST_SPI_HOST].spiq_iomux_pin, .sclk_io_num = spi_periph_signal[TEST_SPI_HOST].spiclk_iomux_pin, .quadhd_io_num = spi_periph_signal[TEST_SPI_HOST].spihd_iomux_pin, .quadwp_io_num = -1,
.max_transfer_sz = 8, .flags = flags_expected
};
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_MASTER, &flags_o, NULL));
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, spicommon_bus_initialize_io(TEST_SPI_HOST, &cfg, flags_expected | SPICOMMON_BUSFLAG_SLAVE, &flags_o, NULL));
}
TEST_CASE("SPI Master no response when switch from host1 (SPI2) to host2 (SPI3)", "[spi]")

View File

@ -1,34 +1,28 @@
# SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
# 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
from pytest_embedded_idf.utils import soc_filtered_targets
@pytest.mark.generic
@pytest.mark.parametrize('config', ['release'], indirect=True)
@idf_parametrize(
'target',
['esp32s2', 'esp32s3', 'esp32c2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32c61', 'esp32h2', 'esp32p4'],
indirect=['target'],
)
@idf_parametrize('target', soc_filtered_targets('SOC_SPI_SUPPORT_SLAVE_HD_VER2 == 1'), indirect=['target'])
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
continue # If `test_env` is define, should not run on generic runner
case_tester.run_normal_case(case=case, reset=True, timeout=180)
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.generic_multi_device
# TODO: [ESP32C61] IDF-10949
@pytest.mark.temp_skip_ci(targets=['esp32c61'], reason='no multi-dev runner')
@pytest.mark.parametrize('count, config', [(2, 'release')], indirect=True)
@idf_parametrize(
'target',
['esp32s2', 'esp32s3', 'esp32c2', 'esp32c3', 'esp32c5', 'esp32c6', 'esp32h2', 'esp32p4'],
indirect=['target'],
)
@idf_parametrize('target', soc_filtered_targets('SOC_SPI_SUPPORT_SLAVE_HD_VER2 == 1'), indirect=['target'])
def test_slave_hd_multi_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
# if `test_env` not defined, will run on `generic_multi_device` by default
if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device':
case_tester.run_multi_dev_case(case=case, reset=True)