Merge branch 'test/move_gpspi_to_pytest_app' into 'master'

spi: move spi related unit test into itself pytest app

Closes IDF-5499 and IDFCI-1377

See merge request espressif/esp-idf!19341
This commit is contained in:
Wan Lei
2022-11-11 12:18:26 +08:00
61 changed files with 742 additions and 321 deletions

View File

@@ -1874,19 +1874,6 @@
when: never
- <<: *if-label-unit_test_esp32c2
.rules:test:unit_test-esp32c2-spi_multi:
rules:
- <<: *if-revert-branch
when: never
- <<: *if-protected
- <<: *if-label-build-only
when: never
- <<: *if-label-target_test
- <<: *if-label-unit_test
- <<: *if-label-unit_test_esp32c2
- <<: *if-dev-push
changes: *patterns-unit_test-spi_multi
.rules:test:unit_test-esp32c3:
rules:
- <<: *if-revert-branch

View File

@@ -452,6 +452,14 @@ component_ut_pytest_esp32c2_adc:
- build_pytest_components_esp32c2
tags: [ esp32c2, adc ]
component_ut_pytest_esp32c2_generic_multi_device:
extends:
- .pytest_components_dir_template
- .rules:test:component_ut-esp32c2
needs:
- build_pytest_components_esp32c2
tags: [ esp32c2, generic_multi_device, xtal_40mhz ]
component_ut_pytest_esp32c2_xtal_26mhz:
extends:
- .pytest_components_dir_template
@@ -975,13 +983,6 @@ UT_018:
- UT_T1_1
- 8Mpsram
UT_020:
extends: .unit_test_esp32_template
tags:
- ESP32_IDF
- Example_SPI_Multi_device
- psram
UT_022:
extends: .unit_test_esp32_template
tags:
@@ -1060,37 +1061,6 @@ UT_045:
- UT_SDIO
- psram
UT_S2_SPI_DUAL:
extends: .unit_test_esp32s2_template
tags:
- ESP32S2_IDF
- Example_SPI_Multi_device
UT_S2_SPI_QUAD:
extends: .unit_test_esp32s2_template
tags:
- ESP32S2_IDF
- Example_SPI_Quad_Multi_device
UT_S3_SPI_QUAD:
extends: .unit_test_esp32s3_template
tags:
- ESP32S3_IDF
- Example_SPI_Quad_Multi_device
UT_C2_SPI_QUAD:
extends: .unit_test_esp32c2_template
tags:
- ESP32C2_IDF
- Example_SPI_Quad_Multi_device
- xtal_40mhz
UT_C3_SPI_QUAD:
extends: .unit_test_esp32c3_template
tags:
- ESP32C3_IDF
- Example_SPI_Quad_Multi_device
UT_S2_SDSPI:
extends: .unit_test_esp32s2_template
tags:
@@ -1105,15 +1075,6 @@ UT_C2:
- UT_T1_1
- xtal_40mhz
UT_C2_SPI_DUAL:
extends:
- .unit_test_esp32c2_template
- .rules:test:unit_test-esp32c2-spi_multi
tags:
- ESP32C2_IDF
- Example_SPI_Multi_device
- xtal_40mhz
UT_C2_26M:
extends: .unit_test_esp32c2_template
tags:
@@ -1142,12 +1103,6 @@ UT_C3_FLASH:
- ESP32C3_IDF
- UT_T1_ESP_FLASH
UT_C3_SPI_DUAL:
extends: .unit_test_esp32c3_template
tags:
- ESP32C3_IDF
- Example_SPI_Multi_device
UT_C3_I2C:
extends: .unit_test_esp32c3_template
tags:
@@ -1181,12 +1136,6 @@ UT_S3_QUAD_PSRAM:
- UT_T1_1
- quad_psram
UT_S3_SPI_DUAL:
extends: .unit_test_esp32s3_template
tags:
- ESP32S3_IDF
- Example_SPI_Multi_device
UT_S3_FLASH:
extends: .unit_test_esp32s3_template
tags:

View File

@@ -1,8 +1,6 @@
idf_component_register(SRC_DIRS . param_test
PRIV_INCLUDE_DIRS include param_test/include
PRIV_REQUIRES cmock test_utils driver nvs_flash
esp_timer esp_adc esp_event esp_wifi spi_flash)
idf_component_register(
SRC_DIRS .
PRIV_INCLUDE_DIRS include
PRIV_REQUIRES test_utils driver nvs_flash esp_timer esp_event test_driver_utils esp_serial_slave_link
)
target_compile_options(${COMPONENT_LIB} PRIVATE "-Wno-format")
# A local copy of idf-extra-components esp_serial_slave_link, for stabilities of the SDIO test
add_subdirectory(esp_serial_slave_link)

View File

@@ -1,11 +0,0 @@
set(srcs "essl.c" "essl_sdio.c" "essl_spi.c")
set(include "include")
set(priv_include "." "include/esp_serial_slave_link")
set(priv_req idf::sdmmc idf::driver)
add_prefix(srcs "${CMAKE_CURRENT_LIST_DIR}/" "${srcs}")
target_sources(${COMPONENT_LIB} PRIVATE "${srcs}")
target_include_directories(${COMPONENT_LIB} PUBLIC ${include})
target_include_directories(${COMPONENT_LIB} PRIVATE ${priv_include})
target_link_libraries(${COMPONENT_LIB} PRIVATE ${priv_req})

View File

