diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/CMakeLists.txt b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/CMakeLists.txt index a01ff056e7..9a5253696b 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/CMakeLists.txt +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/CMakeLists.txt @@ -2,35 +2,27 @@ 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() - list(APPEND srcs "test_i2c_multi.c") +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_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) + list(APPEND srcs "test_i2c_10bit.c") + endif() - if(CONFIG_SOC_I2C_SUPPORT_10BIT_ADDR AND CONFIG_SOC_I2C_SUPPORT_SLAVE) - list(APPEND srcs "test_i2c_10bit.c") - endif() + if(CONFIG_SOC_LP_I2C_SUPPORTED) + list(APPEND srcs "test_lp_i2c.c") + endif() - if(CONFIG_SOC_LP_I2C_SUPPORTED) - list(APPEND srcs "test_lp_i2c.c") - endif() + if(CONFIG_SOC_I2C_SUPPORT_SLEEP_RETENTION) + list(APPEND srcs "test_i2c_sleep_retention.c") + endif() - if(CONFIG_SOC_I2C_SUPPORT_SLEEP_RETENTION) - list(APPEND srcs "test_i2c_sleep_retention.c") - endif() - - if(CONFIG_I2C_ISR_IRAM_SAFE) - list(APPEND srcs "test_i2c_iram.c") - endif() + if(CONFIG_I2C_ISR_IRAM_SAFE) + list(APPEND srcs "test_i2c_iram.c") endif() endif() diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_board.h b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_board.h index 14503d15f7..6890bcd6ce 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_board.h +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_board.h @@ -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 * diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_10bit.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_10bit.c index df1e4f0fc3..8b29b16c64 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_10bit.c +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_10bit.c @@ -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); diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_broadcast.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_broadcast.c index d2bda33f71..5189fcd838 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_broadcast.c +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_broadcast.c @@ -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); diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c index ad79ccbac9..ac1eedc533 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_common.c @@ -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 diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_iram.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_iram.c index e7069e8ade..3b063cda68 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_iram.c +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_iram.c @@ -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); diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_multi.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_multi.c index 01044ffcad..a90d8e9bf2 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_multi.c +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_multi.c @@ -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}; + 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_send_signal("ready to delete"); - vQueueDelete(s_receive_queue); - TEST_ESP_OK(i2c_del_slave_device(slave_handle)); + + 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 read and write test", "[i2c][test_env=generic_multi_device][timeout=150]", i2c_master_write_read_test, i2c_slave_read_write_test); +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"); + free(temp_data); + vQueueDelete(event_queue); + TEST_ESP_OK(i2c_del_slave_device(handle)); +} static void i2c_master_repeat_write(void) { - uint8_t data_wr[DATA_LENGTH] = {0}; + 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); - 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 < DATA_LENGTH; i++) { + TEST_ASSERT(temp_data[i] == i); + } + for (int i = DATA_LENGTH; i < DATA_LENGTH * 2; i++) { + TEST_ASSERT(temp_data[i] == ((i - DATA_LENGTH) + 0x05)); + } + for (int i = DATA_LENGTH * 2; i < DATA_LENGTH * 3; i++) { + TEST_ASSERT(temp_data[i] == ((i - DATA_LENGTH * 2) + 0x0f)); + } + } } - for (int i = DATA_LENGTH; i < DATA_LENGTH * 2; i++) { - TEST_ASSERT(data_rd[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)); - } - 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); diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_ram.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_ram.c deleted file mode 100644 index 1789f449b4..0000000000 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_ram.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ - -#include -#include -#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)); -} diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_slave_v2.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_slave_v2.c deleted file mode 100644 index eb15876a33..0000000000 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_slave_v2.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Unlicense OR CC0-1.0 - */ -#include -#include -#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 diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_sleep_retention.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_sleep_retention.c index 845791cfed..19d17279c4 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_sleep_retention.c +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_i2c_sleep_retention.c @@ -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)); diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_lp_i2c.c b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_lp_i2c.c index 6cf9711004..d9d691fc6b 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_lp_i2c.c +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/main/test_lp_i2c.c @@ -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); diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py b/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py index eaf1f87d0d..65ddbca3ab 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/pytest_i2c.py @@ -35,10 +35,6 @@ def test_i2c(dut: Dut) -> None: 2, 'iram_safe', ), - ( - 2, - 'slave_v2', - ), ], indirect=True, ) diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.slave_v2 b/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.slave_v2 deleted file mode 100644 index e0e63260b9..0000000000 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.ci.slave_v2 +++ /dev/null @@ -1 +0,0 @@ -CONFIG_I2C_ENABLE_SLAVE_DRIVER_VERSION_2=y diff --git a/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.defaults b/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.defaults index b308cb2ddd..bef587c1d3 100644 --- a/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.defaults +++ b/components/esp_driver_i2c/test_apps/i2c_test_apps/sdkconfig.defaults @@ -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 diff --git a/components/hal/esp32c5/include/hal/i2c_ll.h b/components/hal/esp32c5/include/hal/i2c_ll.h index f16ddb1676..73d8be5a36 100644 --- a/components/hal/esp32c5/include/hal/i2c_ll.h +++ b/components/hal/esp32c5/include/hal/i2c_ll.h @@ -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;