/** * test environment UT_T2_I2C: * please prepare two ESP32-WROVER-KIT board. * Then connect GPIO18 and GPIO18, GPIO19 and GPIO19 between these two boards. */ #include #include #include "unity.h" #include "test_utils.h" #include "unity_config.h" #include "driver/i2c.h" #include "esp_attr.h" #include "esp_log.h" #include "soc/gpio_periph.h" #include "soc/i2c_periph.h" #include "esp_system.h" #include "driver/pcnt.h" #define DATA_LENGTH 512 /*!ctr.ms_mode, 1); TEST_ESP_OK(i2c_driver_delete(I2C_MASTER_NUM)); } } // slave test i2c_config_t conf_slave = i2c_slave_init(); for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { conf_slave.sda_pullup_en = sda_pull_up_en[i]; conf_slave.scl_pullup_en = scl_pull_up_en[j]; TEST_ESP_OK(i2c_driver_install(I2C_SLAVE_NUM, I2C_MODE_SLAVE, I2C_SLAVE_RX_BUF_LEN, I2C_SLAVE_TX_BUF_LEN, 0)); TEST_ESP_OK(i2c_param_config( I2C_SLAVE_NUM, &conf_slave)); TEST_ASSERT_EQUAL_INT32(I2C[I2C_SLAVE_NUM] -> ctr.ms_mode, 0); TEST_ESP_OK(i2c_driver_delete(I2C_SLAVE_NUM)); } } } TEST_CASE("I2C set and get period test", "[i2c]") { int high_period, low_period; i2c_config_t conf_master = i2c_master_init(); TEST_ESP_OK(i2c_driver_install(I2C_MASTER_NUM, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0)); TEST_ESP_OK(i2c_param_config(I2C_MASTER_NUM, &conf_master)); TEST_ESP_OK(i2c_set_period(I2C_MASTER_NUM, I2C_SCL_HIGH_PERIOD_V, I2C_SCL_HIGH_PERIOD_V)); TEST_ESP_OK(i2c_get_period(I2C_MASTER_NUM, &high_period, &low_period)); TEST_ASSERT_EQUAL_INT(I2C_SCL_HIGH_PERIOD_V, high_period); TEST_ASSERT_EQUAL_INT(I2C_SCL_HIGH_PERIOD_V, low_period); TEST_ASSERT_NOT_NULL((void *)i2c_set_period(I2C_MASTER_NUM, I2C_SCL_HIGH_PERIOD_V + 1, I2C_SCL_HIGH_PERIOD_V + 1)); TEST_ESP_OK(i2c_set_period(I2C_MASTER_NUM, 300, 400)); TEST_ESP_OK(i2c_get_period(I2C_MASTER_NUM, &high_period, &low_period)); TEST_ASSERT_EQUAL_INT(300, high_period); TEST_ASSERT_EQUAL_INT(400, low_period); TEST_ESP_OK(i2c_driver_delete(I2C_MASTER_NUM)); } TEST_CASE("I2C config FIFO test", "[i2c]") { i2c_config_t conf_slave = i2c_slave_init(); TEST_ESP_OK(i2c_driver_install(I2C_SLAVE_NUM, I2C_MODE_SLAVE, I2C_SLAVE_RX_BUF_LEN, I2C_SLAVE_TX_BUF_LEN, 0)); TEST_ESP_OK(i2c_param_config( I2C_SLAVE_NUM, &conf_slave)); TEST_ASSERT_BIT_LOW(1, I2C[I2C_SLAVE_NUM]->fifo_conf.tx_fifo_rst); TEST_ESP_OK(i2c_reset_tx_fifo(I2C_SLAVE_NUM)); TEST_ASSERT_BIT_LOW(0, I2C[I2C_SLAVE_NUM]->fifo_conf.tx_fifo_rst); TEST_ESP_OK(i2c_reset_rx_fifo(I2C_SLAVE_NUM)); TEST_ASSERT_BIT_LOW(0, I2C[I2C_SLAVE_NUM]->fifo_conf.rx_fifo_rst); TEST_ESP_OK(i2c_driver_delete(I2C_SLAVE_NUM)); } TEST_CASE("I2C timing test", "[i2c]") { int test_setup_time, test_data_time, test_stop_time, test_hold_time; uint8_t *data_wr = (uint8_t *) malloc(DATA_LENGTH); i2c_config_t conf_master = i2c_master_init(); TEST_ESP_OK(i2c_driver_install(I2C_MASTER_NUM, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0)); TEST_ESP_OK(i2c_param_config(I2C_MASTER_NUM, &conf_master)); TEST_ESP_OK(i2c_set_start_timing(I2C_MASTER_NUM, 50, 60)); TEST_ESP_OK(i2c_set_data_timing(I2C_MASTER_NUM, 80, 60)); TEST_ESP_OK(i2c_set_stop_timing(I2C_MASTER_NUM, 100, 60)); for (int i = 0; i < DATA_LENGTH; i++) { data_wr[i] = i; } i2c_master_write_slave(I2C_MASTER_NUM, data_wr, RW_TEST_LENGTH); TEST_ESP_OK(i2c_get_start_timing(I2C_MASTER_NUM, &test_setup_time, &test_hold_time)); TEST_ESP_OK(i2c_get_data_timing(I2C_MASTER_NUM, &test_data_time, &test_hold_time)); TEST_ESP_OK(i2c_get_stop_timing(I2C_MASTER_NUM, &test_stop_time, &test_hold_time)); TEST_ASSERT_EQUAL_INT32(50, test_setup_time); TEST_ASSERT_EQUAL_INT32(80, test_data_time); TEST_ASSERT_EQUAL_INT32(100, test_stop_time); TEST_ASSERT_EQUAL_INT32(60, test_hold_time); free(data_wr); i2c_driver_delete(I2C_MASTER_NUM); } TEST_CASE("I2C data mode test", "[i2c]") { uint8_t *data_wr = (uint8_t *) malloc(DATA_LENGTH); i2c_trans_mode_t test_tx_trans_mode, test_rx_trans_mode; i2c_config_t conf_master = i2c_master_init(); TEST_ESP_OK(i2c_driver_install(I2C_MASTER_NUM, I2C_MODE_MASTER, I2C_MASTER_RX_BUF_DISABLE, I2C_MASTER_TX_BUF_DISABLE, 0)); TEST_ESP_OK(i2c_param_config(I2C_MASTER_NUM, &conf_master)); for (int i = 0; i < DATA_LENGTH; i++) { data_wr[i] = i; } TEST_ESP_OK(i2c_set_data_mode(I2C_MASTER_NUM, I2C_DATA_MODE_LSB_FIRST, I2C_DATA_MODE_LSB_FIRST)); TEST_ESP_OK(i2c_get_data_mode(I2C_MASTER_NUM, &test_tx_trans_mode, &test_rx_trans_mode)); TEST_ASSERT_EQUAL_INT(I2C_DATA_MODE_LSB_FIRST, test_tx_trans_mode); TEST_ASSERT_EQUAL_INT(I2C_DATA_MODE_LSB_FIRST, test_rx_trans_mode); i2c_master_write_slave(I2C_MASTER_NUM, data_wr, RW_TEST_LENGTH); TEST_ESP_OK(i2c_set_data_mode(I2C_MASTER_NUM, I2C_DATA_MODE_MSB_FIRST, I2C_DATA_MODE_MSB_FIRST)); TEST_ESP_OK(i2c_get_data_mode(I2C_MASTER_NUM, &test_tx_trans_mode, &test_rx_trans_mode)); TEST_ASSERT_EQUAL_INT(I2C_DATA_MODE_MSB_FIRST, test_tx_trans_mode); TEST_ASSERT_EQUAL_INT(I2C_DATA_MODE_MSB_FIRST, test_rx_trans_mode); i2c_master_write_slave(I2C_MASTER_NUM, data_wr, RW_TEST_LENGTH); free(data_wr); i2c_driver_delete(I2C_MASTER_NUM); } TEST_CASE("I2C driver memory leaking check", "[i2c]") { esp_err_t ret; int size = esp_get_free_heap_size(); for (uint32_t i = 0; i <= 1000; i++) { ret = i2c_driver_install(I2C_SLAVE_NUM, I2C_MODE_SLAVE, I2C_SLAVE_RX_BUF_LEN, I2C_SLAVE_TX_BUF_LEN, 0); TEST_ASSERT(ret == ESP_OK); vTaskDelay(10 / portTICK_RATE_MS); i2c_driver_delete(I2C_SLAVE_NUM); TEST_ASSERT(ret == ESP_OK); } TEST_ASSERT_INT_WITHIN(100, size, esp_get_free_heap_size()); } static volatile bool exit_flag; static bool test_read_func; static void test_task(void *pvParameters) { xSemaphoreHandle *sema = (xSemaphoreHandle *) pvParameters; uint8_t *data = (uint8_t *) malloc(DATA_LENGTH); i2c_config_t conf_slave = i2c_slave_init(); TEST_ESP_OK(i2c_driver_install(I2C_SLAVE_NUM, I2C_MODE_SLAVE, I2C_SLAVE_RX_BUF_LEN, I2C_SLAVE_TX_BUF_LEN, 0)); TEST_ESP_OK(i2c_param_config( I2C_SLAVE_NUM, &conf_slave)); while (exit_flag == false) { if (test_read_func) { i2c_slave_read_buffer(I2C_SLAVE_NUM, data, DATA_LENGTH, 0); } else { i2c_slave_write_buffer(I2C_SLAVE_NUM, data, DATA_LENGTH, 0); } vTaskDelay(10/portTICK_RATE_MS); } free(data); xSemaphoreGive(*sema); vTaskDelete(NULL); } TEST_CASE("test i2c_slave_read_buffer is not blocked when ticks_to_wait=0", "[i2c]") { xSemaphoreHandle exit_sema = xSemaphoreCreateBinary(); exit_flag = false; test_read_func = true; xTaskCreate(test_task, "tsk1", 2048, &exit_sema, 5, NULL); printf("Waiting for 5 sec\n"); vTaskDelay(5000 / portTICK_PERIOD_MS); exit_flag = true; if (xSemaphoreTake(exit_sema, 1000 / portTICK_PERIOD_MS) == pdTRUE) { vSemaphoreDelete(exit_sema); } else { TEST_FAIL_MESSAGE("i2c_slave_read_buffer is blocked"); } TEST_ESP_OK(i2c_driver_delete(I2C_SLAVE_NUM)); } TEST_CASE("test i2c_slave_write_buffer is not blocked when ticks_to_wait=0", "[i2c]") { xSemaphoreHandle exit_sema = xSemaphoreCreateBinary(); exit_flag = false; test_read_func = false; xTaskCreate(test_task, "tsk1", 2048, &exit_sema, 5, NULL); printf("Waiting for 5 sec\n"); vTaskDelay(5000 / portTICK_PERIOD_MS); exit_flag = true; if (xSemaphoreTake(exit_sema, 1000 / portTICK_PERIOD_MS) == pdTRUE) { vSemaphoreDelete(exit_sema); } else { TEST_FAIL_MESSAGE("i2c_slave_write_buffer is blocked"); } TEST_ESP_OK(i2c_driver_delete(I2C_SLAVE_NUM)); }