@@ -6,7 +6,7 @@
#include "unity.h"
#include "test_utils.h"
#include "param_test.h"
#include "test_spi_utils.h"
#include "esp_log.h"
#include "esp_timer.h"
#include "soc/soc_caps.h"
@@ -115,8 +115,6 @@ const sdio_test_config_t* default_config = &test_cfg_array[0];
#define TEST_SIZE (sizeof(test_cfg_array)/sizeof(sdio_test_config_t))
static const char MASTER_TAG[] = "master";
static const char SLAVE_TAG[] = "slave";
/*******************************************************************************
* Master

View File

@@ -0,0 +1,6 @@
idf_component_register(
SRCS "essl.c" "essl_sdio.c" "essl_spi.c"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "." "include/esp_serial_slave_link"
REQUIRES sdmmc driver
)

View File

@@ -4,10 +4,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "essl.h"
#include "essl_internal.h"
#include "esp_log.h"
#include "freertos/task.h"
#define TIME_EXPIRED_SINCE_CORE(start, end, timeout, max) (bool)((end)>=(start)? \
((end)-(start)>(timeout)) :\
@@ -142,7 +144,7 @@ esp_err_t essl_get_tx_buffer_num(essl_handle_t handle, uint32_t *out_tx_num, uin
if (handle == NULL || out_tx_num == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (handle->update_tx_buffer_num == NULL|| handle->get_tx_buffer_num == NULL) {
if (handle->update_tx_buffer_num == NULL || handle->get_tx_buffer_num == NULL) {
return ESP_ERR_NOT_SUPPORTED;
}
@@ -160,7 +162,7 @@ esp_err_t essl_get_rx_data_size(essl_handle_t handle, uint32_t *out_rx_size, uin
if (handle == NULL || out_rx_size == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (handle->update_rx_data_size == NULL|| handle->get_rx_data_size == NULL) {
if (handle->update_rx_data_size == NULL || handle->get_rx_data_size == NULL) {
return ESP_ERR_NOT_SUPPORTED;
}

View File

@@ -12,23 +12,23 @@
/** Context used by the ``esp_serial_slave_link`` component.
*/
struct essl_dev_t {
void* args;
void *args;
esp_err_t (*init)(void* ctx, uint32_t wait_ms);
esp_err_t (*init)(void *ctx, uint32_t wait_ms);
esp_err_t (*wait_for_ready)(void *ctx, uint32_t wait_ms);
esp_err_t (*update_tx_buffer_num)(void *ctx, uint32_t wait_ms);
esp_err_t (*update_rx_data_size)(void *ctx, uint32_t wait_ms);
esp_err_t (*send_packet)(void *ctx, const void* start, size_t length, uint32_t wait_ms);
esp_err_t (*get_packet)(void *ctx, void* out_data, size_t size, uint32_t wait_ms);
esp_err_t (*write_reg)(void *ctx, uint8_t addr, uint8_t value, uint8_t* value_o, uint32_t wait_ms);
esp_err_t (*send_packet)(void *ctx, const void *start, size_t length, uint32_t wait_ms);
esp_err_t (*get_packet)(void *ctx, void *out_data, size_t size, uint32_t wait_ms);
esp_err_t (*write_reg)(void *ctx, uint8_t addr, uint8_t value, uint8_t *value_o, uint32_t wait_ms);
esp_err_t (*read_reg)(void *ctx, uint8_t add, uint8_t *value_o, uint32_t wait_ms);
esp_err_t (*wait_int)(void *ctx, uint32_t wait_ms);
esp_err_t (*clear_intr)(void* ctx, uint32_t intr_mask, uint32_t wait_ms);
esp_err_t (*get_intr)(void* ctx, uint32_t* intr_raw, uint32_t *intr_st, uint32_t wait_ms);
esp_err_t (*set_intr_ena)(void* ctx, uint32_t ena_mask, uint32_t wait_ms);
esp_err_t (*get_intr_ena)(void* ctx, uint32_t* ena_mask_o, uint32_t wait_ms);
esp_err_t (*send_slave_intr)(void* ctx, uint32_t intr_mask, uint32_t wait_ms);
esp_err_t (*clear_intr)(void *ctx, uint32_t intr_mask, uint32_t wait_ms);
esp_err_t (*get_intr)(void *ctx, uint32_t *intr_raw, uint32_t *intr_st, uint32_t wait_ms);
esp_err_t (*set_intr_ena)(void *ctx, uint32_t ena_mask, uint32_t wait_ms);
esp_err_t (*get_intr_ena)(void *ctx, uint32_t *ena_mask_o, uint32_t wait_ms);
esp_err_t (*send_slave_intr)(void *ctx, uint32_t intr_mask, uint32_t wait_ms);
uint32_t (*get_tx_buffer_num)(void *ctx);
uint32_t (*get_rx_data_size)(void *ctx);

View File

@@ -4,11 +4,13 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "essl_sdio.h"
#include "esp_log.h"
#include "freertos/task.h"
#include "essl_internal.h"
#include "soc/soc_caps.h"
#include "esp_log.h"
#include "sdmmc_cmd.h"
#include "driver/sdmmc_defs.h"
#include "essl_internal.h"
#include "essl_sdio.h"
#if SOC_SDIO_SLAVE_SUPPORTED
#include "soc/host_reg.h"
@@ -48,21 +50,21 @@ static const char TAG[] = "essl_sdio";
.reset_cnt = essl_sdio_reset_cnt, \
}
typedef struct{
typedef struct {
//common part
uint16_t buffer_size;
///< All data that do not fully fill a buffer is still counted as one buffer. E.g. 10 bytes data costs 2 buffers if the size is 8 bytes per buffer.
///< Buffer size of the slave pre-defined between host and slave before communication.
///< All data that do not fully fill a buffer is still counted as one buffer. E.g. 10 bytes data costs 2 buffers if the size is 8 bytes per buffer.
///< Buffer size of the slave pre-defined between host and slave before communication.
size_t tx_sent_buffers; ///< Counter holding the amount of buffers already sent to ESP32 slave. Should be set to 0 when initialization.
size_t tx_sent_buffers_latest; ///< The latest reading (from the slave) of counter holding the amount of buffers loaded. Should be set to 0 when initialization.
size_t rx_got_bytes; ///< Counter holding the amount of bytes already received from ESP32 slave. Should be set to 0 when initialization.
size_t rx_got_bytes_latest; ///< The latest reading (from the slave) of counter holding the amount of bytes to send. Should be set to 0 when initialization.
sdmmc_card_t* card; ///< Initialized sdmmc_cmd card
sdmmc_card_t *card; ///< Initialized sdmmc_cmd card
uint16_t block_size;
///< If this is too large, it takes time to send stuff bits; while if too small, intervals between blocks cost much.
///< Should be set according to length of data, and larger than ``TRANS_LEN_MAX/511``.
///< Block size of the SDIO function 1. After the initialization this will hold the value the slave really do. Valid value is 1-2048.
///< If this is too large, it takes time to send stuff bits; while if too small, intervals between blocks cost much.
///< Should be set according to length of data, and larger than ``TRANS_LEN_MAX/511``.
///< Block size of the SDIO function 1. After the initialization this will hold the value the slave really do. Valid value is 1-2048.
} essl_sdio_context_t;
@@ -71,31 +73,31 @@ esp_err_t essl_sdio_update_rx_data_size(void *arg, uint32_t wait_ms);
static inline esp_err_t essl_sdio_write_byte(sdmmc_card_t *card, uint32_t addr, uint8_t val, uint8_t *val_o)
{
return sdmmc_io_write_byte(card, 1, addr&0x3FF, val, val_o);
return sdmmc_io_write_byte(card, 1, addr & 0x3FF, val, val_o);
}
static inline esp_err_t essl_sdio_write_bytes(sdmmc_card_t *card, uint32_t addr, uint8_t *val, int len)
{
return sdmmc_io_write_bytes(card, 1, addr&0x3FF, val, len);
return sdmmc_io_write_bytes(card, 1, addr & 0x3FF, val, len);
}
static inline esp_err_t essl_sdio_read_byte(sdmmc_card_t *card, uint32_t addr, uint8_t *val_o)
{
return sdmmc_io_read_byte(card, 1, addr&0x3FF, val_o);
return sdmmc_io_read_byte(card, 1, addr & 0x3FF, val_o);
}
static inline esp_err_t essl_sdio_read_bytes(sdmmc_card_t *card, uint32_t addr, uint8_t *val_o, int len)
{
return sdmmc_io_read_bytes(card, 1, addr&0x3FF, val_o, len);
return sdmmc_io_read_bytes(card, 1, addr & 0x3FF, val_o, len);
}
esp_err_t essl_sdio_init_dev(essl_handle_t *out_handle, const essl_sdio_config_t *config)
{
esp_err_t ret = ESP_OK;
essl_sdio_context_t* arg = NULL;
essl_dev_t* dev = NULL;
arg = (essl_sdio_context_t*)heap_caps_malloc(sizeof(essl_sdio_context_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
dev = (essl_dev_t*)heap_caps_malloc(sizeof(essl_dev_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
essl_sdio_context_t *arg = NULL;
essl_dev_t *dev = NULL;
arg = (essl_sdio_context_t *)heap_caps_malloc(sizeof(essl_sdio_context_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
dev = (essl_dev_t *)heap_caps_malloc(sizeof(essl_dev_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (arg == NULL || dev == NULL) {
ret = ESP_ERR_NO_MEM;
@@ -124,78 +126,96 @@ cleanup:
esp_err_t essl_sdio_deinit_dev(essl_handle_t handle)
{
if (handle) free (handle->args);
if (handle) {
free (handle->args);
}
free(handle);
return ESP_OK;
}
esp_err_t essl_sdio_init(void *arg, uint32_t wait_ms)
{
essl_sdio_context_t* ctx = arg;
essl_sdio_context_t *ctx = arg;
esp_err_t err;
uint8_t ioe = 0;
sdmmc_card_t* card = ctx->card;
sdmmc_card_t *card = ctx->card;
err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_ENABLE, &ioe);
if (err != ESP_OK) return err;
ESP_LOGD(TAG, "IOE: 0x%02x", ioe);
if (err != ESP_OK) {
return err;
}
ESP_LOGD(TAG, "IOE: 0x%02"PRIx8, ioe);
uint8_t ior = 0;
err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_READY, &ior);
if (err != ESP_OK) return err;
ESP_LOGD(TAG, "IOR: 0x%02x", ior);
if (err != ESP_OK) {
return err;
}
ESP_LOGD(TAG, "IOR: 0x%02"PRIx8, ior);
// enable function 1
ioe |= FUNC1_EN_MASK;
err = sdmmc_io_write_byte(card, 0, SD_IO_CCCR_FN_ENABLE, ioe, &ioe);
if (err != ESP_OK) return err;
ESP_LOGD(TAG, "IOE: 0x%02x", ioe);
if (err != ESP_OK) {
return err;
}
ESP_LOGD(TAG, "IOE: 0x%02"PRIx8, ioe);
// wait for the card to become ready
while ((ior & FUNC1_EN_MASK) == 0) {
err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_READY, &ior);
if (err != ESP_OK) return err;
ESP_LOGD(TAG, "IOR: 0x%02x", ior);
if (err != ESP_OK) {
return err;
}
ESP_LOGD(TAG, "IOR: 0x%02"PRIx8, ior);
}
// get interrupt status
uint8_t ie = 0;
err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_INT_ENABLE, &ie);
if (err != ESP_OK) return err;
ESP_LOGD(TAG,"IE: 0x%02x", ie);
if (err != ESP_OK) {
return err;
}
ESP_LOGD(TAG, "IE: 0x%02"PRIx8, ie);
// enable interrupts for function 1&2 and master enable
ie |= BIT(0) | FUNC1_EN_MASK;
err = sdmmc_io_write_byte(card, 0, SD_IO_CCCR_INT_ENABLE, ie, &ie);
if (err != ESP_OK) return err;
ESP_LOGD(TAG, "IE: 0x%02x", ie);
if (err != ESP_OK) {
return err;
}
ESP_LOGD(TAG, "IE: 0x%02"PRIx8, ie);
// get bus width register
uint8_t bus_width = 0;
err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BUS_WIDTH, &bus_width);
if (err != ESP_OK) return err;
ESP_LOGD(TAG,"BUS_WIDTH: 0x%02x", bus_width);
if (err != ESP_OK) {
return err;
}
ESP_LOGD(TAG, "BUS_WIDTH: 0x%02"PRIx8, bus_width);
// enable continuous SPI interrupts
bus_width |= CCCR_BUS_WIDTH_ECSI;
err = sdmmc_io_write_byte(card, 0, SD_IO_CCCR_BUS_WIDTH, bus_width, &bus_width);
if (err != ESP_OK) return err;
ESP_LOGD(TAG, "BUS_WIDTH: 0x%02x", bus_width);
if (err != ESP_OK) {
return err;
}
ESP_LOGD(TAG, "BUS_WIDTH: 0x%02"PRIx8, bus_width);
uint16_t bs = 512;
const uint8_t* bs_u8 = (const uint8_t*) &bs;
const uint8_t *bs_u8 = (const uint8_t *) &bs;
uint16_t bs_read = 0;
uint8_t* bs_read_u8 = (uint8_t*) &bs_read;
uint8_t *bs_read_u8 = (uint8_t *) &bs_read;
// Set block sizes for functions 0 to 512 bytes
ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
ESP_LOGD(TAG, "Function 0 BS: %04x", (int) bs_read);
ESP_LOGD(TAG, "Function 0 BS: %d", (unsigned int) bs_read);
ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, SD_IO_CCCR_BLKSIZEL, bs_u8[0], NULL));
ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, SD_IO_CCCR_BLKSIZEH, bs_u8[1], NULL));
ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
ESP_LOGD(TAG, "Function 0 BS: %04x", (int) bs_read);
ESP_LOGD(TAG, "Function 0 BS: %d", (unsigned int) bs_read);
// Set block sizes for functions 1 to given value (default value = 512).
if (ctx->block_size > 0 && ctx->block_size <= 2048) {
@@ -206,13 +226,13 @@ esp_err_t essl_sdio_init(void *arg, uint32_t wait_ms)
size_t offset = SD_IO_FBR_START * 1;
ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
ESP_LOGD(TAG, "Function 1 BS: %04x", (int) bs_read);
ESP_LOGD(TAG, "Function 1 BS: %d", (unsigned int) bs_read);
ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEL, bs_u8[0], NULL));
ESP_ERROR_CHECK(sdmmc_io_write_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEH, bs_u8[1], NULL));
ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEL, &bs_read_u8[0]));
ESP_ERROR_CHECK(sdmmc_io_read_byte(card, 0, offset + SD_IO_CCCR_BLKSIZEH, &bs_read_u8[1]));
ESP_LOGD(TAG, "Function 1 BS: %04x", (int) bs_read);
ESP_LOGD(TAG, "Function 1 BS: %d", (unsigned int) bs_read);
if (bs_read != ctx->block_size) {
ESP_LOGW(TAG, "Function1 block size %d different than set value %d", bs_read, ctx->block_size);
@@ -225,12 +245,14 @@ esp_err_t essl_sdio_wait_for_ready(void *arg, uint32_t wait_ms)
{
ESP_LOGV(TAG, "wait_for_ioready");
esp_err_t err;
sdmmc_card_t *card = ((essl_sdio_context_t*)arg)->card;
sdmmc_card_t *card = ((essl_sdio_context_t *)arg)->card;
// wait for the card to become ready
uint8_t ior = 0;
while ((ior & FUNC1_EN_MASK) == 0) {
err = sdmmc_io_read_byte(card, 0, SD_IO_CCCR_FN_READY, &ior);
if (err != ESP_OK) return err;
if (err != ESP_OK) {
return err;
}
ESP_LOGD(TAG, "IOR: 0x%02x", ior);
}
return ESP_OK;
@@ -238,9 +260,9 @@ esp_err_t essl_sdio_wait_for_ready(void *arg, uint32_t wait_ms)
esp_err_t essl_sdio_send_packet(void *arg, const void *start, size_t length, uint32_t wait_ms)
{
essl_sdio_context_t* ctx = arg;
essl_sdio_context_t *ctx = arg;
uint16_t buffer_size = ctx->buffer_size;
int buffer_used = (length + buffer_size - 1)/buffer_size;
int buffer_used = (length + buffer_size - 1) / buffer_size;
esp_err_t err;
if (essl_sdio_get_tx_buffer_num(arg) < buffer_used) {
@@ -257,7 +279,7 @@ esp_err_t essl_sdio_send_packet(void *arg, const void *start, size_t length, uin
ESP_LOGV(TAG, "send_packet: len: %d", length);
uint8_t *start_ptr = (uint8_t*)start;
uint8_t *start_ptr = (uint8_t *)start;
uint32_t len_remain = length;
do {
const int block_size = 512;
@@ -266,7 +288,7 @@ esp_err_t essl_sdio_send_packet(void *arg, const void *start, size_t length, uin
* higher effeciency. The length is determined by the SDIO address, and
* the remainning will be discard by the slave hardware.
*/
int block_n = len_remain/block_size;
int block_n = len_remain / block_size;
int len_to_send;
if (block_n) {
len_to_send = block_n * block_size;
@@ -275,7 +297,9 @@ esp_err_t essl_sdio_send_packet(void *arg, const void *start, size_t length, uin
len_to_send = len_remain;
err = sdmmc_io_write_bytes(ctx->card, 1, ESSL_CMD53_END_ADDR - len_remain, start_ptr, (len_to_send + 3) & (~3));
}
if (err != ESP_OK) return err;
if (err != ESP_OK) {
return err;
}
start_ptr += len_to_send;
len_remain -= len_to_send;
} while (len_remain);
@@ -286,7 +310,7 @@ esp_err_t essl_sdio_send_packet(void *arg, const void *start, size_t length, uin
esp_err_t essl_sdio_get_packet(void *arg, void *out_data, size_t size, uint32_t wait_ms)
{
essl_sdio_context_t* ctx = arg;
essl_sdio_context_t *ctx = arg;
esp_err_t err;
ESP_LOGV(TAG, "get_packet: read size=%d", size);
@@ -306,7 +330,7 @@ esp_err_t essl_sdio_get_packet(void *arg, void *out_data, size_t size, uint32_t
const int block_size = 512; //currently our driver don't support block size other than 512
int len_to_send;
int block_n = len_remain/block_size;
int block_n = len_remain / block_size;
if (block_n != 0) {
len_to_send = block_n * block_size;
err = sdmmc_io_read_blocks(ctx->card, 1, ESSL_CMD53_END_ADDR - len_remain, start, len_to_send);
@@ -319,52 +343,58 @@ esp_err_t essl_sdio_get_packet(void *arg, void *out_data, size_t size, uint32_t
*/
err = sdmmc_io_read_bytes(ctx->card, 1, ESSL_CMD53_END_ADDR - len_remain, start, (len_to_send + 3) & (~3));
}
if (err != ESP_OK) return err;
if (err != ESP_OK) {
return err;
}
start += len_to_send;
len_remain -= len_to_send;
ctx->rx_got_bytes += len_to_send;
} while(len_remain!=0);
} while (len_remain != 0);
return err;
}
uint32_t essl_sdio_get_tx_buffer_num(void *arg)
{
essl_sdio_context_t* ctx = arg;
essl_sdio_context_t *ctx = arg;
ESP_LOGV(TAG, "tx latest: %d, sent: %d", ctx->tx_sent_buffers_latest, ctx->tx_sent_buffers);
return (ctx->tx_sent_buffers_latest + TX_BUFFER_MAX - ctx->tx_sent_buffers)%TX_BUFFER_MAX;
return (ctx->tx_sent_buffers_latest + TX_BUFFER_MAX - ctx->tx_sent_buffers) % TX_BUFFER_MAX;
}
esp_err_t essl_sdio_update_tx_buffer_num(void *arg, uint32_t wait_ms)
{
essl_sdio_context_t* ctx = arg;
essl_sdio_context_t *ctx = arg;
uint32_t len;
esp_err_t err;
err = essl_sdio_read_bytes(ctx->card, HOST_SLC0HOST_TOKEN_RDATA_REG, (uint8_t *) &len, 4);
if (err != ESP_OK) return err;
len = (len>>16)&TX_BUFFER_MASK;
if (err != ESP_OK) {
return err;
}
len = (len >> 16)&TX_BUFFER_MASK;
ctx->tx_sent_buffers_latest = len;
ESP_LOGV(TAG, "update_tx_buffer_num: %d", len);
ESP_LOGV(TAG, "update_tx_buffer_num: %d", (unsigned int)len);
return ESP_OK;
}
uint32_t essl_sdio_get_rx_data_size(void *arg)
{
essl_sdio_context_t* ctx = arg;
essl_sdio_context_t *ctx = arg;
ESP_LOGV(TAG, "rx latest: %d, read: %d", ctx->rx_got_bytes_latest, ctx->rx_got_bytes);
return (ctx->rx_got_bytes_latest + RX_BYTE_MAX - ctx->rx_got_bytes)%RX_BYTE_MAX;
return (ctx->rx_got_bytes_latest + RX_BYTE_MAX - ctx->rx_got_bytes) % RX_BYTE_MAX;
}
esp_err_t essl_sdio_update_rx_data_size(void *arg, uint32_t wait_ms)
{
essl_sdio_context_t* ctx = arg;
essl_sdio_context_t *ctx = arg;
uint32_t len;
esp_err_t err;
ESP_LOGV(TAG, "get_rx_data_size: got_bytes: %d", ctx->rx_got_bytes);
err = essl_sdio_read_bytes(ctx->card, HOST_SLCHOST_PKT_LEN_REG, (uint8_t *) &len, 4);
if (err != ESP_OK) return err;
if (err != ESP_OK) {
return err;
}
len &= RX_BYTE_MASK;
ctx->rx_got_bytes_latest = len;
return ESP_OK;
@@ -373,80 +403,95 @@ esp_err_t essl_sdio_update_rx_data_size(void *arg, uint32_t wait_ms)
esp_err_t essl_sdio_write_reg(void *arg, uint8_t addr, uint8_t value, uint8_t *value_o, uint32_t wait_ms)
{
ESP_LOGV(TAG, "write_reg: %08X", value);
ESP_LOGV(TAG, "write_reg: 0x%02"PRIX8, value);
// addrress over range
if (addr >= 60) return ESP_ERR_INVALID_ARG;
if (addr >= 60) {
return ESP_ERR_INVALID_ARG;
}
//W7 is reserved for interrupts
if (addr >= 28) addr += 4;
return essl_sdio_write_byte(((essl_sdio_context_t*)arg)->card, HOST_SLCHOST_CONF_W_REG(addr), value, value_o);
if (addr >= 28) {
addr += 4;
}
return essl_sdio_write_byte(((essl_sdio_context_t *)arg)->card, HOST_SLCHOST_CONF_W_REG(addr), value, value_o);
}
esp_err_t essl_sdio_read_reg(void *arg, uint8_t add, uint8_t *value_o, uint32_t wait_ms)
{
ESP_LOGV(TAG, "read_reg");
// address over range
if (add >= 60) return ESP_ERR_INVALID_ARG;
if (add >= 60) {
return ESP_ERR_INVALID_ARG;
}
//W7 is reserved for interrupts
if (add >= 28) add += 4;
esp_err_t ret = essl_sdio_read_byte(((essl_sdio_context_t*)arg)->card, HOST_SLCHOST_CONF_W_REG(add), value_o);
ESP_LOGV(TAG, "reg: %08X", *value_o);
if (add >= 28) {
add += 4;
}
esp_err_t ret = essl_sdio_read_byte(((essl_sdio_context_t *)arg)->card, HOST_SLCHOST_CONF_W_REG(add), value_o);
ESP_LOGV(TAG, "reg: %02"PRIX8, *value_o);
return ret;
}
esp_err_t essl_sdio_clear_intr(void *arg, uint32_t intr_mask, uint32_t wait_ms)
{
ESP_LOGV(TAG, "clear_intr: %08X", intr_mask);
ESP_LOGV(TAG, "clear_intr: %08"PRIX32, intr_mask);
return essl_sdio_write_bytes(((essl_sdio_context_t *) arg)->card, HOST_SLC0HOST_INT_CLR_REG, (uint8_t *) &intr_mask, 4);
}
esp_err_t essl_sdio_get_intr(void *arg, uint32_t *intr_raw, uint32_t *intr_st, uint32_t wait_ms)
{
essl_sdio_context_t* ctx = arg;
essl_sdio_context_t *ctx = arg;
esp_err_t r;
ESP_LOGV(TAG, "get_intr");
if (intr_raw == NULL && intr_st == NULL) return ESP_ERR_INVALID_ARG;
if (intr_raw == NULL && intr_st == NULL) {
return ESP_ERR_INVALID_ARG;
}
if (intr_raw != NULL) {
r= essl_sdio_read_bytes(ctx->card, HOST_SLC0HOST_INT_RAW_REG, (uint8_t *) intr_raw, 4);
if (r != ESP_OK) return r;
r = essl_sdio_read_bytes(ctx->card, HOST_SLC0HOST_INT_RAW_REG, (uint8_t *) intr_raw, 4);
if (r != ESP_OK) {
return r;
}
}
if (intr_st != NULL) {
r = essl_sdio_read_bytes(ctx->card, HOST_SLC0HOST_INT_ST_REG, (uint8_t *) intr_st, 4);
if (r != ESP_OK) return r;
if (r != ESP_OK) {
return r;
}
}
return ESP_OK;
}
esp_err_t essl_sdio_set_intr_ena(void *arg, uint32_t ena_mask, uint32_t wait_ms)
{
ESP_LOGV(TAG, "set_intr_ena: %08X", ena_mask);
return essl_sdio_write_bytes(((essl_sdio_context_t*)arg)->card, HOST_SLC0HOST_FUNC1_INT_ENA_REG,
ESP_LOGV(TAG, "set_intr_ena: %08"PRIX32, ena_mask);
return essl_sdio_write_bytes(((essl_sdio_context_t *)arg)->card, HOST_SLC0HOST_FUNC1_INT_ENA_REG,
(uint8_t *) &ena_mask, 4);
}
esp_err_t essl_sdio_get_intr_ena(void *arg, uint32_t *ena_mask_o, uint32_t wait_ms)
{
ESP_LOGV(TAG, "get_intr_ena");
esp_err_t ret = essl_sdio_read_bytes(((essl_sdio_context_t*)arg)->card, HOST_SLC0HOST_FUNC1_INT_ENA_REG,
esp_err_t ret = essl_sdio_read_bytes(((essl_sdio_context_t *)arg)->card, HOST_SLC0HOST_FUNC1_INT_ENA_REG,
(uint8_t *) ena_mask_o, 4);
ESP_LOGV(TAG, "ena: %08X", *ena_mask_o);
ESP_LOGV(TAG, "ena: %08"PRIX32, *ena_mask_o);
return ret;
}
esp_err_t essl_sdio_send_slave_intr(void *arg, uint32_t intr_mask, uint32_t wait_ms)
{
ESP_LOGV(TAG, "send_slave_intr: %02x", intr_mask);
return essl_sdio_write_byte(((essl_sdio_context_t*)arg)->card, HOST_SLCHOST_CONF_W7_REG + 0, intr_mask, NULL);
//Only 8 bits available
ESP_LOGV(TAG, "send_slave_intr: %02"PRIx8, (uint8_t)intr_mask);
return essl_sdio_write_byte(((essl_sdio_context_t *)arg)->card, HOST_SLCHOST_CONF_W7_REG + 0, (uint8_t)intr_mask, NULL);
}
esp_err_t essl_sdio_wait_int(void *arg, uint32_t wait_ms)
{
return sdmmc_io_wait_int(((essl_sdio_context_t*)arg)->card, wait_ms);
return sdmmc_io_wait_int(((essl_sdio_context_t *)arg)->card, wait_ms);
}
void essl_sdio_reset_cnt(void *arg)
{
essl_sdio_context_t* ctx = arg;
essl_sdio_context_t *ctx = arg;
ctx->rx_got_bytes = 0;
ctx->tx_sent_buffers = 0;
}

View File

@@ -9,13 +9,15 @@
#include "esp_log.h"
#include "esp_check.h"
#include "esp_memory_utils.h"
#include "driver/spi_master.h"
#include "esp_private/periph_ctrl.h"
#include "essl_internal.h"
#include "essl_spi.h"
#include "driver/spi_master.h"
#include "hal/spi_types.h"
#include "hal/spi_ll.h"
#include "essl_internal.h"
#include "essl_spi.h"
/**
* Initialise device function list of SPI by this macro.
*/
@@ -107,7 +109,7 @@ esp_err_t essl_spi_rdbuf(spi_device_handle_t spi, uint8_t *out_data, int addr, i
.dummy_bits = get_hd_dummy_bits(flags),
};
return spi_device_transmit(spi, (spi_transaction_t*)&t);
return spi_device_transmit(spi, (spi_transaction_t *)&t);
}
esp_err_t essl_spi_rdbuf_polling(spi_device_handle_t spi, uint8_t *out_data, int addr, int len, uint32_t flags)
@@ -123,7 +125,7 @@ esp_err_t essl_spi_rdbuf_polling(spi_device_handle_t spi, uint8_t *out_data, int
.dummy_bits = get_hd_dummy_bits(flags),
};
return spi_device_polling_transmit(spi, (spi_transaction_t*)&t);
return spi_device_polling_transmit(spi, (spi_transaction_t *)&t);
}
esp_err_t essl_spi_wrbuf(spi_device_handle_t spi, const uint8_t *data, int addr, int len, uint32_t flags)
@@ -138,7 +140,7 @@ esp_err_t essl_spi_wrbuf(spi_device_handle_t spi, const uint8_t *data, int addr,
},
.dummy_bits = get_hd_dummy_bits(flags),
};
return spi_device_transmit(spi, (spi_transaction_t*)&t);
return spi_device_transmit(spi, (spi_transaction_t *)&t);
}
esp_err_t essl_spi_wrbuf_polling(spi_device_handle_t spi, const uint8_t *data, int addr, int len, uint32_t flags)
@@ -153,7 +155,7 @@ esp_err_t essl_spi_wrbuf_polling(spi_device_handle_t spi, const uint8_t *data, i
},
.dummy_bits = get_hd_dummy_bits(flags),
};
return spi_device_polling_transmit(spi, (spi_transaction_t*)&t);
return spi_device_polling_transmit(spi, (spi_transaction_t *)&t);
}
esp_err_t essl_spi_rddma_seg(spi_device_handle_t spi, uint8_t *out_data, int seg_len, uint32_t flags)
@@ -167,7 +169,7 @@ esp_err_t essl_spi_rddma_seg(spi_device_handle_t spi, uint8_t *out_data, int seg
},
.dummy_bits = get_hd_dummy_bits(flags),
};
return spi_device_transmit(spi, (spi_transaction_t*)&t);
return spi_device_transmit(spi, (spi_transaction_t *)&t);
}
esp_err_t essl_spi_rddma_done(spi_device_handle_t spi, uint32_t flags)
@@ -184,15 +186,17 @@ esp_err_t essl_spi_rddma(spi_device_handle_t spi, uint8_t *out_data, int len, in
if (!esp_ptr_dma_capable(out_data) || ((intptr_t)out_data % 4) != 0) {
return ESP_ERR_INVALID_ARG;
}
seg_len = (seg_len > 0)? seg_len : len;
seg_len = (seg_len > 0) ? seg_len : len;
uint8_t* read_ptr = out_data;
uint8_t *read_ptr = out_data;
esp_err_t ret = ESP_OK;
while (len > 0) {
int send_len = MIN(seg_len, len);
ret = essl_spi_rddma_seg(spi, read_ptr, send_len, flags);
if (ret != ESP_OK) return ret;
if (ret != ESP_OK) {
return ret;
}
len -= send_len;
read_ptr += send_len;
@@ -211,7 +215,7 @@ esp_err_t essl_spi_wrdma_seg(spi_device_handle_t spi, const uint8_t *data, int s
},
.dummy_bits = get_hd_dummy_bits(flags),
};
return spi_device_transmit(spi, (spi_transaction_t*)&t);
return spi_device_transmit(spi, (spi_transaction_t *)&t);
}
esp_err_t essl_spi_wrdma_done(spi_device_handle_t spi, uint32_t flags)
@@ -228,13 +232,15 @@ esp_err_t essl_spi_wrdma(spi_device_handle_t spi, const uint8_t *data, int len,
if (!esp_ptr_dma_capable(data)) {
return ESP_ERR_INVALID_ARG;
}
seg_len = (seg_len > 0)? seg_len : len;
seg_len = (seg_len > 0) ? seg_len : len;
while (len > 0) {
int send_len = MIN(seg_len, len);
esp_err_t ret = essl_spi_wrdma_seg(spi, data, send_len, flags);
if (ret != ESP_OK) return ret;
if (ret != ESP_OK) {
return ret;
}
len -= send_len;
data += send_len;
@@ -329,8 +335,8 @@ static uint32_t essl_spi_get_rx_data_size(void *arg)
static esp_err_t essl_spi_update_rx_data_size(void *arg, uint32_t wait_ms)
{
essl_spi_context_t *ctx = arg;
uint32_t updated_size;
uint32_t previous_size;
uint32_t updated_size = 0;
uint32_t previous_size = 0;
esp_err_t ret;
ret = essl_spi_rdbuf_polling(ctx->spi, (uint8_t *)&previous_size, ctx->master_in.rx_sync_reg, sizeof(uint32_t), 0);
@@ -350,7 +356,7 @@ static esp_err_t essl_spi_update_rx_data_size(void *arg, uint32_t wait_ms)
}
if (updated_size == previous_size) {
ctx->master_in.slave_tx_bytes = updated_size;
ESP_LOGV(TAG, "updated: slave prepared tx buffer is: %d bytes", updated_size);
ESP_LOGV(TAG, "updated: slave prepared tx buffer is: %d bytes", (unsigned int)updated_size);
return ret;
}
previous_size = updated_size;
@@ -419,8 +425,8 @@ static uint32_t essl_spi_get_tx_buffer_num(void *arg)
static esp_err_t essl_spi_update_tx_buffer_num(void *arg, uint32_t wait_ms)
{
essl_spi_context_t *ctx = arg;
uint32_t updated_num;
uint32_t previous_size;
uint32_t updated_num = 0;
uint32_t previous_size = 0;
esp_err_t ret;
ret = essl_spi_rdbuf_polling(ctx->spi, (uint8_t *)&previous_size, ctx->master_out.tx_sync_reg, sizeof(uint32_t), 0);
@@ -440,7 +446,7 @@ static esp_err_t essl_spi_update_tx_buffer_num(void *arg, uint32_t wait_ms)
}
if (updated_num == previous_size) {
ctx->master_out.slave_rx_buf_num = updated_num;
ESP_LOGV(TAG, "updated: slave prepared rx buffer: %d", updated_num);
ESP_LOGV(TAG, "updated: slave prepared rx buffer: %d", (unsigned int)updated_num);
return ret;
}
previous_size = updated_num;
@@ -469,12 +475,12 @@ esp_err_t essl_spi_send_packet(void *arg, const void *data, size_t size, uint32_
}
//Slave still did not load a sufficient amount of buffers
if (essl_spi_get_tx_buffer_num(arg) < buf_num_to_use) {
ESP_LOGV(TAG, "slave buffer: %d is not enough, %d is required", ctx->master_out.slave_rx_buf_num, ctx->master_out.sent_buf_num + buf_num_to_use);
ESP_LOGV(TAG, "slave buffer: %"PRIu32" is not enough, %"PRIu32" is required", (uint32_t)ctx->master_out.slave_rx_buf_num, (uint32_t)ctx->master_out.sent_buf_num + buf_num_to_use);
return ESP_ERR_NOT_FOUND;
}
}
ESP_LOGV(TAG, "send_packet: size to write is: %d", size);
ESP_LOGV(TAG, "send_packet: size to write is: %zu", size);
ret = essl_spi_wrdma_seg(ctx->spi, data, size, 0);
if (ret != ESP_OK) {
return ret;

View File

@@ -6,15 +6,16 @@
#pragma once
#include "sdmmc_cmd.h"
#include "driver/spi_master.h"
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
struct essl_dev_t;
/// Handle of an ESSL device
typedef struct essl_dev_t* essl_handle_t;
typedef struct essl_dev_t *essl_handle_t;
/**
* @brief Initialize the slave.
@@ -219,3 +220,7 @@ esp_err_t essl_get_intr_ena(essl_handle_t handle, uint32_t *ena_mask_o, uint32_t
* - One of the error codes from SDMMC host controller
*/
esp_err_t essl_send_slave_intr(essl_handle_t handle, uint32_t intr_mask, uint32_t wait_ms);
#ifdef __cplusplus
}
#endif

View File

@@ -9,10 +9,13 @@
#pragma once
#include "esp_err.h"
#include "driver/sdmmc_host.h"
#include "esp_serial_slave_link/essl.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/sdmmc_defs.h"
#ifdef __cplusplus
extern "C" {
#endif
/// Configuration for the ESSL SDIO device
typedef struct {
@@ -238,3 +241,7 @@ esp_err_t essl_sdio_send_slave_intr(void *arg, uint32_t intr_mask, uint32_t wait
void essl_sdio_reset_cnt(void *arg);
/** @endcond */
#ifdef __cplusplus
}
#endif

View File

@@ -7,12 +7,12 @@
#pragma once
#include "esp_err.h"
#include "driver/spi_master.h"
#include "esp_serial_slave_link/essl.h"
#ifdef __cplusplus
extern "C"
{
extern "C" {
#endif
/// Configuration of ESSL SPI device

View File

@@ -0,0 +1,5 @@
idf_component_register(
SRCS test_spi_utils.c param_test.c
INCLUDE_DIRS include
REQUIRES driver unity
)

View File

@@ -1,8 +1,9 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
/*
* Parameterized Test Framework
*

View File

@@ -7,17 +7,21 @@
#define _TEST_COMMON_SPI_H_
#include <esp_types.h>
#include "driver/spi_master.h"
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/ringbuf.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "freertos/task.h"
#include "unity.h"
#include "test_utils.h"
#include <string.h>
#include "param_test.h"
#include "soc/io_mux_reg.h"
#include "sdkconfig.h"
#include "soc/spi_periph.h"
#include "driver/spi_master.h"
// All the tests using the header should use this definition as much as possible,
// so that the working host can be changed easily in the future.
@@ -249,7 +253,7 @@ typedef struct {
void spitest_def_param(void* arg);
// functions for slave task
esp_err_t init_slave_context(spi_slave_task_context_t *context);
esp_err_t init_slave_context(spi_slave_task_context_t *context, spi_host_device_t host);
void deinit_slave_context(spi_slave_task_context_t *context);
void spitest_slave_task(void* arg);

View File

@@ -1,12 +1,12 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stddef.h>
#include <stdlib.h>
#include "param_test.h"
#include "esp_log.h"
#include "unity.h"
#include "param_test.h"
void test_serializer(const param_group_t *param_group, const ptest_func_t* test_func)
{

View File

@@ -3,7 +3,7 @@
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "test/test_common_spi.h"
#include "test_spi_utils.h"
#include "driver/spi_slave.h"
#include "esp_log.h"
#include "driver/gpio.h"
@@ -44,7 +44,7 @@ void spitest_def_param(void* arg)
/**********************************************************************************
* functions for slave task
*********************************************************************************/
esp_err_t init_slave_context(spi_slave_task_context_t *context)
esp_err_t init_slave_context(spi_slave_task_context_t *context, spi_host_device_t host)
{
context->data_to_send = xQueueCreate( 16, sizeof( slave_txdata_t ));
if ( context->data_to_send == NULL ) {
@@ -54,7 +54,7 @@ esp_err_t init_slave_context(spi_slave_task_context_t *context)
if ( context->data_received == NULL ) {
return ESP_ERR_NO_MEM;
}
context->spi=TEST_SLAVE_HOST;
context->spi=host;
return ESP_OK;
}
@@ -96,7 +96,7 @@ void spitest_slave_task(void* arg)
} while ( t.trans_len <= 2 );
memcpy(recvbuf, &t.trans_len, sizeof(uint32_t));
*(uint8_t**)(recvbuf+4) = (uint8_t*)txdata.start;
ESP_LOGD( SLAVE_TAG, "received: %d", t.trans_len );
ESP_LOGD( SLAVE_TAG, "received: %" PRIu32, (uint32_t)t.trans_len );
xRingbufferSend( ringbuf, recvbuf, 8+(t.trans_len+7)/8, portMAX_DELAY );
}
}
@@ -163,7 +163,7 @@ void spitest_master_print_data(spi_transaction_t *t, int rxlength)
void spitest_slave_print_data(slave_rxdata_t *t, bool print_rxdata)
{
int rcv_len = (t->len+7)/8;
ESP_LOGI(SLAVE_TAG, "trans_len: %d", t->len);
ESP_LOGI(SLAVE_TAG, "trans_len: %" PRIu32, t->len);
ESP_LOG_BUFFER_HEX("slave tx", t->tx_start, rcv_len);
if (print_rxdata) ESP_LOG_BUFFER_HEX("slave rx", t->data, rcv_len);
}
@@ -188,7 +188,7 @@ esp_err_t spitest_check_data(int len, spi_transaction_t *master_t, slave_rxdata_
ret = ESP_FAIL;
}
if (ret != ESP_OK) {
ESP_LOGI(SLAVE_TAG, "slave_recv_len: %d", rcv_len);
ESP_LOGI(SLAVE_TAG, "slave_recv_len: %" PRIu32, rcv_len);
spitest_master_print_data(master_t, len);
spitest_slave_print_data(slave_t, true);
//already failed, try to use the TEST_ASSERT to output the reason...
@@ -250,4 +250,5 @@ void get_tx_buffer(uint32_t seed, uint8_t *master_send_buf, uint8_t *slave_send_
master_send_buf[i] = rand() % 256;
}
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6)

View File

@@ -0,0 +1,10 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS
"$ENV{IDF_PATH}/tools/unit-test-app/components"
"$ENV{IDF_PATH}/components/driver/test_apps/components"
)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(spi_master_test)

View File

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

View File

@@ -0,0 +1,16 @@
set(srcs
"test_app_main.c"
"test_spi_master.c"
"test_spi_sio.c"
"test_spi_bus_lock.c"
)
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(
SRCS ${srcs}
PRIV_REQUIRES test_utils driver test_driver_utils spi_flash
WHOLE_ARCHIVE
)

View File

@@ -0,0 +1,49 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "unity.h"
#include "unity_test_utils.h"
#include "esp_heap_caps.h"
// iterator to load partition tables in `test spi bus lock, with flash` will lead memory not free
#define TEST_MEMORY_LEAK_THRESHOLD (250)
static size_t before_free_8bit;
static size_t before_free_32bit;
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
void tearDown(void)
{
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
printf("\n");
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
}
void app_main(void)
{
// ____ ____ ___ __ __ _
// / ___|| _ \_ _| | \/ | __ _ ___| |_ ___ _ __
// \___ \| |_) | | | |\/| |/ _` / __| __/ _ \ '__|
// ___) | __/| | | | | | (_| \__ \ || __/ |
// |____/|_| |___| |_| |_|\__,_|___/\__\___|_|
printf("\n");
printf(" ____ ____ ___ __ __ _ \n");
printf(" / ___|| _ \\_ _| | \\/ | __ _ ___| |_ ___ _ __ \n");
printf(" \\___ \\| |_) | | | |\\/| |/ _` / __| __/ _ \\ '__|\n");
printf(" ___) | __/| | | | | | (_| \\__ \\ || __/ | \n");
printf(" |____/|_| |___| |_| |_|\\__,_|___/\\__\\___|_| \n");
unity_run_menu();
}

View File

@@ -8,9 +8,9 @@
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "esp_flash_spi_init.h"
#include "test_utils.h"
#include "test_spi_utils.h"
#include "spi_flash_mmap.h"
#include "test/test_common_spi.h"
#include "unity.h"
@@ -283,14 +283,13 @@ static void test_bus_lock(bool test_flash)
TEST_ESP_OK(spi_bus_free(TEST_SPI_HOST) );
}
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32C3, ESP32S3, ESP32C2)
//no runners
//IDF-5049
TEST_CASE("spi bus lock, with flash","[spi][test_env=UT_T1_ESP_FLASH]")
#if CONFIG_IDF_TARGET_ESP32
// no need this case in other target, only esp32 need buslock to split MSPI and GPSPI2 action
TEST_CASE("spi bus lock, with flash","[spi][test_env=external_flash]")
{
test_bus_lock(true);
}
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(...)
#endif //CONFIG_IDF_TARGET_ESP32
TEST_CASE("spi bus lock","[spi]")

View File

@@ -7,21 +7,13 @@
Tests for the spi_master device driver
*/
#include <esp_types.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "unity.h"
#include "sdkconfig.h"
#include "driver/spi_master.h"
#include "driver/spi_slave.h"
#include "driver/gpio.h"
#include "soc/gpio_periph.h"
#include "soc/spi_periph.h"
#include "soc/soc_memory_layout.h"
#include "esp_private/cache_utils.h"
#include "esp_private/spi_common_internal.h"
@@ -29,7 +21,7 @@
#include "esp_heap_caps.h"
#include "esp_log.h"
#include "test_utils.h"
#include "test/test_common_spi.h"
#include "test_spi_utils.h"
#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6)
@@ -913,7 +905,7 @@ void test_cmd_addr(spi_slave_task_context_t *slave_context, bool lsb_first)
addr_got = addr_got >> (64 - addr_bits);
}
ESP_LOGI(SLAVE_TAG, "cmd_got: %04X, addr_got: %08X%08X", cmd_got, (uint32_t)(addr_got >> 32), (uint32_t)addr_got);
ESP_LOGI(SLAVE_TAG, "cmd_got: %" PRIX16 ", addr_got: %" PRIX32 "%" PRIX32, cmd_got, (uint32_t)(addr_got >> 32), (uint32_t)addr_got);
TEST_ASSERT_EQUAL_HEX16(cmd_expected, cmd_got);
if (addr_bits > 0) {
@@ -932,7 +924,7 @@ void test_cmd_addr(spi_slave_task_context_t *slave_context, bool lsb_first)
TEST_CASE("SPI master variable cmd & addr test", "[spi]")
{
spi_slave_task_context_t slave_context = {};
esp_err_t err = init_slave_context( &slave_context );
esp_err_t err = init_slave_context( &slave_context, TEST_SLAVE_HOST );
TEST_ASSERT( err == ESP_OK );
TaskHandle_t handle_slave;
xTaskCreate( spitest_slave_task, "spi_slave", 4096, &slave_context, 0, &handle_slave);
@@ -1301,7 +1293,7 @@ static void fd_slave(void)
TEST_ASSERT(spi_slave_free(SPI2_HOST) == ESP_OK);
}
TEST_CASE_MULTIPLE_DEVICES("SPI Master: FD, DMA, Master Single Direction Test", "[spi_ms][test_env=Example_SPI_Multi_device]", fd_master, fd_slave);
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
#endif //#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) //TODO: IDF-3494
@@ -1416,7 +1408,6 @@ TEST_CASE("spi_speed", "[spi]")
//release the bus
spi_device_release_bus(spi);
master_free_device_bus(spi);
speed_setup(&spi, !use_dma);
@@ -1437,6 +1428,7 @@ TEST_CASE("spi_speed", "[spi]")
//acquire the bus to send polling transactions faster
ret = spi_device_acquire_bus(spi, portMAX_DELAY);
TEST_ESP_OK(ret);
//record flight time by polling, without DMA
t_flight_num = 0;
for (int i = 0; i < TEST_TIMES; i++) {
@@ -1541,13 +1533,6 @@ void test_add_device_slave(void)
.spics_io_num = CS_REAL_DEV,
.queue_size = 3,
};
#if CONFIG_IDF_TARGET_ESP32
//now esp32 runners use SPI3 pin group to test gpio matrix together on CI.
bus_cfg.miso_io_num = SPI3_IOMUX_PIN_NUM_MISO;
bus_cfg.mosi_io_num = SPI3_IOMUX_PIN_NUM_MOSI;
bus_cfg.sclk_io_num = SPI3_IOMUX_PIN_NUM_CLK;
slvcfg.spics_io_num = SPI3_IOMUX_PIN_NUM_CS;
#endif
TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &bus_cfg, &slvcfg, SPI_DMA_CH_AUTO));
spi_slave_transaction_t slave_trans = {};
@@ -1573,5 +1558,5 @@ void test_add_device_slave(void)
spi_bus_free(TEST_SPI_HOST);
}
TEST_CASE_MULTIPLE_DEVICES("SPI_Master:Test multiple devices", "[spi_ms][test_env=Example_SPI_Multi_device]", test_add_device_master, test_add_device_slave);
TEST_CASE_MULTIPLE_DEVICES("SPI_Master:Test multiple devices", "[spi_ms][test_env=generic_multi_device]", test_add_device_master, test_add_device_slave);
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6)

