mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 18:57:19 +02:00
Merge branch 'refactor/remove_i2c_slave_v1_s1' into 'master'
refactor(i2c): Replace i2c test from version one to version two See merge request espressif/esp-idf!39085
This commit is contained in:
@ -2,21 +2,14 @@ set(srcs "test_app_main.c"
|
||||
"test_i2c_common.c"
|
||||
)
|
||||
|
||||
if(CONFIG_SOC_I2C_SUPPORT_SLAVE)
|
||||
if(CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2)
|
||||
list(APPEND srcs "test_i2c_slave_v2.c")
|
||||
else()
|
||||
if(CONFIG_SOC_I2C_SUPPORT_SLAVE AND CONFIG_SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE)
|
||||
list(APPEND srcs "test_i2c_multi.c")
|
||||
|
||||
if(CONFIG_SOC_I2C_SLAVE_SUPPORT_BROADCAST)
|
||||
list(APPEND srcs "test_i2c_broadcast.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_I2C_SLAVE_SUPPORT_I2CRAM_ACCESS)
|
||||
list(APPEND srcs "test_i2c_ram.c")
|
||||
endif()
|
||||
|
||||
if(CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR AND CONFIG_SOC_I2C_SUPPORT_SLAVE)
|
||||
if(CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR)
|
||||
list(APPEND srcs "test_i2c_10bit.c")
|
||||
endif()
|
||||
|
||||
@ -32,7 +25,6 @@ if(CONFIG_SOC_I2C_SUPPORT_SLAVE)
|
||||
list(APPEND srcs "test_i2c_iram.c")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT CONFIG_I2C_MASTER_ISR_HANDLER_IN_IRAM)
|
||||
list(APPEND srcs "test_i2c_flash_text.c")
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -42,6 +42,14 @@ extern "C" {
|
||||
#define TEST_I2C_PORT 0
|
||||
#define DATA_LENGTH 100
|
||||
|
||||
/**
|
||||
* @brief Slave test event
|
||||
*/
|
||||
typedef enum {
|
||||
I2C_SLAVE_EVT_RX,
|
||||
I2C_SLAVE_EVT_TX
|
||||
} i2c_slave_event_t;
|
||||
|
||||
/**
|
||||
* @brief Display buffer
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@ -22,14 +22,77 @@
|
||||
#include "test_utils.h"
|
||||
#include "test_board.h"
|
||||
|
||||
static QueueHandle_t s_receive_queue;
|
||||
static QueueHandle_t event_queue;
|
||||
static uint8_t *temp_data;
|
||||
static size_t temp_len = 0;
|
||||
|
||||
static IRAM_ATTR bool example_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data)
|
||||
static IRAM_ATTR bool i2c_slave_request_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_request_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t high_task_wakeup = pdFALSE;
|
||||
QueueHandle_t receive_queue = (QueueHandle_t)user_data;
|
||||
xQueueSendFromISR(receive_queue, edata, &high_task_wakeup);
|
||||
return high_task_wakeup == pdTRUE;
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_TX;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool i2c_slave_receive_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_rx_done_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_RX;
|
||||
memcpy(temp_data, evt_data->buffer, evt_data->length);
|
||||
temp_len = evt_data->length;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static void i2c_slave_read_test_10bit(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
i2c_slave_dev_handle_t handle;
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
temp_data = heap_caps_malloc(DATA_LENGTH, MALLOC_CAP_DEFAULT);
|
||||
assert(temp_data);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x134,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_10,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
|
||||
i2c_slave_event_t evt;
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < temp_len; i++) {
|
||||
TEST_ASSERT(temp_data[i] == i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unity_send_signal("ready to delete");
|
||||
free(temp_data);
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
static void i2c_master_write_test_10bit(void)
|
||||
@ -74,47 +137,6 @@ static void i2c_master_write_test_10bit(void)
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
static void i2c_slave_read_test_10bit(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_10,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x134,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = example_i2c_rx_done_callback,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(1000));
|
||||
|
||||
disp_buf(data_rd, DATA_LENGTH);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
}
|
||||
vQueueDelete(s_receive_queue);
|
||||
unity_send_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test 10 bit", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_10bit, i2c_slave_read_test_10bit);
|
||||
|
||||
static void master_read_slave_test_10bit(void)
|
||||
@ -134,6 +156,7 @@ static void master_read_slave_test_10bit(void)
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_10,
|
||||
.device_address = 0x134,
|
||||
.scl_speed_hz = 100000,
|
||||
.scl_wait_us = 20000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
@ -141,18 +164,13 @@ static void master_read_slave_test_10bit(void)
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
printf("Slave please write data to buffer\n");
|
||||
|
||||
unity_send_signal("slave write");
|
||||
unity_wait_for_signal("master read");
|
||||
|
||||
TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1));
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
printf("%d\n", data_rd[i]);
|
||||
printf("%x\n", data_rd[i]);
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
}
|
||||
unity_send_signal("ready to delete 10bit");
|
||||
unity_send_signal("ready to delete master read test");
|
||||
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
@ -160,33 +178,52 @@ static void master_read_slave_test_10bit(void)
|
||||
|
||||
static void slave_write_buffer_test_10bit(void)
|
||||
{
|
||||
uint8_t data_wr[DATA_LENGTH] = {0};
|
||||
i2c_slave_dev_handle_t handle;
|
||||
uint8_t data_wr[DATA_LENGTH];
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_10,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x134,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_10,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("slave write");
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
data_wr[i] = i;
|
||||
}
|
||||
|
||||
TEST_ESP_OK(i2c_slave_transmit(slave_handle, data_wr, DATA_LENGTH, -1));
|
||||
disp_buf(data_wr, DATA_LENGTH);
|
||||
unity_send_signal("master read");
|
||||
unity_wait_for_signal("ready to delete 10bit");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
i2c_slave_event_t evt;
|
||||
uint32_t write_len;
|
||||
while (true) {
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_TX) {
|
||||
TEST_ESP_OK(i2c_slave_write(handle, data_wr, DATA_LENGTH, &write_len, 1000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unity_wait_for_signal("ready to delete master read test");
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master read slave test 10 bit", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_test_10bit, slave_write_buffer_test_10bit);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@ -22,14 +22,26 @@
|
||||
#include "test_utils.h"
|
||||
#include "test_board.h"
|
||||
|
||||
static QueueHandle_t s_receive_queue;
|
||||
static QueueHandle_t event_queue;
|
||||
static uint8_t *temp_data;
|
||||
static size_t temp_len = 0;
|
||||
|
||||
static IRAM_ATTR bool example_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data)
|
||||
static IRAM_ATTR bool i2c_slave_request_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_request_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t high_task_wakeup = pdFALSE;
|
||||
QueueHandle_t receive_queue = (QueueHandle_t)user_data;
|
||||
xQueueSendFromISR(receive_queue, edata, &high_task_wakeup);
|
||||
return high_task_wakeup == pdTRUE;
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_TX;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool i2c_slave_receive_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_rx_done_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_RX;
|
||||
memcpy(temp_data, evt_data->buffer, evt_data->length);
|
||||
temp_len = evt_data->length;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static void i2c_master_write_test_broadcast(void)
|
||||
@ -77,43 +89,52 @@ static void i2c_master_write_test_broadcast(void)
|
||||
static void i2c_slave_read_test_broadcast(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
i2c_slave_dev_handle_t handle;
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
temp_data = heap_caps_malloc(DATA_LENGTH, MALLOC_CAP_DEFAULT);
|
||||
assert(temp_data);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x53,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
.flags.broadcast_en = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = example_i2c_rx_done_callback,
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH));
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(1000));
|
||||
disp_buf(data_rd, DATA_LENGTH);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
i2c_slave_event_t evt;
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < temp_len; i++) {
|
||||
TEST_ASSERT(temp_data[i] == i);
|
||||
}
|
||||
vQueueDelete(s_receive_queue);
|
||||
}
|
||||
}
|
||||
|
||||
unity_send_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
free(temp_data);
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test broadcast", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_broadcast, i2c_slave_read_test_broadcast);
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "hal/uart_ll.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "driver/i2c_master.h"
|
||||
#include "driver/i2c_slave.h"
|
||||
#include "esp_log.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_board.h"
|
||||
@ -440,3 +441,48 @@ TEST_CASE("Test get handle with known port", "[i2c]")
|
||||
TEST_ASSERT((uint32_t)bus_handle == (uint32_t)handle);
|
||||
_test_i2c_del_bus_device(bus_handle, dev_handle);
|
||||
}
|
||||
|
||||
#if SOC_I2C_SUPPORT_SLAVE
|
||||
|
||||
TEST_CASE("I2C peripheral allocate slave all", "[i2c]")
|
||||
{
|
||||
i2c_slave_dev_handle_t dev_handle[SOC_HP_I2C_NUM];
|
||||
for (int i = 0; i < SOC_HP_I2C_NUM; i++) {
|
||||
i2c_slave_config_t i2c_slv_config_1 = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = -1,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config_1, &dev_handle[i]));
|
||||
}
|
||||
i2c_slave_config_t i2c_slv_config_1 = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = -1,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_slave_dev_handle_t dev_handle_2;
|
||||
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, i2c_new_slave_device(&i2c_slv_config_1, &dev_handle_2));
|
||||
|
||||
for (int i = 0; i < SOC_HP_I2C_NUM; i++) {
|
||||
TEST_ESP_OK(i2c_del_slave_device(dev_handle[i]));
|
||||
}
|
||||
|
||||
// Get another one
|
||||
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config_1, &dev_handle_2));
|
||||
TEST_ESP_OK(i2c_del_slave_device(dev_handle_2));
|
||||
}
|
||||
|
||||
#endif // SOC_I2C_SUPPORT_SLAVE
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@ -24,7 +24,9 @@
|
||||
#include "unity_test_utils_cache.h"
|
||||
|
||||
static QueueHandle_t s_send_queue;
|
||||
static QueueHandle_t s_receive_queue;
|
||||
static QueueHandle_t event_queue;
|
||||
static uint8_t *temp_data;
|
||||
static size_t temp_len = 0;
|
||||
|
||||
static IRAM_ATTR bool test_master_tx_done_callback(i2c_master_dev_handle_t i2c_dev, const i2c_master_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
@ -34,19 +36,29 @@ static IRAM_ATTR bool test_master_tx_done_callback(i2c_master_dev_handle_t i2c_d
|
||||
return high_task_wakeup == pdTRUE;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool test_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data)
|
||||
{
|
||||
BaseType_t high_task_wakeup = pdFALSE;
|
||||
QueueHandle_t receive_queue = (QueueHandle_t)user_data;
|
||||
xQueueSendFromISR(receive_queue, edata, &high_task_wakeup);
|
||||
return high_task_wakeup == pdTRUE;
|
||||
}
|
||||
|
||||
static void IRAM_ATTR test_delay_post_cache_disable(void *args)
|
||||
{
|
||||
esp_rom_delay_us(10000);
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool i2c_slave_request_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_request_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_TX;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool i2c_slave_receive_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_rx_done_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_RX;
|
||||
memcpy(temp_data, evt_data->buffer, evt_data->length);
|
||||
temp_len = evt_data->length;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static void i2c_master_write_test_iram_safe(void)
|
||||
{
|
||||
uint8_t data_wr[DATA_LENGTH] = { 0 };
|
||||
@ -97,41 +109,52 @@ static void i2c_master_write_test_iram_safe(void)
|
||||
|
||||
static void i2c_slave_read_test_iram_safe(void)
|
||||
{
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
i2c_slave_dev_handle_t handle;
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
temp_data = heap_caps_malloc(DATA_LENGTH, MALLOC_CAP_DEFAULT);
|
||||
assert(temp_data);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = test_i2c_rx_done_callback,
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH));
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
unity_utils_run_cache_disable_stub(test_delay_post_cache_disable, NULL);
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000));
|
||||
disp_buf(data_rd, DATA_LENGTH);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
|
||||
i2c_slave_event_t evt;
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < temp_len; i++) {
|
||||
TEST_ASSERT(temp_data[i] == i);
|
||||
}
|
||||
vQueueDelete(s_receive_queue);
|
||||
}
|
||||
}
|
||||
|
||||
unity_send_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
free(temp_data);
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test iram safe", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_iram_safe, i2c_slave_read_test_iram_safe);
|
||||
|
@ -33,16 +33,76 @@ void disp_buf(uint8_t *buf, int len)
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#define DATA_LENGTH 100
|
||||
static QueueHandle_t event_queue;
|
||||
static uint8_t *temp_data;
|
||||
static size_t temp_len = 0;
|
||||
|
||||
static QueueHandle_t s_receive_queue;
|
||||
|
||||
static IRAM_ATTR bool test_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data)
|
||||
static IRAM_ATTR bool i2c_slave_request_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_request_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t high_task_wakeup = pdFALSE;
|
||||
QueueHandle_t receive_queue = (QueueHandle_t)user_data;
|
||||
xQueueSendFromISR(receive_queue, edata, &high_task_wakeup);
|
||||
return high_task_wakeup == pdTRUE;
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_TX;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool i2c_slave_receive_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_rx_done_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_RX;
|
||||
memcpy(temp_data, evt_data->buffer, evt_data->length);
|
||||
temp_len = evt_data->length;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static void i2c_slave_read_test(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
i2c_slave_dev_handle_t handle;
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
temp_data = heap_caps_malloc(DATA_LENGTH, MALLOC_CAP_DEFAULT);
|
||||
assert(temp_data);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
|
||||
i2c_slave_event_t evt;
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < temp_len; i++) {
|
||||
TEST_ASSERT(temp_data[i] == i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unity_send_signal("ready to delete");
|
||||
free(temp_data);
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
static void i2c_master_write_test(void)
|
||||
@ -63,13 +123,15 @@ static void i2c_master_write_test(void)
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x58,
|
||||
.device_address = ESP_SLAVE_ADDR,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
unity_send_signal("i2c master init first");
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
unity_send_signal("master write");
|
||||
@ -85,133 +147,12 @@ static void i2c_master_write_test(void)
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
static void i2c_slave_read_test(void)
|
||||
{
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = test_i2c_rx_done_callback,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000));
|
||||
disp_buf(data_rd, DATA_LENGTH);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
}
|
||||
vQueueDelete(s_receive_queue);
|
||||
unity_send_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
// The test for s2 is unstable on ci, but it should not fail in local test
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test", "[i2c][test_env=generic_multi_device][timeout=150][ignore]", i2c_master_write_test, i2c_slave_read_test);
|
||||
#else
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test, i2c_slave_read_test);
|
||||
|
||||
static void i2c_master_write_test_large_write_small_read(void)
|
||||
{
|
||||
uint8_t data_wr[35] = { 0 }; // IDFCI-2151 Temporarily make up this test.
|
||||
int i;
|
||||
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x58,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
unity_send_signal("i2c master init first");
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
unity_send_signal("master write");
|
||||
for (i = 0; i < 35; i++) {
|
||||
data_wr[i] = i;
|
||||
}
|
||||
|
||||
disp_buf(data_wr, i);
|
||||
TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, 35, -1));
|
||||
unity_wait_for_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
static void i2c_slave_read_test_large_write_small_read(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
uint8_t data_rd[7] = {0};
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = test_i2c_rx_done_callback,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, 7));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000));
|
||||
disp_buf(data_rd, 7);
|
||||
for (int i = 0; i < 7; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
}
|
||||
for (int i = 0; i < 7; i++) {
|
||||
TEST_ASSERT(rx_data.buffer[i] == i);
|
||||
}
|
||||
vQueueDelete(s_receive_queue);
|
||||
unity_send_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test (large write small read)", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_large_write_small_read, i2c_slave_read_test_large_write_small_read);
|
||||
#endif
|
||||
|
||||
static void master_read_slave_test(void)
|
||||
{
|
||||
@ -228,8 +169,9 @@ static void master_read_slave_test(void)
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x58,
|
||||
.device_address = ESP_SLAVE_ADDR,
|
||||
.scl_speed_hz = 100000,
|
||||
.scl_wait_us = 20000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
@ -237,15 +179,10 @@ static void master_read_slave_test(void)
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
printf("Slave please write data to buffer\n");
|
||||
|
||||
unity_send_signal("slave write");
|
||||
unity_wait_for_signal("master read");
|
||||
|
||||
TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1));
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
printf("%d\n", data_rd[i]);
|
||||
printf("%x\n", data_rd[i]);
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
}
|
||||
unity_send_signal("ready to delete master read test");
|
||||
@ -256,41 +193,59 @@ static void master_read_slave_test(void)
|
||||
|
||||
static void slave_write_buffer_test(void)
|
||||
{
|
||||
uint8_t data_wr[DATA_LENGTH] = {0};
|
||||
i2c_slave_dev_handle_t handle;
|
||||
uint8_t data_wr[DATA_LENGTH];
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("slave write");
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
data_wr[i] = i;
|
||||
}
|
||||
|
||||
TEST_ESP_OK(i2c_slave_transmit(slave_handle, data_wr, DATA_LENGTH, -1));
|
||||
disp_buf(data_wr, DATA_LENGTH);
|
||||
unity_send_signal("master read");
|
||||
i2c_slave_event_t evt;
|
||||
uint32_t write_len;
|
||||
while (true) {
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_TX) {
|
||||
TEST_ESP_OK(i2c_slave_write(handle, data_wr, DATA_LENGTH, &write_len, 1000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unity_wait_for_signal("ready to delete master read test");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master read slave test", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_test, slave_write_buffer_test);
|
||||
|
||||
static void i2c_master_write_read_test(void)
|
||||
static void i2c_master_write_test_with_customize_api(void)
|
||||
{
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
uint8_t data_wr[DATA_LENGTH] = { 0 };
|
||||
int i;
|
||||
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
@ -305,7 +260,7 @@ static void i2c_master_write_read_test(void)
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x58,
|
||||
.device_address = I2C_DEVICE_ADDRESS_NOT_USED,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
@ -316,88 +271,178 @@ static void i2c_master_write_read_test(void)
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
printf("master read buffer\n");
|
||||
|
||||
unity_send_signal("slave write");
|
||||
unity_wait_for_signal("master read and write");
|
||||
|
||||
TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1));
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
disp_buf(data_rd, DATA_LENGTH);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
}
|
||||
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
unity_send_signal("master write");
|
||||
for (i = 0; i < DATA_LENGTH; i++) {
|
||||
data_wr[i] = i;
|
||||
}
|
||||
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
unity_send_signal("slave read");
|
||||
unity_wait_for_signal("ready to read");
|
||||
TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1));
|
||||
unity_send_signal("sent done");
|
||||
disp_buf(data_wr, i);
|
||||
|
||||
uint8_t address = (ESP_SLAVE_ADDR << 1 | 0);
|
||||
|
||||
i2c_operation_job_t i2c_ops[] = {
|
||||
{ .command = I2C_MASTER_CMD_START },
|
||||
{ .command = I2C_MASTER_CMD_WRITE, .write = { .ack_check = true, .data = (uint8_t *) &address, .total_bytes = 1 } },
|
||||
{ .command = I2C_MASTER_CMD_WRITE, .write = { .ack_check = true, .data = (uint8_t *) data_wr, .total_bytes = DATA_LENGTH } },
|
||||
{ .command = I2C_MASTER_CMD_STOP },
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_master_execute_defined_operations(dev_handle, i2c_ops, sizeof(i2c_ops) / sizeof(i2c_operation_job_t), -1));
|
||||
unity_wait_for_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave with customize api", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_with_customize_api, i2c_slave_read_test);
|
||||
|
||||
static void master_read_slave_test_single_byte(void)
|
||||
{
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = I2C_DEVICE_ADDRESS_NOT_USED,
|
||||
.scl_speed_hz = 100000,
|
||||
.scl_wait_us = 20000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
uint8_t read_address = (ESP_SLAVE_ADDR << 1 | 1);
|
||||
|
||||
i2c_operation_job_t i2c_ops[] = {
|
||||
{ .command = I2C_MASTER_CMD_START },
|
||||
{ .command = I2C_MASTER_CMD_WRITE, .write = { .ack_check = true, .data = (uint8_t *) &read_address, .total_bytes = 1 } },
|
||||
{ .command = I2C_MASTER_CMD_READ, .read = { .ack_value = I2C_NACK_VAL, .data = data_rd, .total_bytes = 1 }},
|
||||
{ .command = I2C_MASTER_CMD_STOP },
|
||||
};
|
||||
|
||||
i2c_master_execute_defined_operations(dev_handle, i2c_ops, sizeof(i2c_ops) / sizeof(i2c_operation_job_t), 1000);
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
TEST_ASSERT(data_rd[0] == 6);
|
||||
unity_send_signal("ready to delete master read test");
|
||||
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
static void i2c_slave_read_write_test(void)
|
||||
static void slave_write_buffer_test_single_byte(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
uint8_t data_wr[DATA_LENGTH] = {0};
|
||||
i2c_slave_dev_handle_t handle;
|
||||
uint8_t data_wr[DATA_LENGTH];
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = test_i2c_rx_done_callback,
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
unity_wait_for_signal("slave write");
|
||||
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
data_wr[i] = i;
|
||||
}
|
||||
TEST_ESP_OK(i2c_slave_transmit(slave_handle, data_wr, DATA_LENGTH, -1));
|
||||
disp_buf(data_wr, DATA_LENGTH);
|
||||
unity_send_signal("master read and write");
|
||||
unity_wait_for_signal("slave read");
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH));
|
||||
unity_send_signal("ready to read");
|
||||
unity_wait_for_signal("sent done");
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(1000));
|
||||
data_wr[0] = 6;
|
||||
|
||||
printf("slave read data is:\n");
|
||||
disp_buf(data_rd, DATA_LENGTH);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
i2c_slave_event_t evt;
|
||||
uint32_t write_len;
|
||||
while (true) {
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_TX) {
|
||||
TEST_ESP_OK(i2c_slave_write(handle, data_wr, 1, &write_len, 1000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unity_wait_for_signal("ready to delete master read test");
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master read slave test single byte", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_test_single_byte, slave_write_buffer_test_single_byte);
|
||||
|
||||
static void i2c_slave_repeat_read(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
i2c_slave_dev_handle_t handle;
|
||||
event_queue = xQueueCreate(5, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
temp_data = heap_caps_malloc(DATA_LENGTH * 3, MALLOC_CAP_DEFAULT);
|
||||
assert(temp_data);
|
||||
int times = 3;
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH * 3,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
i2c_slave_event_t evt;
|
||||
while (times > 0) {
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < temp_len; i++) {
|
||||
TEST_ASSERT(temp_data[i] == (i + 3 - times));
|
||||
}
|
||||
}
|
||||
}
|
||||
times--;
|
||||
}
|
||||
|
||||
unity_send_signal("ready to delete");
|
||||
vQueueDelete(s_receive_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
free(temp_data);
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C read and write test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_read_test, i2c_slave_read_write_test);
|
||||
|
||||
static void i2c_master_repeat_write(void)
|
||||
{
|
||||
uint8_t data_wr[DATA_LENGTH] = { 0 };
|
||||
int i;
|
||||
int times = 3;
|
||||
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
@ -407,13 +452,13 @@ static void i2c_master_repeat_write(void)
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x58,
|
||||
.device_address = ESP_SLAVE_ADDR,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
@ -424,6 +469,11 @@ static void i2c_master_repeat_write(void)
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
unity_send_signal("master write");
|
||||
for (i = 0; i < DATA_LENGTH; i++) {
|
||||
data_wr[i] = i;
|
||||
}
|
||||
|
||||
for (int j = 0; j < times; j++) {
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
data_wr[i] = j + i;
|
||||
@ -433,129 +483,12 @@ static void i2c_master_repeat_write(void)
|
||||
}
|
||||
unity_wait_for_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
static void i2c_slave_repeat_read(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
uint32_t size = 0;
|
||||
int times = 3;
|
||||
uint8_t data_rd[DATA_LENGTH * 3] = {0};
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = test_i2c_rx_done_callback,
|
||||
};
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
while (times > 0) {
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd + size, DATA_LENGTH));
|
||||
xQueueReceive(s_receive_queue, &rx_data, (TickType_t)portMAX_DELAY);
|
||||
|
||||
size += DATA_LENGTH;
|
||||
times--;
|
||||
}
|
||||
|
||||
disp_buf(data_rd, size);
|
||||
for (int j = 0; j < times; j++) {
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i + DATA_LENGTH * j] == (i + j));
|
||||
}
|
||||
}
|
||||
unity_send_signal("ready to delete");
|
||||
vQueueDelete(s_receive_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C repeat write test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_repeat_write, i2c_slave_repeat_read);
|
||||
|
||||
static void master_read_slave_1b_test(void)
|
||||
{
|
||||
uint8_t data_rd[1] = {0};
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x58,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
printf("Slave please write data to buffer\n");
|
||||
|
||||
unity_send_signal("slave write");
|
||||
unity_wait_for_signal("master read");
|
||||
|
||||
TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, 1, -1));
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
printf("%x\n", data_rd[0]);
|
||||
TEST_ASSERT(data_rd[0] == 0xe);
|
||||
unity_send_signal("ready to delete master read test");
|
||||
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
static void slave_write_buffer_1b_test(void)
|
||||
{
|
||||
uint8_t data_wr[1] = {0};
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("slave write");
|
||||
data_wr[0] = 0xe;
|
||||
|
||||
TEST_ESP_OK(i2c_slave_transmit(slave_handle, data_wr, 1, -1));
|
||||
disp_buf(data_wr, 1);
|
||||
unity_send_signal("master read");
|
||||
unity_wait_for_signal("ready to delete master read test");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master read slave 1 byte test", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_1b_test, slave_write_buffer_1b_test);
|
||||
|
||||
static void master_probe_slave(void)
|
||||
{
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
@ -589,13 +522,14 @@ static void master_probe_slave(void)
|
||||
static void slave_init_for_probe(void)
|
||||
{
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
@ -644,7 +578,7 @@ static void i2c_master_write_multi_buffer_test(void)
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x58,
|
||||
.device_address = ESP_SLAVE_ADDR,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
@ -670,47 +604,57 @@ static void i2c_master_write_multi_buffer_test(void)
|
||||
static void i2c_slave_read_multi_buffer_test(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
uint8_t data_rd[DATA_LENGTH * 3] = {0};
|
||||
i2c_slave_dev_handle_t handle;
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
temp_data = heap_caps_malloc(DATA_LENGTH * 3, MALLOC_CAP_DEFAULT);
|
||||
assert(temp_data);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 512,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH * 3,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = test_i2c_rx_done_callback,
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH * 3));
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000));
|
||||
disp_buf(data_rd, DATA_LENGTH * 3);
|
||||
|
||||
i2c_slave_event_t evt;
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
TEST_ASSERT(temp_data[i] == i);
|
||||
}
|
||||
for (int i = DATA_LENGTH; i < DATA_LENGTH * 2; i++) {
|
||||
TEST_ASSERT(data_rd[i] == ((i - DATA_LENGTH) + 0x05));
|
||||
TEST_ASSERT(temp_data[i] == ((i - DATA_LENGTH) + 0x05));
|
||||
}
|
||||
for (int i = DATA_LENGTH * 2; i < DATA_LENGTH * 3; i++) {
|
||||
TEST_ASSERT(data_rd[i] == ((i - DATA_LENGTH * 2) + 0x0f));
|
||||
TEST_ASSERT(temp_data[i] == ((i - DATA_LENGTH * 2) + 0x0f));
|
||||
}
|
||||
vQueueDelete(s_receive_queue);
|
||||
}
|
||||
}
|
||||
|
||||
unity_send_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
free(temp_data);
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave with multi buffer api test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_multi_buffer_test, i2c_slave_read_multi_buffer_test);
|
||||
@ -759,41 +703,51 @@ static void i2c_master_write_test_more_port(void)
|
||||
|
||||
static void i2c_slave_read_test_more_port(void)
|
||||
{
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
i2c_slave_dev_handle_t handle;
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
temp_data = heap_caps_malloc(DATA_LENGTH, MALLOC_CAP_DEFAULT);
|
||||
assert(temp_data);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = 1,
|
||||
.send_buf_depth = 256,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = test_i2c_rx_done_callback,
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH));
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000));
|
||||
disp_buf(data_rd, DATA_LENGTH);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
|
||||
i2c_slave_event_t evt;
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < temp_len; i++) {
|
||||
TEST_ASSERT(temp_data[i] == i);
|
||||
}
|
||||
vQueueDelete(s_receive_queue);
|
||||
}
|
||||
}
|
||||
|
||||
unity_send_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
free(temp_data);
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test, more ports", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_more_port, i2c_slave_read_test_more_port);
|
||||
|
@ -1,213 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "unity.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "esp_err.h"
|
||||
#include "soc/clk_tree_defs.h"
|
||||
#include "soc/soc_caps.h"
|
||||
#include "hal/uart_ll.h"
|
||||
#include "esp_private/periph_ctrl.h"
|
||||
#include "driver/i2c_master.h"
|
||||
#include "driver/i2c_slave.h"
|
||||
#include "esp_log.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_board.h"
|
||||
|
||||
static esp_err_t i2c_master_write_to_addr(i2c_master_dev_handle_t device_handle, uint8_t address, const uint8_t *data, uint32_t size, int xfer_timeout_ms)
|
||||
{
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint8_t *buffer = (uint8_t*)calloc(1, size + 1);
|
||||
buffer[0] = address;
|
||||
memcpy(buffer + 1, data, size);
|
||||
ret = i2c_master_transmit(device_handle, buffer, 1 + size, xfer_timeout_ms);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define DATA_LENGTH_RAM 6
|
||||
|
||||
static void i2c_master_write_to_ram_test(void)
|
||||
{
|
||||
uint8_t data_wr[DATA_LENGTH_RAM] = { 0 };
|
||||
int i;
|
||||
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x58,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
unity_send_signal("i2c master init first");
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
unity_send_signal("master write");
|
||||
for (i = 0; i < DATA_LENGTH_RAM; i++) {
|
||||
data_wr[i] = i + 1;
|
||||
}
|
||||
disp_buf(data_wr, i);
|
||||
// Write slave ram address is 0x5.
|
||||
i2c_master_write_to_addr(dev_handle, 0x5, data_wr, DATA_LENGTH_RAM, -1);
|
||||
|
||||
unity_wait_for_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
static void i2c_slave_read_from_ram_test(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
uint8_t data_rd[DATA_LENGTH_RAM] = {0};
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.flags.access_ram_en = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
|
||||
TEST_ESP_OK(i2c_slave_read_ram(slave_handle, 0x5, data_rd, DATA_LENGTH_RAM));
|
||||
|
||||
disp_buf(data_rd, DATA_LENGTH_RAM);
|
||||
for (int i = 0; i < DATA_LENGTH_RAM; i++) {
|
||||
TEST_ASSERT(data_rd[i] == (i + 1));
|
||||
}
|
||||
unity_send_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave test - slave directly read from ram", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_to_ram_test, i2c_slave_read_from_ram_test);
|
||||
|
||||
static void master_read_slave_from_ram_test(void)
|
||||
{
|
||||
uint8_t data_rd[DATA_LENGTH_RAM] = {0};
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = 0x58,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
unity_send_signal("i2c master init first");
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
printf("Slave please write data to buffer\n");
|
||||
|
||||
unity_send_signal("slave write");
|
||||
unity_wait_for_signal("master read");
|
||||
|
||||
uint8_t *buffer = (uint8_t*)malloc(sizeof(uint8_t));
|
||||
buffer[0] = 0x2; // Means write offset 2 in I2C ram.
|
||||
TEST_ESP_OK(i2c_master_transmit_receive(dev_handle, buffer, 1, data_rd, DATA_LENGTH_RAM, -1));
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
for (int i = 0; i < DATA_LENGTH_RAM; i++) {
|
||||
printf("%d\n", data_rd[i]);
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
}
|
||||
unity_send_signal("ready to delete ram test");
|
||||
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
static void slave_write_buffer_to_ram_test(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
uint8_t data_wr[DATA_LENGTH_RAM] = {0};
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.flags.access_ram_en = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("slave write");
|
||||
for (int i = 0; i < DATA_LENGTH_RAM; i++) {
|
||||
data_wr[i] = i;
|
||||
}
|
||||
|
||||
TEST_ESP_OK(i2c_slave_write_ram(slave_handle, 0x2, data_wr, DATA_LENGTH_RAM));
|
||||
disp_buf(data_wr, DATA_LENGTH_RAM);
|
||||
unity_send_signal("master read");
|
||||
unity_wait_for_signal("ready to delete ram test");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master read slave ram test", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_from_ram_test, slave_write_buffer_to_ram_test);
|
||||
|
||||
TEST_CASE("I2C slave init as ram but read by fifo", "[i2c]")
|
||||
{
|
||||
uint8_t data_rd[10] = {0};
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.flags.access_ram_en = true,
|
||||
};
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, i2c_slave_receive(slave_handle, data_rd, 10));
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
}
|
@ -1,434 +0,0 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "unity.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "esp_err.h"
|
||||
#include "driver/i2c_master.h"
|
||||
#include "driver/i2c_slave.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "esp_log.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_board.h"
|
||||
|
||||
#if SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE
|
||||
|
||||
TEST_CASE("I2C peripheral allocate slave all", "[i2c]")
|
||||
{
|
||||
i2c_slave_dev_handle_t dev_handle[SOC_HP_I2C_NUM];
|
||||
for (int i = 0; i < SOC_HP_I2C_NUM; i++) {
|
||||
i2c_slave_config_t i2c_slv_config_1 = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = -1,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config_1, &dev_handle[i]));
|
||||
}
|
||||
i2c_slave_config_t i2c_slv_config_1 = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = -1,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_slave_dev_handle_t dev_handle_2;
|
||||
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_FOUND, i2c_new_slave_device(&i2c_slv_config_1, &dev_handle_2));
|
||||
|
||||
for (int i = 0; i < SOC_HP_I2C_NUM; i++) {
|
||||
TEST_ESP_OK(i2c_del_slave_device(dev_handle[i]));
|
||||
}
|
||||
|
||||
// Get another one
|
||||
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config_1, &dev_handle_2));
|
||||
TEST_ESP_OK(i2c_del_slave_device(dev_handle_2));
|
||||
}
|
||||
|
||||
static QueueHandle_t event_queue;
|
||||
static uint8_t *temp_data;
|
||||
static size_t temp_len = 0;
|
||||
|
||||
typedef enum {
|
||||
I2C_SLAVE_EVT_RX,
|
||||
I2C_SLAVE_EVT_TX
|
||||
} i2c_slave_event_t;
|
||||
|
||||
void disp_buf(uint8_t *buf, int len)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < len; i++) {
|
||||
printf("%02x ", buf[i]);
|
||||
if ((i + 1) % 16 == 0) {
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
static bool i2c_slave_request_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_request_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_TX;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static bool i2c_slave_receive_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_rx_done_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_RX;
|
||||
memcpy(temp_data, evt_data->buffer, evt_data->length);
|
||||
temp_len = evt_data->length;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static void i2c_slave_read_test_v2(void)
|
||||
{
|
||||
unity_wait_for_signal("i2c master init first");
|
||||
i2c_slave_dev_handle_t handle;
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
temp_data = malloc(DATA_LENGTH);
|
||||
assert(temp_data);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
|
||||
i2c_slave_event_t evt;
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < temp_len; i++) {
|
||||
TEST_ASSERT(temp_data[i] == i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unity_send_signal("ready to delete");
|
||||
free(temp_data);
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
static void i2c_master_write_test_v2(void)
|
||||
{
|
||||
uint8_t data_wr[DATA_LENGTH] = { 0 };
|
||||
int i;
|
||||
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = ESP_SLAVE_ADDR,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
unity_send_signal("i2c master init first");
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
unity_send_signal("master write");
|
||||
for (i = 0; i < DATA_LENGTH; i++) {
|
||||
data_wr[i] = i;
|
||||
}
|
||||
|
||||
disp_buf(data_wr, i);
|
||||
TEST_ESP_OK(i2c_master_transmit(dev_handle, data_wr, DATA_LENGTH, -1));
|
||||
unity_wait_for_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
#if CONFIG_IDF_TARGET_ESP32S2
|
||||
// The test for s2 is unstable on ci, but it should not fail in local test
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave v2 test", "[i2c][test_env=generic_multi_device][timeout=150][ignore]", i2c_master_write_test_v2, i2c_slave_read_test_v2);
|
||||
#else
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave v2 test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_v2, i2c_slave_read_test_v2);
|
||||
#endif
|
||||
|
||||
static void master_read_slave_test_v2(void)
|
||||
{
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = ESP_SLAVE_ADDR,
|
||||
.scl_speed_hz = 100000,
|
||||
.scl_wait_us = 20000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
TEST_ESP_OK(i2c_master_receive(dev_handle, data_rd, DATA_LENGTH, -1));
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
printf("%x\n", data_rd[i]);
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
}
|
||||
unity_send_signal("ready to delete master read test");
|
||||
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
static void slave_write_buffer_test_v2(void)
|
||||
{
|
||||
i2c_slave_dev_handle_t handle;
|
||||
uint8_t data_wr[DATA_LENGTH];
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
data_wr[i] = i;
|
||||
}
|
||||
|
||||
i2c_slave_event_t evt;
|
||||
uint32_t write_len;
|
||||
while (true) {
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_TX) {
|
||||
TEST_ESP_OK(i2c_slave_write(handle, data_wr, DATA_LENGTH, &write_len, 1000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unity_wait_for_signal("ready to delete master read test");
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master read slave test", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_test_v2, slave_write_buffer_test_v2);
|
||||
|
||||
static void i2c_master_write_test_with_customize_api(void)
|
||||
{
|
||||
uint8_t data_wr[DATA_LENGTH] = { 0 };
|
||||
int i;
|
||||
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = I2C_DEVICE_ADDRESS_NOT_USED,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
unity_send_signal("i2c master init first");
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
unity_send_signal("master write");
|
||||
for (i = 0; i < DATA_LENGTH; i++) {
|
||||
data_wr[i] = i;
|
||||
}
|
||||
|
||||
disp_buf(data_wr, i);
|
||||
|
||||
uint8_t address = (ESP_SLAVE_ADDR << 1 | 0);
|
||||
|
||||
i2c_operation_job_t i2c_ops[] = {
|
||||
{ .command = I2C_MASTER_CMD_START },
|
||||
{ .command = I2C_MASTER_CMD_WRITE, .write = { .ack_check = true, .data = (uint8_t *) &address, .total_bytes = 1 } },
|
||||
{ .command = I2C_MASTER_CMD_WRITE, .write = { .ack_check = true, .data = (uint8_t *) data_wr, .total_bytes = DATA_LENGTH } },
|
||||
{ .command = I2C_MASTER_CMD_STOP },
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_master_execute_defined_operations(dev_handle, i2c_ops, sizeof(i2c_ops) / sizeof(i2c_operation_job_t), -1));
|
||||
unity_wait_for_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master write slave with customize api", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_test_with_customize_api, i2c_slave_read_test_v2);
|
||||
|
||||
static void master_read_slave_test_v2_single_byte(void)
|
||||
{
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
i2c_master_bus_config_t i2c_mst_config = {
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.scl_io_num = I2C_MASTER_SCL_IO,
|
||||
.sda_io_num = I2C_MASTER_SDA_IO,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
i2c_master_bus_handle_t bus_handle;
|
||||
TEST_ESP_OK(i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = I2C_DEVICE_ADDRESS_NOT_USED,
|
||||
.scl_speed_hz = 100000,
|
||||
.scl_wait_us = 20000,
|
||||
};
|
||||
|
||||
i2c_master_dev_handle_t dev_handle;
|
||||
TEST_ESP_OK(i2c_master_bus_add_device(bus_handle, &dev_cfg, &dev_handle));
|
||||
|
||||
unity_wait_for_signal("i2c slave init finish");
|
||||
|
||||
uint8_t read_address = (ESP_SLAVE_ADDR << 1 | 1);
|
||||
|
||||
i2c_operation_job_t i2c_ops[] = {
|
||||
{ .command = I2C_MASTER_CMD_START },
|
||||
{ .command = I2C_MASTER_CMD_WRITE, .write = { .ack_check = true, .data = (uint8_t *) &read_address, .total_bytes = 1 } },
|
||||
{ .command = I2C_MASTER_CMD_READ, .read = { .ack_value = I2C_NACK_VAL, .data = data_rd, .total_bytes = 1 }},
|
||||
{ .command = I2C_MASTER_CMD_STOP },
|
||||
};
|
||||
|
||||
i2c_master_execute_defined_operations(dev_handle, i2c_ops, sizeof(i2c_ops) / sizeof(i2c_operation_job_t), 1000);
|
||||
vTaskDelay(100 / portTICK_PERIOD_MS);
|
||||
TEST_ASSERT(data_rd[0] == 6);
|
||||
unity_send_signal("ready to delete master read test");
|
||||
|
||||
TEST_ESP_OK(i2c_master_bus_rm_device(dev_handle));
|
||||
TEST_ESP_OK(i2c_del_master_bus(bus_handle));
|
||||
}
|
||||
|
||||
static void slave_write_buffer_test_v2_single_byte(void)
|
||||
{
|
||||
i2c_slave_dev_handle_t handle;
|
||||
uint8_t data_wr[DATA_LENGTH];
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = ESP_SLAVE_ADDR,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
data_wr[0] = 6;
|
||||
|
||||
i2c_slave_event_t evt;
|
||||
uint32_t write_len;
|
||||
while (true) {
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_TX) {
|
||||
TEST_ESP_OK(i2c_slave_write(handle, data_wr, 1, &write_len, 1000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unity_wait_for_signal("ready to delete master read test");
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("I2C master read slave test single byte", "[i2c][test_env=generic_multi_device][timeout=150]", master_read_slave_test_v2_single_byte, slave_write_buffer_test_v2_single_byte);
|
||||
|
||||
#endif // SOC_I2C_SLAVE_CAN_GET_STRETCH_CAUSE
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@ -22,14 +22,26 @@
|
||||
|
||||
#define DATA_LENGTH 100
|
||||
|
||||
static QueueHandle_t s_receive_queue;
|
||||
static QueueHandle_t event_queue;
|
||||
static uint8_t *temp_data;
|
||||
static size_t temp_len = 0;
|
||||
|
||||
static IRAM_ATTR bool test_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data)
|
||||
static IRAM_ATTR bool i2c_slave_request_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_request_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t high_task_wakeup = pdFALSE;
|
||||
QueueHandle_t receive_queue = (QueueHandle_t)user_data;
|
||||
xQueueSendFromISR(receive_queue, edata, &high_task_wakeup);
|
||||
return high_task_wakeup == pdTRUE;
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_TX;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool i2c_slave_receive_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_rx_done_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_RX;
|
||||
memcpy(temp_data, evt_data->buffer, evt_data->length);
|
||||
temp_len = evt_data->length;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static void i2c_master_write_sleep_retention_test(void)
|
||||
@ -97,39 +109,44 @@ static void i2c_master_write_sleep_retention_test(void)
|
||||
|
||||
static void i2c_slave_read_sleep_retention_test(void)
|
||||
{
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
uint8_t data_rd2[DATA_LENGTH] = {0};
|
||||
event_queue = xQueueCreate(5, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
temp_data = heap_caps_malloc(DATA_LENGTH, MALLOC_CAP_DEFAULT);
|
||||
assert(temp_data);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = I2C_SLAVE_SCL_IO,
|
||||
.sda_io_num = I2C_SLAVE_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.flags.allow_pd = true,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = test_i2c_rx_done_callback,
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH));
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000));
|
||||
disp_buf(data_rd, DATA_LENGTH);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
i2c_slave_event_t evt;
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < temp_len; i++) {
|
||||
TEST_ASSERT(temp_data[i] == i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unity_send_signal("i2c slave receive once, master to sleep");
|
||||
@ -142,18 +159,21 @@ static void i2c_slave_read_sleep_retention_test(void)
|
||||
|
||||
unity_wait_for_signal("master sleep-wakeup");
|
||||
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd2, DATA_LENGTH));
|
||||
unity_send_signal("i2c slave receive again");
|
||||
|
||||
unity_wait_for_signal("master write again");
|
||||
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000));
|
||||
disp_buf(data_rd2, DATA_LENGTH);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd2[i] == i);
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < temp_len; i++) {
|
||||
TEST_ASSERT(temp_data[i] == i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vQueueDelete(s_receive_queue);
|
||||
vQueueDelete(event_queue);
|
||||
unity_send_signal("ready to delete");
|
||||
#if ESP_SLEEP_POWER_DOWN_CPU
|
||||
TEST_ESP_OK(sleep_cpu_configure(false));
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||
*/
|
||||
@ -24,7 +24,27 @@
|
||||
|
||||
#define DATA_LENGTH 100
|
||||
|
||||
static QueueHandle_t s_receive_queue;
|
||||
static QueueHandle_t event_queue;
|
||||
static uint8_t *temp_data;
|
||||
static size_t temp_len = 0;
|
||||
|
||||
static IRAM_ATTR bool i2c_slave_request_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_request_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_TX;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool i2c_slave_receive_cb(i2c_slave_dev_handle_t i2c_slave, const i2c_slave_rx_done_event_data_t *evt_data, void *arg)
|
||||
{
|
||||
BaseType_t xTaskWoken;
|
||||
i2c_slave_event_t evt = I2C_SLAVE_EVT_RX;
|
||||
memcpy(temp_data, evt_data->buffer, evt_data->length);
|
||||
temp_len = evt_data->length;
|
||||
xQueueSendFromISR(event_queue, &evt, &xTaskWoken);
|
||||
return xTaskWoken;
|
||||
}
|
||||
|
||||
TEST_CASE("LP I2C initialize on i2c slave", "[i2c]")
|
||||
{
|
||||
@ -74,14 +94,6 @@ TEST_CASE("LP I2C initialize with wrong clock source", "[i2c]")
|
||||
TEST_ESP_ERR(ESP_ERR_NOT_SUPPORTED, i2c_new_master_bus(&i2c_mst_config, &bus_handle));
|
||||
}
|
||||
|
||||
static IRAM_ATTR bool test_i2c_rx_done_callback(i2c_slave_dev_handle_t channel, const i2c_slave_rx_done_event_data_t *edata, void *user_data)
|
||||
{
|
||||
BaseType_t high_task_wakeup = pdFALSE;
|
||||
QueueHandle_t receive_queue = (QueueHandle_t)user_data;
|
||||
xQueueSendFromISR(receive_queue, edata, &high_task_wakeup);
|
||||
return high_task_wakeup == pdTRUE;
|
||||
}
|
||||
|
||||
static void lp_i2c_master_write_test(void)
|
||||
{
|
||||
uint8_t data_wr[DATA_LENGTH] = { 0 };
|
||||
@ -124,41 +136,51 @@ static void lp_i2c_master_write_test(void)
|
||||
|
||||
static void hp_i2c_slave_read_test(void)
|
||||
{
|
||||
uint8_t data_rd[DATA_LENGTH] = {0};
|
||||
i2c_slave_dev_handle_t handle;
|
||||
event_queue = xQueueCreate(2, sizeof(i2c_slave_event_t));
|
||||
assert(event_queue);
|
||||
temp_data = heap_caps_malloc(DATA_LENGTH, MALLOC_CAP_DEFAULT);
|
||||
assert(temp_data);
|
||||
|
||||
i2c_slave_config_t i2c_slv_config = {
|
||||
.addr_bit_len = I2C_ADDR_BIT_LEN_7,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.i2c_port = TEST_I2C_PORT,
|
||||
.send_buf_depth = 256,
|
||||
.clk_source = I2C_CLK_SRC_DEFAULT,
|
||||
.scl_io_num = LP_I2C_SCL_IO,
|
||||
.sda_io_num = LP_I2C_SDA_IO,
|
||||
.slave_addr = 0x58,
|
||||
.send_buf_depth = DATA_LENGTH,
|
||||
.receive_buf_depth = DATA_LENGTH,
|
||||
.flags.enable_internal_pullup = true,
|
||||
};
|
||||
|
||||
i2c_slave_dev_handle_t slave_handle;
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &slave_handle));
|
||||
TEST_ESP_OK(i2c_new_slave_device(&i2c_slv_config, &handle));
|
||||
|
||||
s_receive_queue = xQueueCreate(1, sizeof(i2c_slave_rx_done_event_data_t));
|
||||
i2c_slave_event_callbacks_t cbs = {
|
||||
.on_recv_done = test_i2c_rx_done_callback,
|
||||
.on_receive = i2c_slave_receive_cb,
|
||||
.on_request = i2c_slave_request_cb,
|
||||
};
|
||||
ESP_ERROR_CHECK(i2c_slave_register_event_callbacks(slave_handle, &cbs, s_receive_queue));
|
||||
|
||||
i2c_slave_rx_done_event_data_t rx_data;
|
||||
TEST_ESP_OK(i2c_slave_receive(slave_handle, data_rd, DATA_LENGTH));
|
||||
TEST_ESP_OK(i2c_slave_register_event_callbacks(handle, &cbs, NULL));
|
||||
|
||||
unity_send_signal("i2c slave init finish");
|
||||
|
||||
unity_wait_for_signal("master write");
|
||||
xQueueReceive(s_receive_queue, &rx_data, pdMS_TO_TICKS(10000));
|
||||
disp_buf(data_rd, DATA_LENGTH);
|
||||
for (int i = 0; i < DATA_LENGTH; i++) {
|
||||
TEST_ASSERT(data_rd[i] == i);
|
||||
|
||||
i2c_slave_event_t evt;
|
||||
if (xQueueReceive(event_queue, &evt, portMAX_DELAY) == pdTRUE) {
|
||||
if (evt == I2C_SLAVE_EVT_RX) {
|
||||
disp_buf(temp_data, temp_len);
|
||||
printf("length is %x\n", temp_len);
|
||||
for (int i = 0; i < temp_len; i++) {
|
||||
TEST_ASSERT(temp_data[i] == i);
|
||||
}
|
||||
vQueueDelete(s_receive_queue);
|
||||
}
|
||||
}
|
||||
|
||||
unity_send_signal("ready to delete");
|
||||
TEST_ESP_OK(i2c_del_slave_device(slave_handle));
|
||||
free(temp_data);
|
||||
vQueueDelete(event_queue);
|
||||
TEST_ESP_OK(i2c_del_slave_device(handle));
|
||||
}
|
||||
|
||||
TEST_CASE_MULTIPLE_DEVICES("LP_I2C master write slave test", "[i2c][test_env=generic_multi_device][timeout=150]", lp_i2c_master_write_test, hp_i2c_slave_read_test);
|
||||
|
@ -35,10 +35,6 @@ def test_i2c(dut: Dut) -> None:
|
||||
2,
|
||||
'iram_safe',
|
||||
),
|
||||
(
|
||||
2,
|
||||
'slave_v2',
|
||||
),
|
||||
],
|
||||
indirect=True,
|
||||
)
|
||||
|
@ -1 +0,0 @@
|
||||
CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2=y
|
@ -1,2 +1,3 @@
|
||||
CONFIG_FREERTOS_HZ=1000
|
||||
CONFIG_ESP_TASK_WDT=n
|
||||
CONFIG_ESP_TASK_WDT_INIT=n
|
||||
CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2=y
|
||||
|
@ -938,6 +938,7 @@ static inline void i2c_ll_enable_arbitration(i2c_dev_t *hw, bool enable_arbi)
|
||||
* @param hw Beginning address of the peripheral registers
|
||||
* @param slv_ex_auto_en 1 if slave auto start data transaction, otherwise, 0.
|
||||
*/
|
||||
__attribute__((always_inline))
|
||||
static inline void i2c_ll_slave_enable_auto_start(i2c_dev_t *hw, bool slv_ex_auto_en)
|
||||
{
|
||||
hw->ctr.slv_tx_auto_start_en = slv_ex_auto_en;
|
||||
|
Reference in New Issue
Block a user