mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 09:39:10 -04:00
Merge branch 'refactor/esp_driver_spi' into 'master'
refactor(spi): make spi driver as component Closes IDF-8371 See merge request espressif/esp-idf!26549
This commit is contained in:
commit
2b173ce727
@ -5,8 +5,7 @@ if(${target} STREQUAL "linux")
|
||||
endif()
|
||||
|
||||
# Always compiled source files
|
||||
set(srcs
|
||||
"spi/spi_bus_lock.c")
|
||||
set(srcs)
|
||||
|
||||
# Always included headers
|
||||
set(includes "include"
|
||||
@ -21,8 +20,8 @@ set(includes "include"
|
||||
"rmt/include"
|
||||
"sdio_slave/include"
|
||||
"sdmmc/include"
|
||||
"sdspi/include"
|
||||
"sigma_delta/include"
|
||||
"spi/include"
|
||||
"temperature_sensor/include"
|
||||
"touch_sensor/include"
|
||||
"twai/include"
|
||||
@ -153,19 +152,13 @@ if(CONFIG_SOC_SDM_SUPPORTED)
|
||||
"deprecated/sigma_delta_legacy.c")
|
||||
endif()
|
||||
|
||||
# SPI related source files
|
||||
# SDSPI related source files
|
||||
if(CONFIG_SOC_GPSPI_SUPPORTED)
|
||||
list(APPEND srcs "spi/gpspi/spi_common.c"
|
||||
"spi/gpspi/spi_master.c"
|
||||
"spi/gpspi/spi_slave.c"
|
||||
"spi/sdspi/sdspi_crc.c"
|
||||
"spi/sdspi/sdspi_host.c"
|
||||
"spi/sdspi/sdspi_transaction.c")
|
||||
list(APPEND srcs "sdspi/sdspi_crc.c"
|
||||
"sdspi/sdspi_host.c"
|
||||
"sdspi/sdspi_transaction.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2)
|
||||
list(APPEND srcs "spi/gpspi/spi_slave_hd.c")
|
||||
endif()
|
||||
|
||||
# Temperature Sensor related source files
|
||||
if(CONFIG_SOC_TEMP_SENSOR_SUPPORTED)
|
||||
@ -218,7 +211,7 @@ else()
|
||||
REQUIRES esp_pm esp_ringbuf freertos soc hal esp_hw_support
|
||||
# for backward compatibility, the driver component needs to
|
||||
# have a public dependency on other "esp_driver_foo" components
|
||||
esp_driver_gpio esp_driver_pcnt esp_driver_gptimer
|
||||
esp_driver_gpio esp_driver_pcnt esp_driver_gptimer esp_driver_spi
|
||||
LDFRAGMENTS ${ldfragments}
|
||||
)
|
||||
endif()
|
||||
|
@ -62,68 +62,6 @@ menu "Driver Configurations"
|
||||
|
||||
endmenu # ADC Configuration
|
||||
|
||||
menu "SPI Configuration"
|
||||
|
||||
config SPI_MASTER_IN_IRAM
|
||||
bool "Place transmitting functions of SPI master into IRAM"
|
||||
default n
|
||||
depends on !FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
select SPI_MASTER_ISR_IN_IRAM
|
||||
help
|
||||
Normally only the ISR of SPI master is placed in the IRAM, so that it
|
||||
can work without the flash when interrupt is triggered.
|
||||
For other functions, there's some possibility that the flash cache
|
||||
miss when running inside and out of SPI functions, which may increase
|
||||
the interval of SPI transactions.
|
||||
Enable this to put ``queue_trans``, ``get_trans_result`` and
|
||||
``transmit`` functions into the IRAM to avoid possible cache miss.
|
||||
|
||||
This configuration won't be available if `CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH` is enabled.
|
||||
|
||||
During unit test, this is enabled to measure the ideal case of api.
|
||||
|
||||
config SPI_MASTER_ISR_IN_IRAM
|
||||
bool "Place SPI master ISR function into IRAM"
|
||||
default y
|
||||
depends on !HEAP_PLACE_FUNCTION_INTO_FLASH
|
||||
select PERIPH_CTRL_FUNC_IN_IRAM
|
||||
select HAL_SPI_MASTER_FUNC_IN_IRAM
|
||||
help
|
||||
Place the SPI master ISR in to IRAM to avoid possible cache miss.
|
||||
|
||||
Enabling this configuration is possible only when HEAP_PLACE_FUNCTION_INTO_FLASH
|
||||
is disabled since the spi master uses can allocate transactions buffers into DMA
|
||||
memory section using the heap component API that ipso facto has to be placed in IRAM.
|
||||
|
||||
Also you can forbid the ISR being disabled during flash writing
|
||||
access, by add ESP_INTR_FLAG_IRAM when initializing the driver.
|
||||
|
||||
config SPI_SLAVE_IN_IRAM
|
||||
bool "Place transmitting functions of SPI slave into IRAM"
|
||||
default n
|
||||
select SPI_SLAVE_ISR_IN_IRAM
|
||||
help
|
||||
Normally only the ISR of SPI slave is placed in the IRAM, so that it
|
||||
can work without the flash when interrupt is triggered.
|
||||
For other functions, there's some possibility that the flash cache
|
||||
miss when running inside and out of SPI functions, which may increase
|
||||
the interval of SPI transactions.
|
||||
Enable this to put ``queue_trans``, ``get_trans_result`` and
|
||||
``transmit`` functions into the IRAM to avoid possible cache miss.
|
||||
|
||||
config SPI_SLAVE_ISR_IN_IRAM
|
||||
bool "Place SPI slave ISR function into IRAM"
|
||||
default y
|
||||
select PERIPH_CTRL_FUNC_IN_IRAM
|
||||
select HAL_SPI_SLAVE_FUNC_IN_IRAM
|
||||
help
|
||||
Place the SPI slave ISR in to IRAM to avoid possible cache miss.
|
||||
|
||||
Also you can forbid the ISR being disabled during flash writing
|
||||
access, by add ESP_INTR_FLAG_IRAM when initializing the driver.
|
||||
|
||||
endmenu # SPI Configuration
|
||||
|
||||
orsource "./twai/Kconfig.twai"
|
||||
|
||||
menu "Temperature sensor Configuration"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -65,9 +65,9 @@ typedef struct {
|
||||
gpio_num_t gpio_cd; ///< GPIO number of card detect signal
|
||||
gpio_num_t gpio_wp; ///< GPIO number of write protect signal
|
||||
gpio_num_t gpio_int; ///< GPIO number of interrupt line (input) for SDIO card.
|
||||
bool gpio_wp_polarity; ///< GPIO write protect polarity
|
||||
/// 0 means "active low", i.e. card is protected when the GPIO is low;
|
||||
/// 1 means "active high", i.e. card is protected when GPIO is high.
|
||||
bool gpio_wp_polarity; /*!< GPIO write protect polarity
|
||||
0 means "active low", i.e. card is protected when the GPIO is low;
|
||||
1 means "active high", i.e. card is protected when GPIO is high. */
|
||||
} sdspi_device_config_t;
|
||||
|
||||
#define SDSPI_SLOT_NO_CS GPIO_NUM_NC ///< indicates that card select line is not used
|
45
components/driver/sdspi/sdspi_crc.c
Normal file
45
components/driver/sdspi/sdspi_crc.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sdspi_crc.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_crc.h"
|
||||
|
||||
static const uint8_t crc7_table[256] = {
|
||||
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
|
||||
0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
|
||||
0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
|
||||
0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
|
||||
0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
|
||||
0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
|
||||
0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
|
||||
0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
|
||||
0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
|
||||
0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
|
||||
0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
|
||||
0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
|
||||
0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
|
||||
0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
|
||||
0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
|
||||
0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79,
|
||||
};
|
||||
|
||||
// returns the CRC-7 for a message of "length" bytes
|
||||
uint8_t sdspi_crc7(const uint8_t *data, size_t size)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
result = crc7_table[(result << 1) ^ data[i]];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Return CRC16 of data, in the on-the-wire format used by SD protocol
|
||||
uint16_t sdspi_crc16(const uint8_t* data, size_t size)
|
||||
{
|
||||
return __builtin_bswap16(esp_rom_crc16_be(UINT16_MAX, data, size) ^ UINT16_MAX);
|
||||
}
|
@ -12,7 +12,6 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return CRC7 of data, in the format used by SD protocol
|
||||
* @param data array of data used to compute CRC
|
||||
@ -29,7 +28,6 @@ uint8_t sdspi_crc7(const uint8_t *data, size_t size);
|
||||
*/
|
||||
uint16_t sdspi_crc16(const uint8_t* data, size_t size);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -22,7 +22,6 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "soc/soc_memory_layout.h"
|
||||
|
||||
|
||||
/// Max number of transactions in flight (used in start_command_write_blocks)
|
||||
#define SDSPI_TRANSACTION_COUNT 4
|
||||
#define SDSPI_MOSI_IDLE_VAL 0xff //!< Data value which causes MOSI to stay high
|
||||
@ -67,7 +66,6 @@ static const char *TAG = "sdspi_host";
|
||||
static const bool use_polling = true;
|
||||
static const bool no_use_polling = true;
|
||||
|
||||
|
||||
/// Functions to send out different kinds of commands
|
||||
static esp_err_t start_command_read_blocks(slot_info_t *slot, sdspi_hw_cmd_t *cmd,
|
||||
uint8_t *data, uint32_t rx_length, bool need_stop_command);
|
||||
@ -286,7 +284,9 @@ esp_err_t sdspi_host_deinit(void)
|
||||
for (size_t i = 0; i < sizeof(s_slots) / sizeof(s_slots[0]); ++i) {
|
||||
slot_info_t* slot = remove_slot_info(i);
|
||||
//slot isn't used, skip
|
||||
if (slot == NULL) continue;
|
||||
if (slot == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
deinit_slot(slot);
|
||||
}
|
||||
@ -553,7 +553,9 @@ static esp_err_t start_command_default(slot_info_t *slot, int flags, sdspi_hw_cm
|
||||
// we have sent and received bytes with enough length.
|
||||
// now shift the response to match the offset of sdspi_hw_cmd_t
|
||||
ret = shift_cmd_response(cmd, cmd_size);
|
||||
if (ret != ESP_OK) return ESP_ERR_TIMEOUT;
|
||||
if (ret != ESP_OK) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
if (flags & SDSPI_CMD_FLAG_RSP_R1B) {
|
||||
ret = poll_busy(slot, cmd->timeout_ms, no_use_polling);
|
||||
@ -649,9 +651,13 @@ static esp_err_t shift_cmd_response(sdspi_hw_cmd_t* cmd, int sent_bytes)
|
||||
uint8_t* pr1 = &cmd->r1;
|
||||
int ncr_cnt = 1;
|
||||
while (true) {
|
||||
if ((*pr1 & SD_SPI_R1_NO_RESPONSE) == 0) break;
|
||||
if ((*pr1 & SD_SPI_R1_NO_RESPONSE) == 0) {
|
||||
break;
|
||||
}
|
||||
pr1++;
|
||||
if (++ncr_cnt > 8) return ESP_ERR_NOT_FOUND;
|
||||
if (++ncr_cnt > 8) {
|
||||
return ESP_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
int copy_bytes = sent_bytes - SDSPI_CMD_SIZE - ncr_cnt;
|
||||
@ -662,7 +668,6 @@ static esp_err_t shift_cmd_response(sdspi_hw_cmd_t* cmd, int sent_bytes)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Receiving one or more blocks of data happens as follows:
|
||||
* 1. send command + receive r1 response (SDSPI_CMD_R1_SIZE bytes total)
|
||||
@ -920,7 +925,9 @@ static esp_err_t start_command_write_blocks(slot_info_t *slot, sdspi_hw_cmd_t *c
|
||||
}
|
||||
|
||||
uint8_t data_rsp = t_crc_rsp.rx_data[2];
|
||||
if (!SD_SPI_DATA_RSP_VALID(data_rsp)) return ESP_ERR_INVALID_RESPONSE;
|
||||
if (!SD_SPI_DATA_RSP_VALID(data_rsp)) {
|
||||
return ESP_ERR_INVALID_RESPONSE;
|
||||
}
|
||||
switch (SD_SPI_DATA_RSP(data_rsp)) {
|
||||
case SD_SPI_DATA_ACCEPTED:
|
||||
break;
|
||||
@ -976,7 +983,9 @@ esp_err_t sdspi_host_io_int_wait(sdspi_dev_handle_t handle, TickType_t timeout_t
|
||||
{
|
||||
slot_info_t* slot = get_slot_info(handle);
|
||||
//skip the interrupt and semaphore if the gpio is already low.
|
||||
if (gpio_get_level(slot->gpio_int)==0) return ESP_OK;
|
||||
if (gpio_get_level(slot->gpio_int) == 0) {
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
//clear the semaphore before wait
|
||||
xSemaphoreTake(slot->semphr_int, 0);
|
@ -34,7 +34,6 @@
|
||||
/// Data rejected due to write error
|
||||
#define TOKEN_RSP_WRITE_ERR 0b01101
|
||||
|
||||
|
||||
/// Data error tokens have format 0b0000xyzw where xyzw are signle bit flags.
|
||||
/// MASK and VAL are used to check if a token is an error token
|
||||
#define TOKEN_ERR_MASK 0b11110000
|
||||
@ -49,7 +48,6 @@
|
||||
/// Card is locked
|
||||
#define TOKEN_ERR_LOCKED BIT(0)
|
||||
|
||||
|
||||
/// Transfer format in SPI mode. See section 7.3.1.1 of SD simplified spec.
|
||||
typedef struct {
|
||||
// These fields form the command sent from host to the card (6 bytes)
|
@ -137,9 +137,13 @@ esp_err_t sdspi_host_do_transaction(int slot, sdmmc_command_t *cmdinfo)
|
||||
flags |= SDSPI_CMD_FLAG_RSP_R5;
|
||||
} else if (!s_app_cmd && cmdinfo->opcode == SD_IO_RW_EXTENDED) {
|
||||
flags |= SDSPI_CMD_FLAG_RSP_R5 | SDSPI_CMD_FLAG_DATA;
|
||||
if (cmdinfo->arg & SD_ARG_CMD53_WRITE) flags |= SDSPI_CMD_FLAG_WRITE;
|
||||
if (cmdinfo->arg & SD_ARG_CMD53_WRITE) {
|
||||
flags |= SDSPI_CMD_FLAG_WRITE;
|
||||
}
|
||||
// The CMD53 can assign block mode in the arg when the length is exactly 512 bytes
|
||||
if (cmdinfo->arg & SD_ARG_CMD53_BLOCK_MODE) flags |= SDSPI_CMD_FLAG_MULTI_BLK;
|
||||
if (cmdinfo->arg & SD_ARG_CMD53_BLOCK_MODE) {
|
||||
flags |= SDSPI_CMD_FLAG_MULTI_BLK;
|
||||
}
|
||||
} else if (!s_app_cmd && (cmdinfo->opcode == MMC_ERASE || cmdinfo->opcode == MMC_STOP_TRANSMISSION)) {
|
||||
flags |= SDSPI_CMD_FLAG_RSP_R1B;
|
||||
} else {
|
@ -1,46 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "sdspi_crc.h"
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_rom_crc.h"
|
||||
|
||||
static const uint8_t crc7_table[256] =
|
||||
{
|
||||
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
|
||||
0x19, 0x10, 0x0b, 0x02, 0x3d, 0x34, 0x2f, 0x26, 0x51, 0x58, 0x43, 0x4a, 0x75, 0x7c, 0x67, 0x6e,
|
||||
0x32, 0x3b, 0x20, 0x29, 0x16, 0x1f, 0x04, 0x0d, 0x7a, 0x73, 0x68, 0x61, 0x5e, 0x57, 0x4c, 0x45,
|
||||
0x2b, 0x22, 0x39, 0x30, 0x0f, 0x06, 0x1d, 0x14, 0x63, 0x6a, 0x71, 0x78, 0x47, 0x4e, 0x55, 0x5c,
|
||||
0x64, 0x6d, 0x76, 0x7f, 0x40, 0x49, 0x52, 0x5b, 0x2c, 0x25, 0x3e, 0x37, 0x08, 0x01, 0x1a, 0x13,
|
||||
0x7d, 0x74, 0x6f, 0x66, 0x59, 0x50, 0x4b, 0x42, 0x35, 0x3c, 0x27, 0x2e, 0x11, 0x18, 0x03, 0x0a,
|
||||
0x56, 0x5f, 0x44, 0x4d, 0x72, 0x7b, 0x60, 0x69, 0x1e, 0x17, 0x0c, 0x05, 0x3a, 0x33, 0x28, 0x21,
|
||||
0x4f, 0x46, 0x5d, 0x54, 0x6b, 0x62, 0x79, 0x70, 0x07, 0x0e, 0x15, 0x1c, 0x23, 0x2a, 0x31, 0x38,
|
||||
0x41, 0x48, 0x53, 0x5a, 0x65, 0x6c, 0x77, 0x7e, 0x09, 0x00, 0x1b, 0x12, 0x2d, 0x24, 0x3f, 0x36,
|
||||
0x58, 0x51, 0x4a, 0x43, 0x7c, 0x75, 0x6e, 0x67, 0x10, 0x19, 0x02, 0x0b, 0x34, 0x3d, 0x26, 0x2f,
|
||||
0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c, 0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04,
|
||||
0x6a, 0x63, 0x78, 0x71, 0x4e, 0x47, 0x5c, 0x55, 0x22, 0x2b, 0x30, 0x39, 0x06, 0x0f, 0x14, 0x1d,
|
||||
0x25, 0x2c, 0x37, 0x3e, 0x01, 0x08, 0x13, 0x1a, 0x6d, 0x64, 0x7f, 0x76, 0x49, 0x40, 0x5b, 0x52,
|
||||
0x3c, 0x35, 0x2e, 0x27, 0x18, 0x11, 0x0a, 0x03, 0x74, 0x7d, 0x66, 0x6f, 0x50, 0x59, 0x42, 0x4b,
|
||||
0x17, 0x1e, 0x05, 0x0c, 0x33, 0x3a, 0x21, 0x28, 0x5f, 0x56, 0x4d, 0x44, 0x7b, 0x72, 0x69, 0x60,
|
||||
0x0e, 0x07, 0x1c, 0x15, 0x2a, 0x23, 0x38, 0x31, 0x46, 0x4f, 0x54, 0x5d, 0x62, 0x6b, 0x70, 0x79,
|
||||
};
|
||||
|
||||
// returns the CRC-7 for a message of "length" bytes
|
||||
uint8_t sdspi_crc7(const uint8_t *data, size_t size)
|
||||
{
|
||||
uint8_t result = 0;
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
result = crc7_table[(result << 1) ^ data[i]];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// Return CRC16 of data, in the on-the-wire format used by SD protocol
|
||||
uint16_t sdspi_crc16(const uint8_t* data, size_t size)
|
||||
{
|
||||
return __builtin_bswap16(esp_rom_crc16_be(UINT16_MAX, data, size) ^ UINT16_MAX);
|
||||
}
|
@ -139,23 +139,6 @@ components/driver/test_apps/sigma_delta:
|
||||
depends_components:
|
||||
- esp_driver_gpio
|
||||
|
||||
components/driver/test_apps/spi/master:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
|
||||
components/driver/test_apps/spi/param:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
|
||||
components/driver/test_apps/spi/slave:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
|
||||
components/driver/test_apps/spi/slave_hd:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
- if: SOC_SPI_SUPPORT_SLAVE_HD_VER2 != 1
|
||||
|
||||
components/driver/test_apps/temperature_sensor:
|
||||
disable:
|
||||
- if: SOC_TEMP_SENSOR_SUPPORTED != 1
|
||||
|
@ -8,6 +8,6 @@ components/esp_adc/test_apps/adc:
|
||||
- esp_adc
|
||||
- esp_driver_gpio
|
||||
- efuse
|
||||
- esp_driver_spi # ADC continuous driver relies on SPI on ESP32S2
|
||||
depends_filepatterns:
|
||||
- components/driver/spi/**/* # ADC continuous driver relies on SPI on ESP32S2
|
||||
- components/driver/i2s/**/* # ADC continuous driver relies on I2S on ESP32
|
||||
|
26
components/esp_driver_spi/CMakeLists.txt
Normal file
26
components/esp_driver_spi/CMakeLists.txt
Normal file
@ -0,0 +1,26 @@
|
||||
idf_build_get_property(target IDF_TARGET)
|
||||
|
||||
if(${target} STREQUAL "linux")
|
||||
return() # This component is not supported by the POSIX/Linux simulator
|
||||
endif()
|
||||
|
||||
set(srcs "spi_bus_lock.c")
|
||||
|
||||
set(public_include "include")
|
||||
|
||||
if(CONFIG_SOC_GPSPI_SUPPORTED)
|
||||
list(APPEND srcs "src/gpspi/spi_common.c"
|
||||
"src/gpspi/spi_master.c"
|
||||
"src/gpspi/spi_slave.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2)
|
||||
list(APPEND srcs "src/gpspi/spi_slave_hd.c")
|
||||
endif()
|
||||
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS ${public_include}
|
||||
REQUIRES esp_pm
|
||||
PRIV_REQUIRES esp_timer esp_mm esp_driver_gpio esp_ringbuf
|
||||
LDFRAGMENTS "linker.lf"
|
||||
)
|
61
components/esp_driver_spi/Kconfig
Normal file
61
components/esp_driver_spi/Kconfig
Normal file
@ -0,0 +1,61 @@
|
||||
menu "ESP-Driver:SPI Configurations"
|
||||
depends on SOC_GPSPI_SUPPORTED
|
||||
config SPI_MASTER_IN_IRAM
|
||||
bool "Place transmitting functions of SPI master into IRAM"
|
||||
default n
|
||||
depends on !FREERTOS_PLACE_FUNCTIONS_INTO_FLASH
|
||||
select SPI_MASTER_ISR_IN_IRAM
|
||||
help
|
||||
Normally only the ISR of SPI master is placed in the IRAM, so that it
|
||||
can work without the flash when interrupt is triggered.
|
||||
For other functions, there's some possibility that the flash cache
|
||||
miss when running inside and out of SPI functions, which may increase
|
||||
the interval of SPI transactions.
|
||||
Enable this to put ``queue_trans``, ``get_trans_result`` and
|
||||
``transmit`` functions into the IRAM to avoid possible cache miss.
|
||||
|
||||
This configuration won't be available if `CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH` is enabled.
|
||||
|
||||
During unit test, this is enabled to measure the ideal case of api.
|
||||
|
||||
config SPI_MASTER_ISR_IN_IRAM
|
||||
bool "Place SPI master ISR function into IRAM"
|
||||
default y
|
||||
depends on !HEAP_PLACE_FUNCTION_INTO_FLASH
|
||||
select PERIPH_CTRL_FUNC_IN_IRAM
|
||||
select HAL_SPI_MASTER_FUNC_IN_IRAM
|
||||
help
|
||||
Place the SPI master ISR in to IRAM to avoid possible cache miss.
|
||||
|
||||
Enabling this configuration is possible only when HEAP_PLACE_FUNCTION_INTO_FLASH
|
||||
is disabled since the spi master uses can allocate transactions buffers into DMA
|
||||
memory section using the heap component API that ipso facto has to be placed in IRAM.
|
||||
|
||||
Also you can forbid the ISR being disabled during flash writing
|
||||
access, by add ESP_INTR_FLAG_IRAM when initializing the driver.
|
||||
|
||||
config SPI_SLAVE_IN_IRAM
|
||||
bool "Place transmitting functions of SPI slave into IRAM"
|
||||
default n
|
||||
select SPI_SLAVE_ISR_IN_IRAM
|
||||
help
|
||||
Normally only the ISR of SPI slave is placed in the IRAM, so that it
|
||||
can work without the flash when interrupt is triggered.
|
||||
For other functions, there's some possibility that the flash cache
|
||||
miss when running inside and out of SPI functions, which may increase
|
||||
the interval of SPI transactions.
|
||||
Enable this to put ``queue_trans``, ``get_trans_result`` and
|
||||
``transmit`` functions into the IRAM to avoid possible cache miss.
|
||||
|
||||
config SPI_SLAVE_ISR_IN_IRAM
|
||||
bool "Place SPI slave ISR function into IRAM"
|
||||
default y
|
||||
select PERIPH_CTRL_FUNC_IN_IRAM
|
||||
select HAL_SPI_SLAVE_FUNC_IN_IRAM
|
||||
help
|
||||
Place the SPI slave ISR in to IRAM to avoid possible cache miss.
|
||||
|
||||
Also you can forbid the ISR being disabled during flash writing
|
||||
access, by add ESP_INTR_FLAG_IRAM when initializing the driver.
|
||||
|
||||
endmenu # SPI Configuration
|
@ -125,7 +125,6 @@ typedef struct {
|
||||
*/
|
||||
} spi_bus_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize a SPI bus
|
||||
*
|
@ -102,7 +102,6 @@ typedef struct {
|
||||
*/
|
||||
} spi_device_interface_config_t;
|
||||
|
||||
|
||||
#define SPI_TRANS_MODE_DIO (1<<0) ///< Transmit/receive data in 2-bit mode
|
||||
#define SPI_TRANS_MODE_QIO (1<<1) ///< Transmit/receive data in 4-bit mode
|
||||
#define SPI_TRANS_USE_RXDATA (1<<2) ///< Receive into rx_data member of spi_transaction_t instead into memory at rx_buffer.
|
||||
@ -158,7 +157,6 @@ typedef struct {
|
||||
uint8_t dummy_bits; ///< The dummy length in this transaction, in bits.
|
||||
} spi_transaction_ext_t ;
|
||||
|
||||
|
||||
typedef struct spi_device_t *spi_device_handle_t; ///< Handle for a device on a SPI bus
|
||||
/**
|
||||
* @brief Allocate a device on a SPI bus
|
||||
@ -183,7 +181,6 @@ typedef struct spi_device_t *spi_device_handle_t; ///< Handle for a device on a
|
||||
*/
|
||||
esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interface_config_t *dev_config, spi_device_handle_t *handle);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Remove a device from the SPI bus
|
||||
*
|
||||
@ -195,7 +192,6 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
|
||||
*/
|
||||
esp_err_t spi_bus_remove_device(spi_device_handle_t handle);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Queue a SPI transaction for interrupt transaction execution. Get the result by ``spi_device_get_trans_result``.
|
||||
*
|
||||
@ -217,7 +213,6 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle);
|
||||
*/
|
||||
esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *trans_desc, TickType_t ticks_to_wait);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the result of a SPI transaction queued earlier by ``spi_device_queue_trans``.
|
||||
*
|
||||
@ -240,7 +235,6 @@ esp_err_t spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *
|
||||
*/
|
||||
esp_err_t spi_device_get_trans_result(spi_device_handle_t handle, spi_transaction_t **trans_desc, TickType_t ticks_to_wait);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send a SPI transaction, wait for it to complete, and return the result
|
||||
*
|
||||
@ -259,7 +253,6 @@ esp_err_t spi_device_get_trans_result(spi_device_handle_t handle, spi_transactio
|
||||
*/
|
||||
esp_err_t spi_device_transmit(spi_device_handle_t handle, spi_transaction_t *trans_desc);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Immediately start a polling transaction.
|
||||
*
|
||||
@ -283,7 +276,6 @@ esp_err_t spi_device_transmit(spi_device_handle_t handle, spi_transaction_t *tra
|
||||
*/
|
||||
esp_err_t spi_device_polling_start(spi_device_handle_t handle, spi_transaction_t *trans_desc, TickType_t ticks_to_wait);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Poll until the polling transaction ends.
|
||||
*
|
||||
@ -301,7 +293,6 @@ esp_err_t spi_device_polling_start(spi_device_handle_t handle, spi_transaction_t
|
||||
*/
|
||||
esp_err_t spi_device_polling_end(spi_device_handle_t handle, TickType_t ticks_to_wait);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Send a polling transaction, wait for it to complete, and return the result
|
||||
*
|
||||
@ -323,7 +314,6 @@ esp_err_t spi_device_polling_end(spi_device_handle_t handle, TickType_t ticks_to
|
||||
*/
|
||||
esp_err_t spi_device_polling_transmit(spi_device_handle_t handle, spi_transaction_t *trans_desc);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Occupy the SPI bus for a device to do continuous transactions.
|
||||
*
|
@ -4,7 +4,6 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _DRIVER_SPI_SLAVE_H_
|
||||
#define _DRIVER_SPI_SLAVE_H_
|
||||
|
||||
@ -13,13 +12,11 @@
|
||||
#include "freertos/semphr.h"
|
||||
#include "driver/spi_common.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
#define SPI_SLAVE_TXBIT_LSBFIRST (1<<0) ///< Transmit command/address/data LSB first instead of the default MSB first
|
||||
#define SPI_SLAVE_RXBIT_LSBFIRST (1<<1) ///< Receive data LSB first instead of the default MSB first
|
||||
#define SPI_SLAVE_BIT_LSBFIRST (SPI_SLAVE_TXBIT_LSBFIRST|SPI_SLAVE_RXBIT_LSBFIRST) ///< Transmit and receive LSB first
|
||||
@ -65,7 +62,6 @@ typedef struct {
|
||||
*/
|
||||
} spi_slave_interface_config_t;
|
||||
|
||||
|
||||
#define SPI_SLAVE_TRANS_DMA_BUFFER_ALIGN_AUTO (1<<0) ///< Automatically re-malloc dma buffer if user buffer doesn't meet hardware alignment or dma_capable, this process may loss some memory and performance
|
||||
|
||||
/**
|
||||
@ -123,7 +119,6 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
|
||||
*/
|
||||
esp_err_t spi_slave_free(spi_host_device_t host);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Queue a SPI transaction for execution
|
||||
*
|
||||
@ -148,7 +143,6 @@ esp_err_t spi_slave_free(spi_host_device_t host);
|
||||
*/
|
||||
esp_err_t spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get the result of a SPI transaction queued earlier
|
||||
*
|
||||
@ -171,7 +165,6 @@ esp_err_t spi_slave_queue_trans(spi_host_device_t host, const spi_slave_transact
|
||||
*/
|
||||
esp_err_t spi_slave_get_trans_result(spi_host_device_t host, spi_slave_transaction_t **trans_desc, TickType_t ticks_to_wait);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Do a SPI transaction
|
||||
*
|
||||
@ -191,7 +184,6 @@ esp_err_t spi_slave_get_trans_result(spi_host_device_t host, spi_slave_transacti
|
||||
*/
|
||||
esp_err_t spi_slave_transmit(spi_host_device_t host, spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -62,7 +62,6 @@ typedef struct {
|
||||
void* arg; ///< Argument indicating this SPI Slave HD peripheral instance
|
||||
} spi_slave_hd_callback_config_t;
|
||||
|
||||
|
||||
//flags for ``spi_slave_hd_slot_config_t`` to use
|
||||
#define SPI_SLAVE_HD_TXBIT_LSBFIRST (1<<0) ///< Transmit command/address/data LSB first instead of the default MSB first
|
||||
#define SPI_SLAVE_HD_RXBIT_LSBFIRST (1<<1) ///< Receive data LSB first instead of the default MSB first
|
@ -19,13 +19,11 @@
|
||||
#include "esp_private/gdma.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_SPI_MASTER_ISR_IN_IRAM
|
||||
#define SPI_MASTER_ISR_ATTR IRAM_ATTR
|
||||
#else
|
||||
@ -38,7 +36,6 @@ extern "C"
|
||||
#define SPI_MASTER_ATTR
|
||||
#endif
|
||||
|
||||
|
||||
#define BUS_LOCK_DEBUG 0
|
||||
|
||||
#if BUS_LOCK_DEBUG
|
||||
@ -88,7 +85,6 @@ typedef struct {
|
||||
/// Destructor called when a bus is deinitialized.
|
||||
typedef esp_err_t (*spi_destroy_func_t)(void*);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Try to claim a SPI peripheral
|
||||
*
|
||||
@ -281,7 +277,6 @@ typedef void(*dmaworkaround_cb_t)(void *arg);
|
||||
*/
|
||||
bool spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t cb, void *arg);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Check if a DMA reset is requested but has not completed yet
|
||||
*
|
||||
@ -289,7 +284,6 @@ bool spicommon_dmaworkaround_req_reset(int dmachan, dmaworkaround_cb_t cb, void
|
||||
*/
|
||||
bool spicommon_dmaworkaround_reset_in_progress(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Mark a DMA channel as idle.
|
||||
*
|
||||
@ -779,7 +773,6 @@ extern const spi_bus_lock_dev_handle_t g_spi_lock_main_flash_dev;
|
||||
*/
|
||||
esp_err_t spi_bus_lock_init_main_dev(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@ -22,7 +22,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reset the trans Queue of slave driver
|
||||
* @note
|
||||
@ -40,7 +39,6 @@ extern "C" {
|
||||
*/
|
||||
esp_err_t spi_slave_queue_reset(spi_host_device_t host);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Reset the trans Queue from within ISR of slave driver
|
||||
* @note
|
||||
@ -55,7 +53,6 @@ esp_err_t spi_slave_queue_reset(spi_host_device_t host);
|
||||
*/
|
||||
esp_err_t spi_slave_queue_reset_isr(spi_host_device_t host);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Queue a SPI transaction in ISR
|
||||
* @note
|
||||
@ -76,7 +73,6 @@ esp_err_t spi_slave_queue_reset_isr(spi_host_device_t host);
|
||||
*/
|
||||
esp_err_t spi_slave_queue_trans_isr(spi_host_device_t host, const spi_slave_transaction_t *trans_desc);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
0
components/esp_driver_spi/linker.lf
Normal file
0
components/esp_driver_spi/linker.lf
Normal file
@ -17,7 +17,6 @@
|
||||
#include <strings.h>
|
||||
#include "esp_heap_caps.h"
|
||||
|
||||
|
||||
/*
|
||||
* This lock is designed to solve the conflicts between SPI devices (used in tasks) and
|
||||
* the background operations (ISR or cache access).
|
||||
@ -145,7 +144,6 @@ typedef struct spi_bus_lock_dev_t spi_bus_lock_dev_t;
|
||||
|
||||
typedef struct spi_bus_lock_t spi_bus_lock_t;
|
||||
|
||||
|
||||
#define MAX_DEV_NUM 10
|
||||
|
||||
// Bit 29-20: lock bits, Bit 19-10: pending bits
|
||||
@ -564,7 +562,9 @@ SPI_MASTER_ISR_ATTR static inline esp_err_t dev_wait(spi_bus_lock_dev_t *dev_han
|
||||
{
|
||||
BaseType_t ret = xSemaphoreTake(dev_handle->semphr, wait);
|
||||
|
||||
if (ret == pdFALSE) return ESP_ERR_TIMEOUT;
|
||||
if (ret == pdFALSE) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -624,9 +624,13 @@ static int try_acquire_free_dev(spi_bus_lock_t *lock, bool cs_required)
|
||||
esp_err_t spi_bus_lock_register_dev(spi_bus_lock_handle_t lock, spi_bus_lock_dev_config_t *config,
|
||||
spi_bus_lock_dev_handle_t *out_dev_handle)
|
||||
{
|
||||
if (lock == NULL) return ESP_ERR_INVALID_ARG;
|
||||
if (lock == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
int id = try_acquire_free_dev(lock, config->flags & SPI_BUS_LOCK_DEV_FLAG_CS_REQUIRED);
|
||||
if (id == -1) return ESP_ERR_NOT_SUPPORTED;
|
||||
if (id == -1) {
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
spi_bus_lock_dev_t* dev_lock = (spi_bus_lock_dev_t*)heap_caps_calloc(sizeof(spi_bus_lock_dev_t), 1, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
|
||||
if (dev_lock == NULL) {
|
||||
@ -654,7 +658,9 @@ void spi_bus_lock_unregister_dev(spi_bus_lock_dev_handle_t dev_handle)
|
||||
spi_bus_lock_t* lock = dev_handle->parent;
|
||||
BUS_LOCK_DEBUG_EXECUTE_CHECK(atomic_load(&lock->dev[id]) == (intptr_t)dev_handle);
|
||||
|
||||
if (lock->last_dev == dev_handle) lock->last_dev = NULL;
|
||||
if (lock->last_dev == dev_handle) {
|
||||
lock->last_dev = NULL;
|
||||
}
|
||||
|
||||
atomic_store(&lock->dev[id], (intptr_t)NULL);
|
||||
if (dev_handle->semphr) {
|
||||
@ -714,7 +720,9 @@ IRAM_ATTR esp_err_t spi_bus_lock_acquire_start(spi_bus_lock_dev_t *dev_handle, T
|
||||
//block until becoming the acquiring processor (help by previous acquiring processor)
|
||||
esp_err_t err = dev_wait(dev_handle, wait);
|
||||
//TODO: add timeout handling here.
|
||||
if (err != ESP_OK) return err;
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
ESP_DRAM_LOGV(TAG, "dev %d acquired.", dev_lock_get_id(dev_handle));
|
||||
@ -780,7 +788,9 @@ IRAM_ATTR esp_err_t spi_bus_lock_wait_bg_done(spi_bus_lock_dev_handle_t dev_hand
|
||||
//block until becoming the acquiring processor (help by previous acquiring processor)
|
||||
esp_err_t err = dev_wait(dev_handle, wait);
|
||||
//TODO: add timeout handling here.
|
||||
if (err != ESP_OK) return err;
|
||||
if (err != ESP_OK) {
|
||||
return err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "stdatomic.h"
|
||||
@ -57,7 +56,6 @@ static const char *SPI_TAG = "spi";
|
||||
|
||||
#define FUNC_GPIO PIN_FUNC_GPIO
|
||||
|
||||
|
||||
typedef struct {
|
||||
int host_id;
|
||||
spi_destroy_func_t destroy_func;
|
||||
@ -89,7 +87,6 @@ static uint8_t spi_dma_chan_enabled = 0;
|
||||
static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
#endif //#if !SOC_GDMA_SUPPORTED
|
||||
|
||||
|
||||
static inline bool is_valid_host(spi_host_device_t host)
|
||||
{
|
||||
#if (SOC_SPI_PERIPH_NUM == 2)
|
||||
@ -330,7 +327,6 @@ esp_err_t spicommon_gdma_get_handle(spi_host_device_t host_id, gdma_channel_hand
|
||||
(gdma_direction == GDMA_CHANNEL_DIRECTION_RX), \
|
||||
ESP_ERR_INVALID_ARG, SPI_TAG, "GDMA Direction not supported!");
|
||||
|
||||
|
||||
if (gdma_direction == GDMA_CHANNEL_DIRECTION_TX) {
|
||||
*gdma_handle = bus_ctx[host_id]->tx_channel;
|
||||
}
|
||||
@ -400,9 +396,11 @@ static bool check_iomux_pins_oct(spi_host_device_t host, const spi_bus_config_t*
|
||||
return false;
|
||||
}
|
||||
int io_nums[] = {bus_config->data0_io_num, bus_config->data1_io_num, bus_config->data2_io_num, bus_config->data3_io_num,
|
||||
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};
|
||||
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_mux_nums[] = {SPI2_IOMUX_PIN_NUM_MOSI_OCT, SPI2_IOMUX_PIN_NUM_MISO_OCT, SPI2_IOMUX_PIN_NUM_WP_OCT, SPI2_IOMUX_PIN_NUM_HD_OCT,
|
||||
SPI2_IOMUX_PIN_NUM_CLK_OCT, SPI2_IOMUX_PIN_NUM_IO4_OCT, SPI2_IOMUX_PIN_NUM_IO5_OCT, SPI2_IOMUX_PIN_NUM_IO6_OCT, SPI2_IOMUX_PIN_NUM_IO7_OCT};
|
||||
SPI2_IOMUX_PIN_NUM_CLK_OCT, SPI2_IOMUX_PIN_NUM_IO4_OCT, SPI2_IOMUX_PIN_NUM_IO5_OCT, SPI2_IOMUX_PIN_NUM_IO6_OCT, SPI2_IOMUX_PIN_NUM_IO7_OCT
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(io_nums) / sizeof(io_nums[0]); i++) {
|
||||
if (io_nums[i] >= 0 && io_nums[i] != io_mux_nums[i]) {
|
||||
return false;
|
||||
@ -454,10 +452,12 @@ static void bus_iomux_pins_set_oct(spi_host_device_t host, const spi_bus_config_
|
||||
{
|
||||
assert(host == SPI2_HOST);
|
||||
int io_nums[] = {bus_config->data0_io_num, bus_config->data1_io_num, bus_config->data2_io_num, bus_config->data3_io_num,
|
||||
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};
|
||||
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].spid5_out, spi_periph_signal[host].spid6_out, spi_periph_signal[host].spid7_out
|
||||
};
|
||||
for (size_t i = 0; i < sizeof(io_nums) / sizeof(io_nums[0]); i++) {
|
||||
if (io_nums[i] > 0) {
|
||||
gpio_iomux_in(io_nums[i], io_signals[i]);
|
||||
@ -576,7 +576,9 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
#endif //SOC_SPI_SUPPORT_OCT
|
||||
|
||||
//set flags for QUAD mode according to the existence of wp and hd
|
||||
if (bus_config->quadhd_io_num >= 0 && bus_config->quadwp_io_num >= 0) temp_flag |= SPICOMMON_BUSFLAG_WPHD;
|
||||
if (bus_config->quadhd_io_num >= 0 && bus_config->quadwp_io_num >= 0) {
|
||||
temp_flag |= SPICOMMON_BUSFLAG_WPHD;
|
||||
}
|
||||
if (bus_config->mosi_io_num >= 0) {
|
||||
temp_flag |= SPICOMMON_BUSFLAG_MOSI;
|
||||
SPI_CHECK_PIN(bus_config->mosi_io_num, "mosi", mosi_need_output);
|
||||
@ -701,7 +703,8 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
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}};
|
||||
{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);
|
||||
@ -717,7 +720,9 @@ esp_err_t spicommon_bus_initialize_io(spi_host_device_t host, const spi_bus_conf
|
||||
#endif //SOC_SPI_SUPPORT_OCT
|
||||
}
|
||||
|
||||
if (flags_o) *flags_o = temp_flag;
|
||||
if (flags_o) {
|
||||
*flags_o = temp_flag;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
@ -753,7 +758,9 @@ void spicommon_cs_initialize(spi_host_device_t host, int cs_io_num, int cs_num,
|
||||
} else {
|
||||
gpio_set_direction(cs_io_num, GPIO_MODE_INPUT);
|
||||
}
|
||||
if (cs_num == 0) esp_rom_gpio_connect_in_signal(cs_io_num, spi_periph_signal[host].spics_in, false);
|
||||
if (cs_num == 0) {
|
||||
esp_rom_gpio_connect_in_signal(cs_io_num, spi_periph_signal[host].spics_in, false);
|
||||
}
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[cs_io_num]);
|
||||
gpio_hal_iomux_func_sel(GPIO_PIN_MUX_REG[cs_io_num], FUNC_GPIO);
|
||||
}
|
||||
@ -776,7 +783,6 @@ bool spicommon_bus_using_iomux(spi_host_device_t host)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void spi_bus_main_set_lock(spi_bus_lock_handle_t lock)
|
||||
{
|
||||
bus_ctx[0]->bus_attr.lock = lock;
|
||||
@ -835,7 +841,9 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t *
|
||||
bus_attr->rx_dma_chan = actual_rx_dma_chan;
|
||||
|
||||
int dma_desc_ct = (bus_config->max_transfer_sz + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED;
|
||||
if (dma_desc_ct == 0) dma_desc_ct = 1; //default to 4k when max is not given
|
||||
if (dma_desc_ct == 0) {
|
||||
dma_desc_ct = 1; //default to 4k when max is not given
|
||||
}
|
||||
|
||||
bus_attr->max_transfer_sz = dma_desc_ct * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED;
|
||||
bus_attr->dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA);
|
||||
@ -904,7 +912,9 @@ cleanup:
|
||||
|
||||
const spi_bus_attr_t* spi_bus_get_attr(spi_host_device_t host_id)
|
||||
{
|
||||
if (bus_ctx[host_id] == NULL) return NULL;
|
||||
if (bus_ctx[host_id] == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return &bus_ctx[host_id]->bus_attr;
|
||||
}
|
||||
@ -950,7 +960,6 @@ esp_err_t spi_bus_register_destroy_func(spi_host_device_t host_id,
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Code for workaround for DMA issue in ESP32 v0/v1 silicon
|
||||
*/
|
@ -326,8 +326,12 @@ void spi_get_timing(bool gpio_is_used, int input_delay_ns, int eff_clk, int* dum
|
||||
int timing_miso_delay;
|
||||
|
||||
spi_hal_cal_timing(APB_CLK_FREQ, eff_clk, gpio_is_used, input_delay_ns, &timing_dummy, &timing_miso_delay);
|
||||
if (dummy_o) *dummy_o = timing_dummy;
|
||||
if (cycles_remain_o) *cycles_remain_o = timing_miso_delay;
|
||||
if (dummy_o) {
|
||||
*dummy_o = timing_dummy;
|
||||
}
|
||||
if (cycles_remain_o) {
|
||||
*cycles_remain_o = timing_miso_delay;
|
||||
}
|
||||
#else
|
||||
//TODO: IDF-6578
|
||||
ESP_LOGW(SPI_TAG, "This func temporary not supported for current target!");
|
||||
@ -428,7 +432,9 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
|
||||
|
||||
//Allocate memory for device
|
||||
dev = malloc(sizeof(spi_device_t));
|
||||
if (dev == NULL) goto nomem;
|
||||
if (dev == NULL) {
|
||||
goto nomem;
|
||||
}
|
||||
memset(dev, 0, sizeof(spi_device_t));
|
||||
|
||||
dev->id = freecs;
|
||||
@ -492,8 +498,12 @@ esp_err_t spi_bus_add_device(spi_host_device_t host_id, const spi_device_interfa
|
||||
|
||||
nomem:
|
||||
if (dev) {
|
||||
if (dev->trans_queue) vQueueDelete(dev->trans_queue);
|
||||
if (dev->ret_queue) vQueueDelete(dev->ret_queue);
|
||||
if (dev->trans_queue) {
|
||||
vQueueDelete(dev->trans_queue);
|
||||
}
|
||||
if (dev->ret_queue) {
|
||||
vQueueDelete(dev->ret_queue);
|
||||
}
|
||||
spi_bus_lock_unregister_dev(dev->dev_lock);
|
||||
}
|
||||
free(dev);
|
||||
@ -519,11 +529,17 @@ esp_err_t spi_bus_remove_device(spi_device_handle_t handle)
|
||||
|
||||
//return
|
||||
int spics_io_num = handle->cfg.spics_io_num;
|
||||
if (spics_io_num >= 0) spicommon_cs_free_io(spics_io_num);
|
||||
if (spics_io_num >= 0) {
|
||||
spicommon_cs_free_io(spics_io_num);
|
||||
}
|
||||
|
||||
//Kill queues
|
||||
if (handle->trans_queue) vQueueDelete(handle->trans_queue);
|
||||
if (handle->ret_queue) vQueueDelete(handle->ret_queue);
|
||||
if (handle->trans_queue) {
|
||||
vQueueDelete(handle->trans_queue);
|
||||
}
|
||||
if (handle->ret_queue) {
|
||||
vQueueDelete(handle->ret_queue);
|
||||
}
|
||||
spi_bus_lock_unregister_dev(handle->dev_lock);
|
||||
|
||||
assert(handle->host->device[handle->id] == handle);
|
||||
@ -568,7 +584,9 @@ static SPI_MASTER_ISR_ATTR void spi_setup_device(spi_device_t *dev)
|
||||
static SPI_MASTER_ISR_ATTR spi_device_t *get_acquiring_dev(spi_host_t *host)
|
||||
{
|
||||
spi_bus_lock_dev_handle_t dev_lock = spi_bus_lock_get_acquiring_dev(host->bus_attr->lock);
|
||||
if (!dev_lock) return NULL;
|
||||
if (!dev_lock) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return host->device[spi_bus_lock_get_dev_id(dev_lock)];
|
||||
}
|
||||
@ -652,7 +670,9 @@ static void SPI_MASTER_ISR_ATTR spi_new_trans(spi_device_t *dev, spi_trans_priv_
|
||||
spi_hal_prepare_data(hal, hal_dev, &hal_trans);
|
||||
|
||||
//Call pre-transmission callback, if any
|
||||
if (dev->cfg.pre_cb) dev->cfg.pre_cb(trans);
|
||||
if (dev->cfg.pre_cb) {
|
||||
dev->cfg.pre_cb(trans);
|
||||
}
|
||||
//Kick off transfer
|
||||
spi_hal_user_start(hal);
|
||||
}
|
||||
@ -666,7 +686,9 @@ static void SPI_MASTER_ISR_ATTR spi_post_trans(spi_host_t *host)
|
||||
spi_hal_fetch_result(&host->hal);
|
||||
//Call post-transaction callback, if any
|
||||
spi_device_t* dev = host->device[host->cur_cs];
|
||||
if (dev->cfg.post_cb) dev->cfg.post_cb(cur_trans);
|
||||
if (dev->cfg.post_cb) {
|
||||
dev->cfg.post_cb(cur_trans);
|
||||
}
|
||||
|
||||
host->cur_cs = DEV_NUM_MAX;
|
||||
}
|
||||
@ -734,7 +756,6 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg)
|
||||
spi_bus_lock_handle_t lock = host->bus_attr->lock;
|
||||
BaseType_t trans_found = pdFALSE;
|
||||
|
||||
|
||||
// There should be remaining requests
|
||||
BUS_LOCK_DEBUG_EXECUTE_CHECK(spi_bus_lock_bg_req_exist(lock));
|
||||
|
||||
@ -781,7 +802,9 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg)
|
||||
// or resume acquiring device task (if quit due to bus acquiring).
|
||||
} while (!spi_bus_lock_bg_exit(lock, trans_found, &do_yield));
|
||||
|
||||
if (do_yield) portYIELD_FROM_ISR();
|
||||
if (do_yield) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static SPI_MASTER_ISR_ATTR esp_err_t check_trans_valid(spi_device_handle_t handle, spi_transaction_t *trans_desc)
|
||||
@ -936,7 +959,9 @@ clean_up:
|
||||
esp_err_t SPI_MASTER_ATTR spi_device_queue_trans(spi_device_handle_t handle, spi_transaction_t *trans_desc, TickType_t ticks_to_wait)
|
||||
{
|
||||
esp_err_t ret = check_trans_valid(handle, trans_desc);
|
||||
if (ret != ESP_OK) return ret;
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
spi_host_t *host = handle->host;
|
||||
|
||||
@ -950,7 +975,9 @@ esp_err_t SPI_MASTER_ATTR spi_device_queue_trans(spi_device_handle_t handle, spi
|
||||
|
||||
spi_trans_priv_t trans_buf = { .trans = trans_desc, };
|
||||
ret = setup_priv_desc(host, &trans_buf);
|
||||
if (ret != ESP_OK) return ret;
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
// though clock source is selectable, read/write reg and mem of spi peripherial still use APB
|
||||
@ -1015,10 +1042,14 @@ esp_err_t SPI_MASTER_ATTR spi_device_transmit(spi_device_handle_t handle, spi_tr
|
||||
spi_transaction_t *ret_trans;
|
||||
//ToDo: check if any spi transfers in flight
|
||||
ret = spi_device_queue_trans(handle, trans_desc, portMAX_DELAY);
|
||||
if (ret != ESP_OK) return ret;
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = spi_device_get_trans_result(handle, &ret_trans, portMAX_DELAY);
|
||||
if (ret != ESP_OK) return ret;
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
assert(ret_trans == trans_desc);
|
||||
return ESP_OK;
|
||||
@ -1093,13 +1124,17 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_start(spi_device_handle_t handl
|
||||
esp_err_t ret;
|
||||
SPI_CHECK(ticks_to_wait == portMAX_DELAY, "currently timeout is not available for polling transactions", ESP_ERR_INVALID_ARG);
|
||||
ret = check_trans_valid(handle, trans_desc);
|
||||
if (ret!=ESP_OK) return ret;
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
SPI_CHECK(!spi_bus_device_is_polling(handle), "Cannot send polling transaction while the previous polling transaction is not terminated.", ESP_ERR_INVALID_STATE);
|
||||
|
||||
spi_host_t *host = handle->host;
|
||||
spi_trans_priv_t priv_polling_trans = { .trans = trans_desc, };
|
||||
ret = setup_priv_desc(host, &priv_polling_trans);
|
||||
if (ret!=ESP_OK) return ret;
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If device_acquiring_lock is set to handle, it means that the user has already
|
||||
* acquired the bus thanks to the function `spi_device_acquire_bus()`.
|
||||
@ -1182,7 +1217,9 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_polling_transmit(spi_device_handle_t ha
|
||||
{
|
||||
esp_err_t ret;
|
||||
ret = spi_device_polling_start(handle, trans_desc, portMAX_DELAY);
|
||||
if (ret != ESP_OK) return ret;
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return spi_device_polling_end(handle, portMAX_DELAY);
|
||||
}
|
@ -36,7 +36,6 @@ static const char *SPI_TAG = "spi_slave";
|
||||
|
||||
#define SPI_CHECK(a, str, ret_val) ESP_RETURN_ON_FALSE(a, ret_val, SPI_TAG, str)
|
||||
|
||||
|
||||
#ifdef CONFIG_SPI_SLAVE_ISR_IN_IRAM
|
||||
#define SPI_SLAVE_ISR_ATTR IRAM_ATTR
|
||||
#else
|
||||
@ -181,7 +180,9 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
|
||||
|
||||
//See how many dma descriptors we need and allocate them
|
||||
int dma_desc_ct = (bus_config->max_transfer_sz + SPI_MAX_DMA_LEN - 1) / SPI_MAX_DMA_LEN;
|
||||
if (dma_desc_ct == 0) dma_desc_ct = 1; //default to 4k when max is not given
|
||||
if (dma_desc_ct == 0) {
|
||||
dma_desc_ct = 1; //default to 4k when max is not given
|
||||
}
|
||||
spihost[host]->max_transfer_sz = dma_desc_ct * SPI_MAX_DMA_LEN;
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
size_t alignment;
|
||||
@ -216,7 +217,9 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
|
||||
}
|
||||
|
||||
// The slave DMA suffers from unexpected transactions. Forbid reading if DMA is enabled by disabling the CS line.
|
||||
if (spihost[host]->dma_enabled) freeze_cs(spihost[host]);
|
||||
if (spihost[host]->dma_enabled) {
|
||||
freeze_cs(spihost[host]);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
err = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi_slave",
|
||||
@ -282,8 +285,12 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b
|
||||
|
||||
cleanup:
|
||||
if (spihost[host]) {
|
||||
if (spihost[host]->trans_queue) vQueueDelete(spihost[host]->trans_queue);
|
||||
if (spihost[host]->ret_queue) vQueueDelete(spihost[host]->ret_queue);
|
||||
if (spihost[host]->trans_queue) {
|
||||
vQueueDelete(spihost[host]->trans_queue);
|
||||
}
|
||||
if (spihost[host]->ret_queue) {
|
||||
vQueueDelete(spihost[host]->ret_queue);
|
||||
}
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
if (spihost[host]->pm_lock) {
|
||||
esp_pm_lock_release(spihost[host]->pm_lock);
|
||||
@ -309,8 +316,12 @@ esp_err_t spi_slave_free(spi_host_device_t host)
|
||||
{
|
||||
SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG);
|
||||
SPI_CHECK(spihost[host], "host not slave", ESP_ERR_INVALID_ARG);
|
||||
if (spihost[host]->trans_queue) vQueueDelete(spihost[host]->trans_queue);
|
||||
if (spihost[host]->ret_queue) vQueueDelete(spihost[host]->ret_queue);
|
||||
if (spihost[host]->trans_queue) {
|
||||
vQueueDelete(spihost[host]->trans_queue);
|
||||
}
|
||||
if (spihost[host]->ret_queue) {
|
||||
vQueueDelete(spihost[host]->ret_queue);
|
||||
}
|
||||
if (spihost[host]->dma_enabled) {
|
||||
spicommon_dma_chan_free(host);
|
||||
free(spihost[host]->hal.dmadesc_tx);
|
||||
@ -406,7 +417,9 @@ esp_err_t SPI_SLAVE_ATTR spi_slave_queue_trans(spi_host_device_t host, const spi
|
||||
SPI_CHECK(ESP_OK == spi_slave_setup_priv_trans(host, &priv_trans), "slave setup priv_trans failed", ESP_ERR_NO_MEM);
|
||||
|
||||
r = xQueueSend(spihost[host]->trans_queue, (void *)&priv_trans, ticks_to_wait);
|
||||
if (!r) return ESP_ERR_TIMEOUT;
|
||||
if (!r) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
esp_intr_enable(spihost[host]->intr);
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -512,23 +525,28 @@ esp_err_t SPI_SLAVE_ATTR spi_slave_get_trans_result(spi_host_device_t host, spi_
|
||||
|
||||
spi_slave_trans_priv_t priv_trans;
|
||||
r = xQueueReceive(spihost[host]->ret_queue, (void *)&priv_trans, ticks_to_wait);
|
||||
if (!r) return ESP_ERR_TIMEOUT;
|
||||
if (!r) {
|
||||
return ESP_ERR_TIMEOUT;
|
||||
}
|
||||
|
||||
spi_slave_uninstall_priv_trans(host, &priv_trans);
|
||||
*trans_desc = priv_trans.trans;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
esp_err_t SPI_SLAVE_ATTR spi_slave_transmit(spi_host_device_t host, spi_slave_transaction_t *trans_desc, TickType_t ticks_to_wait)
|
||||
{
|
||||
esp_err_t ret;
|
||||
spi_slave_transaction_t *ret_trans;
|
||||
//ToDo: check if any spi transfers in flight
|
||||
ret = spi_slave_queue_trans(host, trans_desc, ticks_to_wait);
|
||||
if (ret != ESP_OK) return ret;
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
ret = spi_slave_get_trans_result(host, &ret_trans, ticks_to_wait);
|
||||
if (ret != ESP_OK) return ret;
|
||||
if (ret != ESP_OK) {
|
||||
return ret;
|
||||
}
|
||||
assert(ret_trans == trans_desc);
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -556,7 +574,9 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg)
|
||||
bool use_dma = host->dma_enabled;
|
||||
if (host->cur_trans.trans) {
|
||||
// When DMA is enabled, the slave rx dma suffers from unexpected transactions. Forbid reading until transaction ready.
|
||||
if (use_dma) freeze_cs(host);
|
||||
if (use_dma) {
|
||||
freeze_cs(host);
|
||||
}
|
||||
|
||||
spi_slave_hal_store_result(hal);
|
||||
host->cur_trans.trans->trans_len = spi_slave_hal_get_rcv_bitlen(hal);
|
||||
@ -579,7 +599,9 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg)
|
||||
assert(ret == ESP_OK);
|
||||
}
|
||||
#endif
|
||||
if (host->cfg.post_trans_cb) host->cfg.post_trans_cb(host->cur_trans.trans);
|
||||
if (host->cfg.post_trans_cb) {
|
||||
host->cfg.post_trans_cb(host->cur_trans.trans);
|
||||
}
|
||||
|
||||
if (!(host->cfg.flags & SPI_SLAVE_NO_RETURN_RESULT)) {
|
||||
xQueueSendFromISR(host->ret_queue, &host->cur_trans, &do_yield);
|
||||
@ -595,7 +617,9 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg)
|
||||
if (spicommon_dmaworkaround_reset_in_progress()) {
|
||||
//We need to wait for the reset to complete. Disable int (will be re-enabled on reset callback) and exit isr.
|
||||
esp_intr_disable(host->intr);
|
||||
if (do_yield) portYIELD_FROM_ISR();
|
||||
if (do_yield) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -637,7 +661,11 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg)
|
||||
|
||||
//Kick off transfer
|
||||
spi_slave_hal_user_start(hal);
|
||||
if (host->cfg.post_setup_cb) host->cfg.post_setup_cb(priv_trans.trans);
|
||||
if (host->cfg.post_setup_cb) {
|
||||
host->cfg.post_setup_cb(priv_trans.trans);
|
||||
}
|
||||
}
|
||||
if (do_yield) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
if (do_yield) portYIELD_FROM_ISR();
|
||||
}
|
@ -234,10 +234,18 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b
|
||||
//Init callbacks
|
||||
memcpy((uint8_t *)&host->callback, (uint8_t *)&config->cb_config, sizeof(spi_slave_hd_callback_config_t));
|
||||
spi_event_t event = 0;
|
||||
if (host->callback.cb_buffer_tx != NULL) event |= SPI_EV_BUF_TX;
|
||||
if (host->callback.cb_buffer_rx != NULL) event |= SPI_EV_BUF_RX;
|
||||
if (host->callback.cb_cmd9 != NULL) event |= SPI_EV_CMD9;
|
||||
if (host->callback.cb_cmdA != NULL) event |= SPI_EV_CMDA;
|
||||
if (host->callback.cb_buffer_tx != NULL) {
|
||||
event |= SPI_EV_BUF_TX;
|
||||
}
|
||||
if (host->callback.cb_buffer_rx != NULL) {
|
||||
event |= SPI_EV_BUF_RX;
|
||||
}
|
||||
if (host->callback.cb_cmd9 != NULL) {
|
||||
event |= SPI_EV_CMD9;
|
||||
}
|
||||
if (host->callback.cb_cmdA != NULL) {
|
||||
event |= SPI_EV_CMDA;
|
||||
}
|
||||
spi_slave_hd_hal_enable_event_intr(&host->hal, event);
|
||||
|
||||
return ESP_OK;
|
||||
@ -251,14 +259,28 @@ cleanup:
|
||||
esp_err_t spi_slave_hd_deinit(spi_host_device_t host_id)
|
||||
{
|
||||
spi_slave_hd_slot_t *host = spihost[host_id];
|
||||
if (host == NULL) return ESP_ERR_INVALID_ARG;
|
||||
if (host == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
if (host->tx_trans_queue) vQueueDelete(host->tx_trans_queue);
|
||||
if (host->tx_ret_queue) vQueueDelete(host->tx_ret_queue);
|
||||
if (host->rx_trans_queue) vQueueDelete(host->rx_trans_queue);
|
||||
if (host->rx_ret_queue) vQueueDelete(host->rx_ret_queue);
|
||||
if (host->tx_cnting_sem) vSemaphoreDelete(host->tx_cnting_sem);
|
||||
if (host->rx_cnting_sem) vSemaphoreDelete(host->rx_cnting_sem);
|
||||
if (host->tx_trans_queue) {
|
||||
vQueueDelete(host->tx_trans_queue);
|
||||
}
|
||||
if (host->tx_ret_queue) {
|
||||
vQueueDelete(host->tx_ret_queue);
|
||||
}
|
||||
if (host->rx_trans_queue) {
|
||||
vQueueDelete(host->rx_trans_queue);
|
||||
}
|
||||
if (host->rx_ret_queue) {
|
||||
vQueueDelete(host->rx_ret_queue);
|
||||
}
|
||||
if (host->tx_cnting_sem) {
|
||||
vSemaphoreDelete(host->tx_cnting_sem);
|
||||
}
|
||||
if (host->rx_cnting_sem) {
|
||||
vSemaphoreDelete(host->rx_cnting_sem);
|
||||
}
|
||||
esp_intr_free(host->intr);
|
||||
esp_intr_free(host->intr_dma);
|
||||
#ifdef CONFIG_PM_ENABLE
|
||||
@ -418,7 +440,9 @@ static IRAM_ATTR void spi_slave_hd_intr_segment(void *arg)
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&host->int_spinlock);
|
||||
|
||||
if (awoken == pdTRUE) portYIELD_FROM_ISR();
|
||||
if (awoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static IRAM_ATTR void spi_slave_hd_append_tx_isr(void *arg)
|
||||
@ -456,7 +480,9 @@ static IRAM_ATTR void spi_slave_hd_append_tx_isr(void *arg)
|
||||
assert(ret == pdTRUE);
|
||||
}
|
||||
}
|
||||
if (awoken==pdTRUE) portYIELD_FROM_ISR();
|
||||
if (awoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
static IRAM_ATTR void spi_slave_hd_append_rx_isr(void *arg)
|
||||
@ -467,7 +493,6 @@ static IRAM_ATTR void spi_slave_hd_append_rx_isr(void *arg)
|
||||
BaseType_t awoken = pdFALSE;
|
||||
BaseType_t ret __attribute__((unused));
|
||||
|
||||
|
||||
spi_slave_hd_trans_priv_t ret_priv_trans;
|
||||
size_t trans_len;
|
||||
while (1) {
|
||||
@ -502,7 +527,9 @@ static IRAM_ATTR void spi_slave_hd_append_rx_isr(void *arg)
|
||||
assert(ret == pdTRUE);
|
||||
}
|
||||
}
|
||||
if (awoken==pdTRUE) portYIELD_FROM_ISR();
|
||||
if (awoken == pdTRUE) {
|
||||
portYIELD_FROM_ISR();
|
||||
}
|
||||
}
|
||||
|
||||
#if SOC_GDMA_SUPPORTED
|
26
components/esp_driver_spi/test_apps/.build-test-rules.yml
Normal file
26
components/esp_driver_spi/test_apps/.build-test-rules.yml
Normal file
@ -0,0 +1,26 @@
|
||||
.spi_depends_default: &spi_depends_default
|
||||
depends_components:
|
||||
- esp_mm # for cache
|
||||
- esp_driver_spi
|
||||
- esp_driver_gpio
|
||||
|
||||
components/esp_driver_spi/test_apps/spi/master:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
<<: *spi_depends_default
|
||||
|
||||
components/esp_driver_spi/test_apps/spi/param:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
<<: *spi_depends_default
|
||||
|
||||
components/esp_driver_spi/test_apps/spi/slave:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
<<: *spi_depends_default
|
||||
|
||||
components/esp_driver_spi/test_apps/spi/slave_hd:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
- if: SOC_SPI_SUPPORT_SLAVE_HD_VER2 != 1
|
||||
<<: *spi_depends_default
|
@ -15,7 +15,7 @@ project(spi_master_test)
|
||||
if(CONFIG_COMPILER_DUMP_RTL_FILES)
|
||||
add_custom_target(check_test_app_sections ALL
|
||||
COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
|
||||
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/
|
||||
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_spi/,${CMAKE_BINARY_DIR}/esp-idf/hal/
|
||||
--elf-file ${CMAKE_BINARY_DIR}/spi_master_test.elf
|
||||
find-refs
|
||||
--from-sections=.iram0.text
|
@ -11,6 +11,6 @@ set(srcs
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(
|
||||
SRCS ${srcs}
|
||||
PRIV_REQUIRES test_utils driver test_driver_utils spi_flash
|
||||
PRIV_REQUIRES test_utils esp_driver_spi test_driver_utils spi_flash
|
||||
WHOLE_ARCHIVE
|
||||
)
|
@ -13,7 +13,6 @@
|
||||
#include "spi_flash_mmap.h"
|
||||
#include "unity.h"
|
||||
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
// The VSPI pins on UT_T1_ESP_FLASH are connected to a external flash
|
||||
#define TEST_BUS_PIN_NUM_MISO VSPI_IOMUX_PIN_NUM_MISO
|
||||
@ -269,7 +268,9 @@ static void test_bus_lock(bool test_flash)
|
||||
|
||||
for (;;) {
|
||||
vTaskDelay(10);
|
||||
if (context1.finished && context2.finished && context3.finished && context4.finished) break;
|
||||
if (context1.finished && context2.finished && context3.finished && context4.finished) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_ESP_OK(spi_bus_remove_device(context1.handle));
|
||||
@ -289,7 +290,6 @@ TEST_CASE("spi bus lock, with flash","[spi][test_env=external_flash]")
|
||||
}
|
||||
#endif //CONFIG_IDF_TARGET_ESP32
|
||||
|
||||
|
||||
TEST_CASE("spi bus lock", "[spi]")
|
||||
{
|
||||
test_bus_lock(false);
|
@ -7,7 +7,6 @@
|
||||
Tests for the spi_master device driver
|
||||
*/
|
||||
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include "driver/spi_master.h"
|
||||
#include "driver/spi_slave.h"
|
||||
@ -24,7 +23,6 @@
|
||||
#include "test_utils.h"
|
||||
#include "test_spi_utils.h"
|
||||
|
||||
|
||||
const static char TAG[] = "test_spi";
|
||||
|
||||
// There is no input-only pin except on esp32 and esp32s2
|
||||
@ -75,8 +73,7 @@ static void check_spi_pre_n_for(spi_clock_source_t clock_source, int clk, int pr
|
||||
* {freq, pre, n}
|
||||
*/
|
||||
#define TEST_CLK_TIMES 8
|
||||
struct test_clk_param_group_t
|
||||
{
|
||||
struct test_clk_param_group_t {
|
||||
uint32_t clk_param_80m[TEST_CLK_TIMES][3];
|
||||
uint32_t clk_param_48m[TEST_CLK_TIMES][3];
|
||||
uint32_t clk_param_40m[TEST_CLK_TIMES][3];
|
||||
@ -92,7 +89,6 @@ struct test_clk_param_group_t
|
||||
{{1, SOC_SPI_MAX_PRE_DIVIDER, 64}, {100000, 2, 35}, {333333, 1, 21}, {800000, 1, 9}, {900000, 1, 8}, {1100000, 1, 6}, {4000000, 1, 2,}, {7000000, 1, 1} },
|
||||
};
|
||||
|
||||
|
||||
TEST_CASE("SPI Master clockdiv calculation routines", "[spi]")
|
||||
{
|
||||
spi_bus_config_t buscfg = SPI_BUS_TEST_DEFAULT_CONFIG();
|
||||
@ -317,7 +313,6 @@ TEST_CASE("SPI Master test", "[spi]")
|
||||
TEST_ASSERT(success);
|
||||
}
|
||||
|
||||
|
||||
TEST_CASE("SPI Master test, interaction of multiple devs", "[spi]")
|
||||
{
|
||||
esp_err_t ret;
|
||||
@ -355,7 +350,6 @@ TEST_CASE("SPI Master test, interaction of multiple devs", "[spi]")
|
||||
printf("Sending to dev 2\n");
|
||||
success &= spi_test(handle2, 5000);
|
||||
|
||||
|
||||
ret = spi_bus_remove_device(handle2);
|
||||
TEST_ASSERT(ret == ESP_OK);
|
||||
master_free_device_bus(handle1);
|
||||
@ -673,7 +667,6 @@ TEST_CASE("SPI Master no response when switch from host1 (SPI2) to host2 (SPI3)"
|
||||
TEST_ESP_OK(spi_bus_free(host));
|
||||
}
|
||||
|
||||
|
||||
DRAM_ATTR static uint32_t data_dram[80] = {0};
|
||||
//force to place in code area.
|
||||
static const uint8_t data_drom[320 + 3] = {
|
||||
@ -826,7 +819,6 @@ TEST_CASE("SPI Master DMA test: length, start, not aligned", "[spi]")
|
||||
TEST_ASSERT(spi_bus_free(TEST_SPI_HOST) == ESP_OK);
|
||||
}
|
||||
|
||||
|
||||
#if (TEST_SPI_PERIPH_NUM >= 2)
|
||||
//These will only be enabled on chips with 2 or more SPI peripherals
|
||||
|
||||
@ -1337,7 +1329,6 @@ static void fd_slave(void)
|
||||
TEST_CASE_MULTIPLE_DEVICES("SPI Master: FD, DMA, Master Single Direction Test", "[spi_ms][test_env=generic_multi_device]", fd_master, fd_slave);
|
||||
#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32) //TODO: IDF-3494
|
||||
|
||||
|
||||
//NOTE: Explained in IDF-1445 | MR !14996
|
||||
#if !(CONFIG_SPIRAM) || (CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL >= 16384)
|
||||
/********************************************************************************
|
||||
@ -1600,11 +1591,11 @@ void test_add_device_slave(void)
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("SPI_Master:Test multiple devices", "[spi_ms]", test_add_device_master, test_add_device_slave);
|
||||
|
||||
|
||||
#if (SOC_CPU_CORES_NUM > 1) && (!CONFIG_FREERTOS_UNICORE)
|
||||
|
||||
#define TEST_ISR_CNT 100
|
||||
static void test_master_isr_core_post_trans_cbk(spi_transaction_t *curr_trans){
|
||||
static void test_master_isr_core_post_trans_cbk(spi_transaction_t *curr_trans)
|
||||
{
|
||||
*((int *)curr_trans->user) += esp_cpu_get_core_id();
|
||||
}
|
||||
|
||||
@ -1640,7 +1631,6 @@ TEST_CASE("test_master_isr_pin_to_core","[spi]")
|
||||
// by default the esp_intr_alloc is called on ESP_MAIN_TASK_AFFINITY_CPU0 now
|
||||
TEST_ASSERT_EQUAL_UINT32(0, master_expect);
|
||||
|
||||
|
||||
//-------------------------------------CPU1---------------------------------------
|
||||
buscfg.isr_cpu_id = ESP_INTR_CPU_AFFINITY_1;
|
||||
|
@ -49,7 +49,6 @@ static void inner_connect(spi_bus_config_t bus)
|
||||
//Slave MOSI(spid_in) input to `mosi_num`
|
||||
spitest_gpio_input_sel(bus.mosi_io_num, FUNC_GPIO, spi_periph_signal[TEST_SLAVE_HOST].spid_in);
|
||||
|
||||
|
||||
//Master MOSI input(spid_in) to `miso_num`, due to SIO mode, we use Master's `spid_in` to receive data
|
||||
spitest_gpio_input_sel(bus.miso_io_num, FUNC_GPIO, spi_periph_signal[TEST_SPI_HOST].spid_in);
|
||||
//Slave MISO output(spiq_out)
|
||||
@ -76,11 +75,9 @@ 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);
|
||||
inner_connect(bus_cfg);
|
||||
|
||||
|
||||
WORD_ALIGNED_ATTR uint8_t master_rx_buffer[320];
|
||||
WORD_ALIGNED_ATTR uint8_t slave_rx_buffer[320];
|
||||
|
||||
@ -114,7 +111,6 @@ TEST_CASE("SPI Single Board Test SIO", "[spi]")
|
||||
ESP_LOG_BUFFER_HEXDUMP("slave rx", slv_trans.rx_buffer, tlen, ESP_LOG_INFO);
|
||||
TEST_ASSERT_EQUAL_HEX8_ARRAY(mst_trans.tx_buffer, slv_trans.rx_buffer, tlen);
|
||||
|
||||
|
||||
ESP_LOGI("spi", "=========== TEST(%d) Master RX, Slave TX ==========", i);
|
||||
//Slave TX
|
||||
memset(&slv_trans, 0x0, sizeof(spi_slave_transaction_t));
|
@ -378,7 +378,6 @@ static int test_freq_mode_local[] = {
|
||||
#define SLAVE_EXTRA_DELAY_DMA 0
|
||||
#endif
|
||||
|
||||
|
||||
static spitest_param_set_t mode_pgroup[] = {
|
||||
{
|
||||
.pset_name = "Mode 0",
|
||||
@ -1269,7 +1268,6 @@ TEST_SPI_MASTER_SLAVE(MODE, mode_conf, "")
|
||||
|
||||
#endif // #if (TEST_SPI_PERIPH_NUM >= 2)
|
||||
|
||||
|
||||
#define TEST_STEP_LEN 96
|
||||
#define TEST_STEP 2
|
||||
static int s_spi_bus_freq[] = {
|
||||
@ -1395,7 +1393,6 @@ static void test_slave_fd_dma(void)
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("TEST_SPI_Freq_FD_DMA", "[spi_ms][timeout=30]", test_master_fd_dma, test_slave_fd_dma);
|
||||
|
||||
|
||||
//------------------------------------------- Full Duplex no DMA Freq test --------------------------------------
|
||||
static void test_master_fd_no_dma(void)
|
||||
{
|
||||
@ -1511,7 +1508,6 @@ static void test_slave_fd_no_dma(void)
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("TEST_SPI_Freq_FD_no_DMA", "[spi_ms][timeout=30]", test_master_fd_no_dma, test_slave_fd_no_dma);
|
||||
|
||||
|
||||
#if SOC_SPI_SUPPORT_SLAVE_HD_VER2
|
||||
//------------------------------------------- Half Duplex with DMA Freq test --------------------------------------
|
||||
static void test_master_hd_dma(void)
|
||||
@ -1614,7 +1610,6 @@ static void test_slave_hd_dma(void)
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("TEST_SPI_Freq_HD_DMA", "[spi_ms][timeout=30]", test_master_hd_dma, test_slave_hd_dma);
|
||||
|
||||
|
||||
//------------------------------------------- Half Duplex no DMA Freq test --------------------------------------
|
||||
static void test_master_hd_no_dma(void)
|
||||
{
|
||||
@ -1717,7 +1712,6 @@ static void test_slave_hd_no_dma(void)
|
||||
TEST_CASE_MULTIPLE_DEVICES("TEST_SPI_Freq_HD_no_DMA", "[spi_ms][timeout=30]", test_master_hd_no_dma, test_slave_hd_no_dma);
|
||||
#endif // SOC_SPI_SUPPORT_SLAVE_HD_VER2
|
||||
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32
|
||||
// item num should same as `s_spi_bus_freq`
|
||||
static int s_master_input_delay[] = {12.5, 12.5 * 2, 12.5 * 2, 12.5 * 5, 12.5 * 5};
|
||||
@ -1853,7 +1847,6 @@ static void test_slave_sio_dma(void)
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("TEST_SPI_Freq_SIO_DMA", "[spi_ms][timeout=30]", test_master_sio_dma, test_slave_sio_dma);
|
||||
|
||||
|
||||
//------------------------------------------- SIO no DMA Freq test --------------------------------------
|
||||
static void test_master_sio_no_dma(void)
|
||||
{
|
@ -15,7 +15,7 @@ project(spi_slave_test)
|
||||
if(CONFIG_COMPILER_DUMP_RTL_FILES)
|
||||
add_custom_target(check_test_app_sections ALL
|
||||
COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py
|
||||
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/driver/,${CMAKE_BINARY_DIR}/esp-idf/hal/
|
||||
--rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_spi/,${CMAKE_BINARY_DIR}/esp-idf/hal/
|
||||
--elf-file ${CMAKE_BINARY_DIR}/spi_slave_test.elf
|
||||
find-refs
|
||||
--from-sections=.iram0.text
|
@ -211,14 +211,19 @@ static void test_hd_start(spi_device_handle_t *spi, int freq, const spitest_para
|
||||
check_no_rx(ctx);
|
||||
check_no_tx(ctx);
|
||||
|
||||
|
||||
srand(9322);
|
||||
for (int i = 0; i < TEST_DMA_MAX_SIZE; i++) ctx->slave_rddma_buf[i] = rand();
|
||||
for (int i = 0; i < TEST_DMA_MAX_SIZE; i++) ctx->master_wrdma_buf[i] = rand();
|
||||
for (int i = 0; i < TEST_DMA_MAX_SIZE; i++) {
|
||||
ctx->slave_rddma_buf[i] = rand();
|
||||
}
|
||||
for (int i = 0; i < TEST_DMA_MAX_SIZE; i++) {
|
||||
ctx->master_wrdma_buf[i] = rand();
|
||||
}
|
||||
|
||||
int pos = rand() % TEST_DMA_MAX_SIZE;
|
||||
int len = rand() % TEST_DMA_MAX_SIZE + 1;
|
||||
if (pos + len > TEST_DMA_MAX_SIZE) len = TEST_DMA_MAX_SIZE - pos;
|
||||
if (pos + len > TEST_DMA_MAX_SIZE) {
|
||||
len = TEST_DMA_MAX_SIZE - pos;
|
||||
}
|
||||
|
||||
ESP_LOGI("rddma_load_len", "%d", len);
|
||||
ctx->tx_data = (spi_slave_hd_data_t) {
|
||||
@ -238,7 +243,6 @@ static void test_hd_start(spi_device_handle_t *spi, int freq, const spitest_para
|
||||
TEST_ESP_OK(err);
|
||||
}
|
||||
|
||||
|
||||
#define REG_REGION_SIZE SOC_SPI_MAXIMUM_BUFFER_SIZE
|
||||
|
||||
void check_no_signal(testhd_context_t* context)
|
||||
@ -254,7 +258,9 @@ void test_wrdma(testhd_context_t* ctx, const spitest_param_set_t *cfg, spi_devic
|
||||
{
|
||||
int pos = rand() % TEST_DMA_MAX_SIZE;
|
||||
int len = rand() % TEST_DMA_MAX_SIZE + 1;
|
||||
if (pos+len > TEST_DMA_MAX_SIZE) len = TEST_DMA_MAX_SIZE - pos;
|
||||
if (pos + len > TEST_DMA_MAX_SIZE) {
|
||||
len = TEST_DMA_MAX_SIZE - pos;
|
||||
}
|
||||
|
||||
int test_seg_size = len;//TEST_SEG_SIZE;
|
||||
ESP_LOGW("test_wrdma", "len: %d, seg_size: %d", len, test_seg_size);
|
||||
@ -283,7 +289,6 @@ void test_rddma(testhd_context_t* ctx, const spitest_param_set_t* cfg, spi_devic
|
||||
int len;
|
||||
int test_seg_size;
|
||||
|
||||
|
||||
len = ctx->tx_data.len;
|
||||
test_seg_size = TEST_SEG_SIZE;
|
||||
|
||||
@ -300,7 +305,9 @@ void test_rddma(testhd_context_t* ctx, const spitest_param_set_t* cfg, spi_devic
|
||||
|
||||
int pos = rand() % TEST_DMA_MAX_SIZE;
|
||||
len = rand() % TEST_DMA_MAX_SIZE + 1;
|
||||
if (pos + len > TEST_DMA_MAX_SIZE) len = TEST_DMA_MAX_SIZE - pos;
|
||||
if (pos + len > TEST_DMA_MAX_SIZE) {
|
||||
len = TEST_DMA_MAX_SIZE - pos;
|
||||
}
|
||||
|
||||
ctx->tx_data = (spi_slave_hd_data_t) {
|
||||
.data = &ctx->slave_rddma_buf[pos],
|
||||
@ -321,8 +328,12 @@ static void test_hd_loop(const void* arg1, void* arg2)
|
||||
for (int j = 0; ; j++) {
|
||||
spi_device_handle_t spi;
|
||||
const int freq = timing_speed_array[j];
|
||||
if (freq==0) break;
|
||||
if (test_cfg->freq_limit && freq > test_cfg->freq_limit) break;
|
||||
if (freq == 0) {
|
||||
break;
|
||||
}
|
||||
if (test_cfg->freq_limit && freq > test_cfg->freq_limit) {
|
||||
break;
|
||||
}
|
||||
|
||||
ESP_LOGI(MASTER_TAG, "======> %dk", freq / 1000);
|
||||
|
||||
@ -353,7 +364,9 @@ static void test_hd_loop(const void* arg1, void* arg2)
|
||||
for (int i = 0; i < 128; i ++) {
|
||||
int pos = rand() % REG_REGION_SIZE;
|
||||
int len = rand() % REG_REGION_SIZE + 1;
|
||||
if (len+pos>REG_REGION_SIZE) len = REG_REGION_SIZE-pos;
|
||||
if (len + pos > REG_REGION_SIZE) {
|
||||
len = REG_REGION_SIZE - pos;
|
||||
}
|
||||
|
||||
memset(recv_buffer, 0xcc, sizeof(recv_buffer));
|
||||
|
||||
@ -395,7 +408,9 @@ static void test_hd_loop(const void* arg1, void* arg2)
|
||||
for (int k = 0; k < 2; k++) {
|
||||
int pos = rand() % REG_REGION_SIZE;
|
||||
int len = rand() % REG_REGION_SIZE + 1;
|
||||
if (len + pos > REG_REGION_SIZE) len = REG_REGION_SIZE - pos;
|
||||
if (len + pos > REG_REGION_SIZE) {
|
||||
len = REG_REGION_SIZE - pos;
|
||||
}
|
||||
|
||||
printf("pos: %d, len: %d\n", pos, len);
|
||||
|
||||
@ -454,7 +469,8 @@ static int test_freq_hd[] = {
|
||||
#define TEST_HD_IN_CONTINUOUS_MODE true
|
||||
|
||||
static spitest_param_set_t hd_conf[] = {
|
||||
{ .pset_name = "MODE0",
|
||||
{
|
||||
.pset_name = "MODE0",
|
||||
.freq_list = test_freq_hd,
|
||||
.dup = FULL_DUPLEX,
|
||||
.master_iomux = false,
|
||||
@ -462,7 +478,8 @@ static spitest_param_set_t hd_conf[] = {
|
||||
.slave_tv_ns = TV_WITH_ESP_SLAVE,
|
||||
.mode = 0,
|
||||
},
|
||||
{ .pset_name = "MODE1",
|
||||
{
|
||||
.pset_name = "MODE1",
|
||||
.freq_list = test_freq_hd,
|
||||
.dup = FULL_DUPLEX,
|
||||
.master_iomux = false,
|
||||
@ -470,7 +487,8 @@ static spitest_param_set_t hd_conf[] = {
|
||||
.slave_tv_ns = TV_WITH_ESP_SLAVE,
|
||||
.mode = 1,
|
||||
},
|
||||
{ .pset_name = "MODE2",
|
||||
{
|
||||
.pset_name = "MODE2",
|
||||
.freq_list = test_freq_hd,
|
||||
.dup = FULL_DUPLEX,
|
||||
.master_iomux = false,
|
||||
@ -478,7 +496,8 @@ static spitest_param_set_t hd_conf[] = {
|
||||
.slave_tv_ns = TV_WITH_ESP_SLAVE,
|
||||
.mode = 2,
|
||||
},
|
||||
{ .pset_name = "MODE3",
|
||||
{
|
||||
.pset_name = "MODE3",
|
||||
.freq_list = test_freq_hd,
|
||||
.dup = FULL_DUPLEX,
|
||||
.master_iomux = false,
|
||||
@ -642,7 +661,6 @@ static void hd_master(void)
|
||||
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]);
|
||||
@ -651,7 +669,6 @@ static void hd_master(void)
|
||||
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);
|
||||
@ -750,7 +767,8 @@ TEST_CASE_MULTIPLE_DEVICES("SPI Slave HD: segment mode, master sends too long",
|
||||
|
||||
#define BUF_SIZE 256
|
||||
|
||||
static void hd_master_quad(void){
|
||||
static void hd_master_quad(void)
|
||||
{
|
||||
spi_bus_config_t bus_cfg = {
|
||||
.miso_io_num = PIN_NUM_MISO,
|
||||
.mosi_io_num = PIN_NUM_MOSI,
|
||||
@ -802,7 +820,8 @@ static void hd_master_quad(void){
|
||||
master_free_device_bus(spi);
|
||||
}
|
||||
|
||||
static void hd_slave_quad(void){
|
||||
static void hd_slave_quad(void)
|
||||
{
|
||||
|
||||
spi_bus_config_t bus_cfg = {
|
||||
.miso_io_num = PIN_NUM_MISO,
|
||||
@ -887,13 +906,12 @@ TEST_CASE_MULTIPLE_DEVICES("SPI quad hd test ", "[spi_ms][test_env=generic_multi
|
||||
|
||||
#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)
|
||||
|
||||
|
||||
|
||||
//***************************************TEST FOR APPEND MODE******************************************//
|
||||
#define TEST_APPEND_CACHE_SIZE 4
|
||||
#define TEST_TRANS_LEN TEST_DMA_MAX_SIZE
|
||||
|
||||
void prepare_data(uint8_t *buff, uint32_t len, int8_t diff){
|
||||
void prepare_data(uint8_t *buff, uint32_t len, int8_t diff)
|
||||
{
|
||||
buff[0] = random();
|
||||
for (int line_index = 1; line_index < len; line_index ++) {
|
||||
buff[line_index] = buff[0] + line_index * diff;
|
||||
@ -989,7 +1007,9 @@ void slave_run_append(void)
|
||||
}
|
||||
}
|
||||
printf("================Master Rx Done==================\n");
|
||||
for (int i = 0; i < TEST_APPEND_CACHE_SIZE; i++) free(slave_tx_trans[i].data);
|
||||
for (int i = 0; i < TEST_APPEND_CACHE_SIZE; i++) {
|
||||
free(slave_tx_trans[i].data);
|
||||
}
|
||||
|
||||
spi_slave_hd_deinit(TEST_SPI_HOST);
|
||||
}
|
@ -27,5 +27,5 @@ endif()
|
||||
idf_component_register(SRCS ${srcs}
|
||||
INCLUDE_DIRS ${includes}
|
||||
PRIV_REQUIRES ${priv_requires}
|
||||
REQUIRES driver esp_driver_gpio
|
||||
REQUIRES driver esp_driver_gpio esp_driver_spi
|
||||
LDFRAGMENTS linker.lf)
|
||||
|
@ -41,7 +41,6 @@ components/esp_lcd/test_apps/rgb_lcd:
|
||||
components/esp_lcd/test_apps/spi_lcd:
|
||||
depends_components:
|
||||
- esp_lcd
|
||||
depends_filepatterns:
|
||||
- components/driver/spi/**/*
|
||||
- esp_driver_spi
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
|
@ -49,7 +49,7 @@ else()
|
||||
|
||||
list(APPEND srcs ${cache_srcs})
|
||||
set(priv_requires bootloader_support app_update soc esp_mm
|
||||
driver esp_driver_gpio # TODO: IDF-8503 move spi_bus_lock to esp_hw_support component
|
||||
esp_driver_gpio esp_driver_spi # TODO: IDF-8503 move spi_bus_lock to esp_hw_support component
|
||||
)
|
||||
endif()
|
||||
|
||||
|
@ -6,13 +6,13 @@ components/spi_flash/test_apps/esp_flash:
|
||||
temporary: true
|
||||
reason: target esp32p4 is not supported yet # TODO: IDF-7499
|
||||
depends_filepatterns:
|
||||
- components/driver/spi/**/*
|
||||
- components/bootloader_support/bootloader_flash/**/*
|
||||
depends_components:
|
||||
- esp_mm
|
||||
- esp_psram
|
||||
- spi_flash
|
||||
- esp_driver_gpio
|
||||
- esp_driver_spi
|
||||
- esptool_py # Some flash related kconfigs are listed here.
|
||||
|
||||
components/spi_flash/test_apps/flash_encryption:
|
||||
@ -53,11 +53,11 @@ components/spi_flash/test_apps/mspi_test:
|
||||
temporary: true
|
||||
reason: not supported yet #TODO: IDF-7556 for p4
|
||||
depends_filepatterns:
|
||||
- components/driver/spi/**/*
|
||||
- components/bootloader_support/bootloader_flash/**/*
|
||||
depends_components:
|
||||
- esp_mm
|
||||
- esp_psram
|
||||
- spi_flash
|
||||
- esp_driver_gpio
|
||||
- esp_driver_spi
|
||||
- esptool_py # Some flash related kconfigs are listed here.
|
||||
|
@ -110,11 +110,11 @@ INPUT = \
|
||||
$(PROJECT_PATH)/components/driver/sdmmc/include/driver/sdmmc_default_configs.h \
|
||||
$(PROJECT_PATH)/components/driver/sdmmc/include/driver/sdmmc_host.h \
|
||||
$(PROJECT_PATH)/components/driver/sdmmc/include/driver/sdmmc_types.h \
|
||||
$(PROJECT_PATH)/components/driver/spi/include/driver/sdspi_host.h \
|
||||
$(PROJECT_PATH)/components/driver/spi/include/driver/spi_common.h \
|
||||
$(PROJECT_PATH)/components/driver/spi/include/driver/spi_master.h \
|
||||
$(PROJECT_PATH)/components/driver/spi/include/driver/spi_slave_hd.h \
|
||||
$(PROJECT_PATH)/components/driver/spi/include/driver/spi_slave.h \
|
||||
$(PROJECT_PATH)/components/driver/sdspi/include/driver/sdspi_host.h \
|
||||
$(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_common.h \
|
||||
$(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_master.h \
|
||||
$(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_slave_hd.h \
|
||||
$(PROJECT_PATH)/components/esp_driver_spi/include/driver/spi_slave.h \
|
||||
$(PROJECT_PATH)/components/driver/temperature_sensor/include/driver/temperature_sensor.h \
|
||||
$(PROJECT_PATH)/components/driver/touch_sensor/include/driver/touch_sensor_common.h \
|
||||
$(PROJECT_PATH)/components/driver/twai/include/driver/twai.h \
|
||||
|
@ -8,7 +8,7 @@ Overview
|
||||
|
||||
The SD/SDIO/MMC driver currently supports SD memory, SDIO cards, and eMMC chips. This is a protocol level driver built on top of SDMMC and SD SPI host drivers.
|
||||
|
||||
SDMMC and SD SPI host drivers (:component_file:`driver/sdmmc/include/driver/sdmmc_host.h` and :component_file:`driver/spi/include/driver/sdspi_host.h`) provide API functions for:
|
||||
SDMMC and SD SPI host drivers (:component_file:`driver/sdmmc/include/driver/sdmmc_host.h` and :component_file:`driver/sdspi/include/driver/sdspi_host.h`) provide API functions for:
|
||||
|
||||
- Sending commands to slave devices
|
||||
- Sending and receiving data
|
||||
|
@ -8,6 +8,7 @@ In order to control the dependence of other components on drivers at a smaller g
|
||||
- `esp_driver_gptimer` - Driver for general purpose timers
|
||||
- `esp_driver_pcnt` - Driver for pulse counter
|
||||
- `esp_driver_gpio` - Driver for GPIO
|
||||
- `esp_driver_spi` - Driver for GPSPI
|
||||
|
||||
For compatibility, the original `driver`` component is still treated as an all-in-one component by registering these `esp_driver_xyz`` components as its public dependencies. In other words, you do not need to modify the CMake file of an existing project, but you now have a way to specify the specific peripheral driver that your project depends on.
|
||||
|
||||
|
@ -8,7 +8,7 @@ SD/SDIO/MMC 驱动程序
|
||||
|
||||
SD/SDIO/MMC 驱动是一种基于 SDMMC 和 SD SPI 主机驱动的协议级驱动程序,目前已支持 SD 存储器、SDIO 卡和 eMMC 芯片。
|
||||
|
||||
SDMMC 主机驱动和 SD SPI 主机驱动(:component_file:`driver/sdmmc/include/driver/sdmmc_host.h` 和 :component_file:`driver/spi/include/driver/sdspi_host.h`)为以下功能提供 API:
|
||||
SDMMC 主机驱动和 SD SPI 主机驱动(:component_file:`driver/sdmmc/include/driver/sdmmc_host.h` 和 :component_file:`driver/sdspi/include/driver/sdspi_host.h`)为以下功能提供 API:
|
||||
|
||||
- 发送命令至从设备
|
||||
- 接收和发送数据
|
||||
|
@ -8,6 +8,7 @@
|
||||
- `esp_driver_gptimer` - 通用定时器驱动
|
||||
- `esp_driver_pcnt` - 脉冲计数器驱动
|
||||
- `esp_driver_gpio` - GPIO 驱动
|
||||
- `esp_driver_spi` - 通用 SPI 驱动
|
||||
|
||||
为了兼容性,原来的 `driver` 组件仍然存在,并作为一个 “all-in-one" 的组件,将以上这些 `esp_driver_xyz` 组件注册成自己的公共依赖。换句话说,你无需修改既有项目的 CMake 文件,但是你现在多了一个途径去指定你项目依赖的具体的外设驱动。
|
||||
|
||||
|
@ -9,8 +9,7 @@ examples/ethernet/basic:
|
||||
- lwip
|
||||
- esp_event
|
||||
- esp_driver_gpio
|
||||
depends_filepatterns:
|
||||
- components/driver/spi/**/*
|
||||
- esp_driver_spi
|
||||
|
||||
examples/ethernet/enc28j60:
|
||||
disable:
|
||||
@ -23,8 +22,7 @@ examples/ethernet/enc28j60:
|
||||
- lwip
|
||||
- esp_event
|
||||
- esp_driver_gpio
|
||||
depends_filepatterns:
|
||||
- components/driver/spi/**/*
|
||||
- esp_driver_spi
|
||||
|
||||
examples/ethernet/iperf:
|
||||
disable_test:
|
||||
@ -38,8 +36,8 @@ examples/ethernet/iperf:
|
||||
- esp_event
|
||||
- console
|
||||
- esp_driver_gpio
|
||||
- esp_driver_spi
|
||||
depends_filepatterns:
|
||||
- components/driver/spi/**/*
|
||||
- examples/common_components/iperf/**/*
|
||||
- examples/common_components/protocol_examples_common/**/*
|
||||
- examples/system/console/advanced/components/cmd_system/**/*
|
||||
|
@ -4,8 +4,8 @@ examples/network/bridge:
|
||||
disable_test:
|
||||
- if: IDF_TARGET != "esp32"
|
||||
reason: Generic functionality, no need to be run on specific targets
|
||||
depends_filepatterns:
|
||||
- components/driver/spi/**/*
|
||||
depends_components:
|
||||
- esp_driver_spi
|
||||
|
||||
examples/network/eth2ap:
|
||||
disable:
|
||||
|
@ -131,16 +131,14 @@ examples/peripherals/lcd/spi_lcd_touch:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
depends_components:
|
||||
- esp_lcd
|
||||
depends_filepatterns:
|
||||
- components/driver/spi/**/*
|
||||
- esp_driver_spi
|
||||
|
||||
examples/peripherals/lcd/tjpgd:
|
||||
disable:
|
||||
- if: SOC_GPSPI_SUPPORTED != 1
|
||||
depends_components:
|
||||
- esp_lcd
|
||||
depends_filepatterns:
|
||||
- components/driver/spi/**/*
|
||||
- esp_driver_spi
|
||||
|
||||
examples/peripherals/ledc:
|
||||
disable:
|
||||
|
@ -7,12 +7,12 @@ idf_component_get_property(original_driver_dir driver COMPONENT_OVERRIDEN_DIR)
|
||||
set(include_dirs
|
||||
"${IDF_PATH}/components/esp_driver_gpio/include/driver"
|
||||
"${IDF_PATH}/components/esp_driver_gpio/include"
|
||||
"${IDF_PATH}/components/esp_driver_spi/include/driver"
|
||||
"${IDF_PATH}/components/esp_driver_spi/include"
|
||||
"${original_driver_dir}/i2c/include/driver"
|
||||
"${original_driver_dir}/spi/include/driver"
|
||||
"${original_driver_dir}/rmt/include/driver"
|
||||
"${original_driver_dir}/usb_serial_jtag/include/driver"
|
||||
"${original_driver_dir}/i2c/include"
|
||||
"${original_driver_dir}/spi/include"
|
||||
"${original_driver_dir}/rmt/include"
|
||||
"${original_driver_dir}/usb_serial_jtag/include"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/../hal/include")
|
||||
@ -21,8 +21,8 @@ idf_component_mock(INCLUDE_DIRS ${include_dirs}
|
||||
REQUIRES freertos
|
||||
MOCK_HEADER_FILES
|
||||
${IDF_PATH}/components/esp_driver_gpio/include/driver/gpio.h
|
||||
${original_driver_dir}/spi/include/driver/spi_master.h
|
||||
${original_driver_dir}/spi/include/driver/spi_common.h
|
||||
${IDF_PATH}/components/esp_driver_spi/include/driver/spi_master.h
|
||||
${IDF_PATH}/components/esp_driver_spi/include/driver/spi_common.h
|
||||
${original_driver_dir}/i2c/include/driver/i2c.h
|
||||
${original_driver_dir}/rmt/include/driver/rmt_rx.h
|
||||
${original_driver_dir}/rmt/include/driver/rmt_tx.h
|
||||
|
@ -35,7 +35,7 @@ set(extra_components_which_shouldnt_be_included
|
||||
cxx
|
||||
# [refactor-todo]: driver is a dependency of esp_pm, spi_flash, vfs, esp_wifi
|
||||
# all of these should be removed from G1 except for spi_flash.
|
||||
driver esp_driver_gpio esp_driver_pcnt esp_driver_gptimer
|
||||
driver esp_driver_gpio esp_driver_pcnt esp_driver_gptimer esp_driver_spi
|
||||
# esp_app_format is dependency of bootloader_support, app_update
|
||||
esp_app_format
|
||||
# esp_bootloader_format is dependency of bootloader_support, app_update
|
||||
|
Loading…
x
Reference in New Issue
Block a user