View File

@@ -24,7 +24,7 @@
#include "esp_log.h"
#include "soc/spi_periph.h"
#include "test_utils.h"
#include "test/test_common_spi.h"
#include "test_spi_utils.h"
#include "soc/gpio_periph.h"
#include "hal/spi_ll.h"
@@ -269,14 +269,6 @@ void test_sio_slave_emulate(bool sio_master_in)
spi_bus_config_t bus_cfg = SPI_BUS_TEST_DEFAULT_CONFIG();
spi_slave_interface_config_t slv_cfg = SPI_SLAVE_TEST_DEFAULT_CONFIG();
#if CONFIG_IDF_TARGET_ESP32
// esp32 use different pin for slave in current runner
bus_cfg.mosi_io_num = spi_periph_signal[TEST_SLAVE_HOST].spid_iomux_pin;
bus_cfg.miso_io_num = spi_periph_signal[TEST_SLAVE_HOST].spiq_iomux_pin;
bus_cfg.sclk_io_num = spi_periph_signal[TEST_SLAVE_HOST].spiclk_iomux_pin;
slv_cfg.spics_io_num = spi_periph_signal[TEST_SLAVE_HOST].spics0_iomux_pin;
#endif
TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &bus_cfg, &slv_cfg, SPI_DMA_CH_AUTO));
printf("CS:CLK:MO:MI: %d\t%d\t%d\t%d\n", slv_cfg.spics_io_num, bus_cfg.sclk_io_num, bus_cfg.mosi_io_num, bus_cfg.miso_io_num);
@@ -334,5 +326,5 @@ void test_slave_run(void)
test_sio_slave_emulate(true);
}
TEST_CASE_MULTIPLE_DEVICES("SPI_Master:Test_SIO_Mode_Multi_Board", "[spi_ms][test_env=Example_SPI_Multi_device]", test_master_run, test_slave_run);
TEST_CASE_MULTIPLE_DEVICES("SPI_Master:Test_SIO_Mode_Multi_Board", "[spi_ms][test_env=generic_multi_device]", test_master_run, test_slave_run);
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6)

View File

@@ -0,0 +1,8 @@
# Special partition table for unit test app
#
# Name, Type, SubType, Offset, Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
factory, 0, 0, 0x20000, 0x260000
# flash_test partition used for SPI flash tests, WL FAT tests, and SPIFFS tests
flash_test, data, fat, , 528K
1 # Special partition table for unit test app
2 #
3 # Name, Type, SubType, Offset, Size, Flags
4 # Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
5 factory, 0, 0, 0x20000, 0x260000
6 # flash_test partition used for SPI flash tests, WL FAT tests, and SPIFFS tests
7 flash_test, data, fat, , 528K

View File

@@ -0,0 +1,34 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.supported_targets
@pytest.mark.generic
def test_master_single_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
if 'test_env' in case.attributes:
continue
case_tester.run_normal_case(case=case, reset=True)
# Job for test_env `external_flash` just for esp32 only
@pytest.mark.esp32
@pytest.mark.flash_mutli
def test_master_esp_flash(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
# test case `spi_bus_lock_with_flash` use difference test env
if case.attributes.get('test_env') == 'external_flash':
case_tester.run_normal_case(case=case, reset=True)
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.supported_targets
@pytest.mark.generic_multi_device
@pytest.mark.parametrize('count', [2,], indirect=True)
def test_master_multi_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device':
case_tester.run_multi_dev_case(case=case, reset=True)

View File

@@ -0,0 +1,2 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n

View File

@@ -0,0 +1,8 @@
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
CONFIG_XTAL_FREQ_AUTO=y
CONFIG_SPI_FLASH_SHARE_SPI1_BUS=y
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partition_table_esp32_flash.csv"
CONFIG_PARTITION_TABLE_FILENAME="partition_table_esp32_flash.csv"
CONFIG_PARTITION_TABLE_OFFSET=0x8000

View File

@@ -0,0 +1,2 @@
# test_case `spi_speed` need freq 240M
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y

View File

@@ -0,0 +1,2 @@
# test_case `spi_speed` need freq 240M
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y

View File

@@ -0,0 +1,10 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS
"$ENV{IDF_PATH}/tools/unit-test-app/components"
"$ENV{IDF_PATH}/components/driver/test_apps/components"
)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(spi_param_test)

View File

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

View File

@@ -0,0 +1,14 @@
set(srcs
"test_app_main.c"
"test_spi_param.c"
)
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(
SRCS ${srcs}
PRIV_REQUIRES test_utils driver test_driver_utils
WHOLE_ARCHIVE
)

View File

@@ -0,0 +1,48 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "unity.h"
#include "unity_test_utils.h"
#include "esp_heap_caps.h"
#define TEST_MEMORY_LEAK_THRESHOLD (150)
static size_t before_free_8bit;
static size_t before_free_32bit;
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
void tearDown(void)
{
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
printf("\n");
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
}
void app_main(void)
{
// ____ ____ ___ ____
// / ___|| _ \_ _| | _ \ __ _ _ __ __ _ _ __ ___
// \___ \| |_) | | | |_) / _` | '__/ _` | '_ ` _ `.
// ___) | __/| | | __/ (_| | | | (_| | | | | | |
// |____/|_| |___| |_| \__,_|_| \__,_|_| |_| |_|
printf("\n");
printf(" ____ ____ ___ ____ \n");
printf(" / ___|| _ \\_ _| | _ \\ __ _ _ __ __ _ _ __ ___ \n");
printf(" \\___ \\| |_) | | | |_) / _` | '__/ _` | '_ ` _ \\ \n");
printf(" ___) | __/| | | __/ (_| | | | (_| | | | | | |\n");
printf(" |____/|_| |___| |_| \\__,_|_| \\__,_|_| |_| |_|\n");
unity_run_menu();
}

View File

@@ -7,7 +7,8 @@
#include "esp_attr.h"
#include "soc/spi_periph.h"
#include "sdkconfig.h"
#include "test/test_common_spi.h"
#include "test_utils.h"
#include "test_spi_utils.h"
#include "driver/spi_master.h"
#include "driver/spi_slave.h"
@@ -44,7 +45,7 @@ static void local_test_init(void** arg)
spitest_context_t* context = (spitest_context_t*)*arg;
TEST_ASSERT(context!=NULL);
context->slave_context = (spi_slave_task_context_t){};
esp_err_t err = init_slave_context( &context->slave_context);
esp_err_t err = init_slave_context( &context->slave_context, TEST_SLAVE_HOST);
TEST_ASSERT(err == ESP_OK);
xTaskCreate(spitest_slave_task, "spi_slave", 4096, &context->slave_context, 0, &context->handle_slave);
@@ -211,7 +212,7 @@ static void local_test_loop(const void* arg1, void* arg2)
}
if (failed) {
ESP_LOGI(SLAVE_TAG, "slave_recv_len: %d", rcv_len);
ESP_LOGI(SLAVE_TAG, "slave_recv_len: %" PRIu32, rcv_len);
spitest_master_print_data(t, len);
ESP_LOG_BUFFER_HEX("slave tx", slave_trans.tx_buffer, len);
@@ -659,9 +660,12 @@ static const ptest_func_t slave_test_func = {
.def_param = spitest_def_param,
};
//temporarily close mass data print to avoid pytest run too busy to timeout
#define TEST_LOG_DBUG false
#define TEST_SPI_MASTER_SLAVE(name, param_group, extra_tag) \
PARAM_GROUP_DECLARE(name, param_group) \
TEST_MASTER_SLAVE(name, param_group, "[spi_ms][test_env=Example_SPI_Multi_device][timeout=120]"extra_tag, &master_test_func, &slave_test_func)
TEST_MASTER_SLAVE(name, param_group, "[spi_ms][test_env=generic_multi_device][timeout=120]"extra_tag, &master_test_func, &slave_test_func)
/************ Master Code ***********************************************/
static void test_master_init(void** arg)
@@ -671,8 +675,9 @@ static void test_master_init(void** arg)
spitest_context_t* context = *arg;
TEST_ASSERT(context!=NULL);
context->slave_context = (spi_slave_task_context_t){};
esp_err_t err = init_slave_context(&context->slave_context);
esp_err_t err = init_slave_context(&context->slave_context, TEST_SPI_HOST);
TEST_ASSERT(err == ESP_OK);
unity_send_signal("Master ready");
}
static void test_master_deinit(void* arg)
@@ -685,13 +690,10 @@ static void test_master_start(spi_device_handle_t *spi, int freq, const spitest_
{
//master config
spi_bus_config_t buspset=SPI_BUS_TEST_DEFAULT_CONFIG();
buspset.miso_io_num = MASTER_IOMUX_PIN_MISO;
buspset.mosi_io_num = MASTER_IOMUX_PIN_MOSI;
buspset.sclk_io_num = MASTER_IOMUX_PIN_SCLK;
//this does nothing, but avoid the driver from using native pins
if (!pset->master_iomux) buspset.quadhd_io_num = UNCONNECTED_PIN;
spi_device_interface_config_t devpset=SPI_DEVICE_TEST_DEFAULT_CONFIG();
devpset.spics_io_num = MASTER_IOMUX_PIN_CS;
devpset.spics_io_num = SPI2_IOMUX_PIN_NUM_CS;
devpset.mode = pset->mode;
const int cs_pretrans_max = 15;
if (pset->dup==HALF_DUPLEX_MISO) {
@@ -757,7 +759,7 @@ static void test_master_loop(const void *arg1, void* arg2)
ESP_LOGI(MASTER_TAG, "==============> %dk", freq/1000);
test_master_start(&spi, freq, test_cfg, context);
unity_wait_for_signal("slave ready");
unity_wait_for_signal("Slave ready");
for( int j= 0; j < test_cfg->test_size; j ++ ) {
//wait for both master and slave end
@@ -768,11 +770,15 @@ static void test_master_loop(const void *arg1, void* arg2)
spi_transaction_t *t = &context->master_trans[j];
TEST_ESP_OK (spi_device_transmit(spi, t) );
int len = get_trans_len(test_cfg->dup, t);
spitest_master_print_data(t, len);
if(TEST_LOG_DBUG){
spitest_master_print_data(t, len);
}
size_t rcv_len;
slave_rxdata_t *rcv_data = xRingbufferReceive( context->slave_context.data_received, &rcv_len, portMAX_DELAY );
spitest_slave_print_data(rcv_data, false);
if(TEST_LOG_DBUG){
spitest_slave_print_data(rcv_data, false);
}
//check result
bool check_master_data = (test_cfg->dup != HALF_DUPLEX_MOSI &&
@@ -800,9 +806,10 @@ static void test_slave_init(void** arg)
spitest_context_t* context = (spitest_context_t*)*arg;
TEST_ASSERT(context!=NULL);
context->slave_context = (spi_slave_task_context_t){};
esp_err_t err = init_slave_context( &context->slave_context );
esp_err_t err = init_slave_context( &context->slave_context, TEST_SPI_HOST);
TEST_ASSERT( err == ESP_OK );
unity_wait_for_signal("Master ready");
xTaskCreate( spitest_slave_task, "spi_slave", 4096, &context->slave_context, 0, &context->handle_slave);
}
@@ -819,19 +826,16 @@ static void timing_slave_start(int speed, const spitest_param_set_t* pset, spite
{
//slave config
spi_bus_config_t slv_buscfg=SPI_BUS_TEST_DEFAULT_CONFIG();
slv_buscfg.miso_io_num = SLAVE_IOMUX_PIN_MISO;
slv_buscfg.mosi_io_num = SLAVE_IOMUX_PIN_MOSI;
slv_buscfg.sclk_io_num = SLAVE_IOMUX_PIN_SCLK;
//this does nothing, but avoid the driver from using native pins
if (!pset->slave_iomux) slv_buscfg.quadhd_io_num = UNCONNECTED_PIN;
spi_slave_interface_config_t slvcfg=SPI_SLAVE_TEST_DEFAULT_CONFIG();
slvcfg.spics_io_num = SLAVE_IOMUX_PIN_CS;
slvcfg.spics_io_num = SPI2_IOMUX_PIN_NUM_CS;
slvcfg.mode = pset->mode;
//Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected.
slave_pull_up(&slv_buscfg, slvcfg.spics_io_num);
int slave_dma_chan = (pset->slave_dma_chan == 0) ? 0 : SPI_DMA_CH_AUTO;
TEST_ESP_OK(spi_slave_initialize(TEST_SLAVE_HOST, &slv_buscfg, &slvcfg, slave_dma_chan));
TEST_ESP_OK(spi_slave_initialize(TEST_SPI_HOST, &slv_buscfg, &slvcfg, slave_dma_chan));
//prepare data for the master
for (int i = 0; i < pset->test_size; i++) {
@@ -867,7 +871,7 @@ static void test_slave_loop(const void *arg1, void* arg2)
}
vTaskDelay(50/portTICK_PERIOD_MS);
unity_send_signal("slave ready");
unity_send_signal("Slave ready");
for( int i= 0; i < pset->test_size; i ++ ) {
//wait for both master and slave end
@@ -877,11 +881,15 @@ static void test_slave_loop(const void *arg1, void* arg2)
spi_transaction_t *t = &context->master_trans[i];
int len = get_trans_len(pset->dup, t);
spitest_master_print_data(t, FULL_DUPLEX);
if(TEST_LOG_DBUG){
spitest_master_print_data(t, FULL_DUPLEX);
}
size_t rcv_len;
slave_rxdata_t *rcv_data = xRingbufferReceive( context->slave_context.data_received, &rcv_len, portMAX_DELAY );
spitest_slave_print_data(rcv_data, true);
if(TEST_LOG_DBUG){
spitest_slave_print_data(rcv_data, true);
}
//check result
const bool check_master_data = false;
@@ -891,7 +899,7 @@ static void test_slave_loop(const void *arg1, void* arg2)
//clean
vRingbufferReturnItem( context->slave_context.data_received, rcv_data );
}
TEST_ASSERT(spi_slave_free(TEST_SLAVE_HOST) == ESP_OK);
TEST_ASSERT(spi_slave_free(TEST_SPI_HOST) == ESP_OK);
}
}

View File

@@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.supported_targets
@pytest.mark.generic
def test_param_single_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
if 'test_env' in case.attributes:
continue
case_tester.run_normal_case(case=case, reset=True)
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.supported_targets
@pytest.mark.generic_multi_device
@pytest.mark.parametrize('count', [2,], indirect=True)
def test_param_multi_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device':
case_tester.run_multi_dev_case(case=case, reset=True)

View File

@@ -0,0 +1,2 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n

View File

@@ -0,0 +1,10 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS
"$ENV{IDF_PATH}/tools/unit-test-app/components"
"$ENV{IDF_PATH}/components/driver/test_apps/components"
)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(spi_slave_test)

View File

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

View File

@@ -0,0 +1,14 @@
set(srcs
"test_app_main.c"
"test_spi_slave.c"
)
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(
SRCS ${srcs}
PRIV_REQUIRES test_utils driver test_driver_utils
WHOLE_ARCHIVE
)

View File

@@ -0,0 +1,48 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "unity.h"
#include "unity_test_utils.h"
#include "esp_heap_caps.h"
#define TEST_MEMORY_LEAK_THRESHOLD (100)
static size_t before_free_8bit;
static size_t before_free_32bit;
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
void tearDown(void)
{
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
printf("\n");
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
}
void app_main(void)
{
// ____ ____ ___ ____ _
// / ___|| _ \_ _| / ___|| | __ ___ _____
// \___ \| |_) | | \___ \| |/ _` \ \ / / _ `
// ___) | __/| | ___) | | (_| |\ V / __/
// |____/|_| |___| |____/|_|\__,_| \_/ \___|
printf("\n");
printf(" ____ ____ ___ ____ _ \n");
printf(" / ___|| _ \\_ _| / ___|| | __ ___ _____ \n");
printf(" \\___ \\| |_) | | \\___ \\| |/ _` \\ \\ / / _ \\\n");
printf(" ___) | __/| | ___) | | (_| |\\ V / __/\n");
printf(" |____/|_| |___| |____/|_|\\__,_| \\_/ \\___|\n");
unity_run_menu();
}

View File

@@ -10,7 +10,8 @@
#include <string.h>
#include "sdkconfig.h"
#include "unity.h"
#include "test/test_common_spi.h"
#include "test_utils.h"
#include "test_spi_utils.h"
#include "driver/spi_master.h"
#include "driver/spi_slave.h"
#include "driver/gpio.h"
@@ -382,7 +383,7 @@ static void unaligned_test_slave(void)
TEST_ASSERT(spi_slave_free(TEST_SPI_HOST) == ESP_OK);
}
TEST_CASE_MULTIPLE_DEVICES("SPI_Slave_Unaligned_Test", "[spi_ms][test_env=Example_SPI_Multi_device][timeout=120]", unaligned_test_master, unaligned_test_slave);
TEST_CASE_MULTIPLE_DEVICES("SPI_Slave_Unaligned_Test", "[spi_ms][test_env=generic_multi_device][timeout=120]", unaligned_test_master, unaligned_test_slave);
#endif //#if (TEST_SPI_PERIPH_NUM == 1)
#endif //!TEMPORARY_DISABLED_FOR_TARGETS(...)

View File

@@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.supported_targets
@pytest.mark.generic
def test_slave_single_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
if 'test_env' in case.attributes:
continue
case_tester.run_normal_case(case=case, reset=True)
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.supported_targets
@pytest.mark.generic_multi_device
@pytest.mark.parametrize('count', [2,], indirect=True)
def test_slave_multi_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device':
case_tester.run_multi_dev_case(case=case, reset=True)

View File

@@ -0,0 +1,2 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n

View File

@@ -0,0 +1,10 @@
# This is the project CMakeLists.txt file for the test subproject
cmake_minimum_required(VERSION 3.16)
set(EXTRA_COMPONENT_DIRS
"$ENV{IDF_PATH}/tools/unit-test-app/components"
"$ENV{IDF_PATH}/components/driver/test_apps/components"
)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(spi_slave_hd_test)

View File

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

View File

@@ -0,0 +1,14 @@
set(srcs
"test_app_main.c"
"test_spi_slave_hd.c"
)
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
# the component can be registered as WHOLE_ARCHIVE
idf_component_register(
SRCS ${srcs}
PRIV_REQUIRES test_utils driver test_driver_utils esp_serial_slave_link sdmmc
WHOLE_ARCHIVE
)

View File

@@ -0,0 +1,48 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "unity.h"
#include "unity_test_utils.h"
#include "esp_heap_caps.h"
#define TEST_MEMORY_LEAK_THRESHOLD (200)
static size_t before_free_8bit;
static size_t before_free_32bit;
void setUp(void)
{
before_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
before_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
}
void tearDown(void)
{
esp_reent_cleanup(); //clean up some of the newlib's lazy allocations
size_t after_free_8bit = heap_caps_get_free_size(MALLOC_CAP_8BIT);
size_t after_free_32bit = heap_caps_get_free_size(MALLOC_CAP_32BIT);
printf("\n");
unity_utils_check_leak(before_free_8bit, after_free_8bit, "8BIT", TEST_MEMORY_LEAK_THRESHOLD);
unity_utils_check_leak(before_free_32bit, after_free_32bit, "32BIT", TEST_MEMORY_LEAK_THRESHOLD);
}
void app_main(void)
{
// ____ ____ ___ ____ _ _ _ ____
// / ___|| _ \_ _| / ___|| | __ ___ _____ | | | | _ `.
// \___ \| |_) | | \___ \| |/ _` \ \ / / _ \ | |_| | | | |
// ___) | __/| | ___) | | (_| |\ V / __/ | _ | |_| |
// |____/|_| |___| |____/|_|\__,_| \_/ \___| |_| |_|____/
printf("\n");
printf(" ____ ____ ___ ____ _ _ _ ____ \n");
printf(" / ___|| _ \\_ _| / ___|| | __ ___ _____ | | | | _ \\ \n");
printf(" \\___ \\| |_) | | \\___ \\| |/ _` \\ \\ / / _ \\ | |_| | | | |\n");
printf(" ___) | __/| | ___) | | (_| |\\ V / __/ | _ | |_| |\n");
printf(" |____/|_| |___| |____/|_|\\__,_| \\_/ \\___| |_| |_|____/ \n");
unity_run_menu();
}

View File

@@ -8,15 +8,10 @@
*/
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "unity.h"
#include "test_utils.h"
#include "test_spi_utils.h"
#include "soc/spi_periph.h"
#include "driver/spi_master.h"
#include "esp_serial_slave_link/essl_spi.h"
#include "test/test_common_spi.h"
#if SOC_SPI_SUPPORT_SLAVE_HD_VER2
#include "driver/spi_slave_hd.h"
@@ -631,11 +626,12 @@ static void hd_master(void)
WORD_ALIGNED_ATTR uint8_t *master_recv_buf = calloc(1, send_buf_size * 2);
//This buffer is used for 2-board test and should be assigned totally the same as the ``hd_slave`` does.
WORD_ALIGNED_ATTR uint8_t *slave_send_buf = malloc(send_buf_size * 2);
get_tx_buffer(199, master_send_buf, slave_send_buf, send_buf_size);
get_tx_buffer(199, master_send_buf, slave_send_buf, send_buf_size * 2);
//This is the same as the ``hd_slave`` sets.
int trans_len[] = {5, send_buf_size};
unity_send_signal("master ready");
unity_wait_for_signal("slave ready");
essl_spi_wrdma(spi, master_send_buf, send_buf_size, -1, 0);
@@ -676,13 +672,14 @@ static void hd_slave(void)
};
TEST_ESP_OK(spi_slave_hd_init(TEST_SLAVE_HOST, &bus_cfg, &slave_hd_cfg));
unity_wait_for_signal("master ready");
const int send_buf_size = 1024;
WORD_ALIGNED_ATTR uint8_t *slave_send_buf = malloc(send_buf_size * 2);
WORD_ALIGNED_ATTR uint8_t *slave_recv_buf = calloc(1, send_buf_size * 2);
//This buffer is used for 2-board test and should be assigned totally the same as the ``hd_master`` does.
WORD_ALIGNED_ATTR uint8_t *master_send_buf = malloc(send_buf_size * 2);
get_tx_buffer(199, master_send_buf, slave_send_buf, send_buf_size);
get_tx_buffer(199, master_send_buf, slave_send_buf, send_buf_size * 2);
//make the first transaction shorter than the actual trans length of the master, so that the second one will be loaded while the master is still doing the first transaction.
int trans_len[] = {5, send_buf_size};
@@ -739,7 +736,7 @@ static void hd_slave(void)
spi_slave_hd_deinit(TEST_SLAVE_HOST);
}
TEST_CASE_MULTIPLE_DEVICES("SPI Slave HD: segment mode, master sends too long", "[spi_ms][test_env=Example_SPI_Multi_device]", hd_master, hd_slave);
TEST_CASE_MULTIPLE_DEVICES("SPI Slave HD: segment mode, master sends too long", "[spi_ms][test_env=generic_multi_device]", hd_master, hd_slave);
#endif //#if (TEST_SPI_PERIPH_NUM == 1)
/**
@@ -776,6 +773,7 @@ static void hd_master_quad(void){
WORD_ALIGNED_ATTR uint8_t *slave_send_buf = heap_caps_malloc(BUF_SIZE, MALLOC_CAP_DMA);
get_tx_buffer(199, master_send_buf, slave_send_buf, BUF_SIZE);
unity_send_signal("Master ready");
unity_wait_for_signal("slave ready");
essl_spi_wrdma(spi, master_send_buf, BUF_SIZE / 2, -1, SPI_TRANS_MODE_QIO);
@@ -851,6 +849,7 @@ static void hd_slave_quad(void){
},
};
unity_wait_for_signal("Master ready");
for (int i = 0; i < 2; i ++) {
TEST_ESP_OK(spi_slave_hd_queue_trans(TEST_SLAVE_HOST, SPI_SLAVE_CHAN_RX, &slave_trans[i], portMAX_DELAY));
unity_send_signal("slave ready");
@@ -880,7 +879,7 @@ static void hd_slave_quad(void){
spi_slave_hd_deinit(TEST_SLAVE_HOST);
}
TEST_CASE_MULTIPLE_DEVICES("SPI quad hd test ", "[spi_ms][test_env=Example_SPI_Quad_Multi_device]", hd_master_quad, hd_slave_quad);
TEST_CASE_MULTIPLE_DEVICES("SPI quad hd test ", "[spi_ms][test_env=generic_multi_device]", hd_master_quad, hd_slave_quad);
#endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2)

View File

@@ -0,0 +1,24 @@
# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: Apache-2.0
import pytest
# If `test_env` is define, should not run on generic runner
@pytest.mark.supported_targets
@pytest.mark.generic
def test_slave_hd_single_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
if 'test_env' in case.attributes:
continue
case_tester.run_normal_case(case=case, reset=True)
# if `test_env` not defined, will run on `generic_multi_device` by default
@pytest.mark.supported_targets
@pytest.mark.generic_multi_device
@pytest.mark.parametrize('count', [2,], indirect=True)
def test_slave_hd_multi_dev(case_tester) -> None: # type: ignore
for case in case_tester.test_menu:
if case.attributes.get('test_env', 'generic_multi_device') == 'generic_multi_device':
case_tester.run_multi_dev_case(case=case, reset=True)

View File

@@ -0,0 +1,2 @@
CONFIG_FREERTOS_HZ=1000
CONFIG_ESP_TASK_WDT=n

View File

@@ -103,9 +103,9 @@ INPUT = \
$(PROJECT_PATH)/components/driver/include/driver/touch_sensor_common.h \
$(PROJECT_PATH)/components/driver/include/driver/twai.h \
$(PROJECT_PATH)/components/driver/include/driver/uart.h \
$(PROJECT_PATH)/components/driver/test/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h \
$(PROJECT_PATH)/components/driver/test/esp_serial_slave_link/include/esp_serial_slave_link/essl_spi.h \
$(PROJECT_PATH)/components/driver/test/esp_serial_slave_link/include/esp_serial_slave_link/essl.h \
$(PROJECT_PATH)/components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_sdio.h \
$(PROJECT_PATH)/components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl_spi.h \
$(PROJECT_PATH)/components/driver/test_apps/components/esp_serial_slave_link/include/esp_serial_slave_link/essl.h \
$(PROJECT_PATH)/components/efuse/$(IDF_TARGET)/include/esp_efuse_chip.h \
$(PROJECT_PATH)/components/efuse/include/esp_efuse.h \
$(PROJECT_PATH)/components/esp_adc/include/esp_adc/adc_cali_scheme.h \

View File

@@ -95,7 +95,7 @@ class NormalCaseTester(BaseTester):
for retry in range(self.retry_times):
self.dut.write(str(case.index))
try:
self.dut.expect('Running {}...'.format(case.name), timeout=1)
self.dut.expect_exact('Running {}...'.format(case.name), timeout=1)
break
except TIMEOUT as e:
if retry >= self.retry_times - 1:

View File

@@ -3,6 +3,7 @@
cmake_minimum_required(VERSION 3.16)
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/cxx/experimental/experimental_cpp_component/")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/components/driver/test_apps/components")
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(unit-test-app)