| /* |
| * Copyright (c) 2017 BayLibre, SAS |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <errno.h> |
| #include <string.h> |
| |
| #define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG |
| #include <logging/sys_log.h> |
| |
| #include <zephyr.h> |
| #include <device.h> |
| #include <stdio.h> |
| #include <misc/util.h> |
| |
| #include <i2c.h> |
| #include <drivers/i2c/slave/eeprom.h> |
| |
| #include <ztest.h> |
| |
| #define TEST_DATA_SIZE 20 |
| |
| static u8_t eeprom_0_data[TEST_DATA_SIZE] = "0123456789abcdefghij"; |
| static u8_t eeprom_1_data[TEST_DATA_SIZE] = "jihgfedcba9876543210"; |
| static u8_t i2c_buffer[TEST_DATA_SIZE]; |
| |
| /* |
| * We need 5x(buffer size) + 1 to print a comma-separated list of each |
| * byte in hex, plus a null. |
| */ |
| u8_t buffer_print_eeprom[TEST_DATA_SIZE * 5 + 1]; |
| u8_t buffer_print_i2c[TEST_DATA_SIZE * 5 + 1]; |
| |
| static void to_display_format(const u8_t *src, size_t size, char *dst) |
| { |
| size_t i; |
| |
| for (i = 0; i < size; i++) { |
| sprintf(dst + 5 * i, "0x%02x,", src[i]); |
| } |
| } |
| |
| static void run_full_read(struct device *i2c, u8_t addr, u8_t *comp_buffer) |
| { |
| int ret; |
| |
| SYS_LOG_INF("Start full read. Master: %s, address: 0x%x", |
| i2c->config->name, addr); |
| |
| /* Read EEPROM from I2C Master requests, then compare */ |
| ret = i2c_burst_read(i2c, addr, |
| 0, i2c_buffer, TEST_DATA_SIZE); |
| zassert_equal(ret, 0, "Failed to read EEPROM"); |
| |
| if (memcmp(i2c_buffer, comp_buffer, TEST_DATA_SIZE)) { |
| to_display_format(i2c_buffer, TEST_DATA_SIZE, |
| buffer_print_i2c); |
| to_display_format(comp_buffer, TEST_DATA_SIZE, |
| buffer_print_eeprom); |
| SYS_LOG_ERR("Buffer contents are different: %s", |
| buffer_print_i2c); |
| SYS_LOG_ERR(" vs: %s", |
| buffer_print_eeprom); |
| |
| ztest_test_fail(); |
| } |
| } |
| |
| static void run_partial_read(struct device *i2c, u8_t addr, u8_t *comp_buffer, |
| unsigned int offset) |
| { |
| int ret; |
| |
| SYS_LOG_INF("Start partial read. Master: %s, address: 0x%x, off=%d", |
| i2c->config->name, addr, offset); |
| |
| ret = i2c_burst_read(i2c, addr, |
| offset, i2c_buffer, TEST_DATA_SIZE-offset); |
| zassert_equal(ret, 0, "Failed to read EEPROM"); |
| |
| if (memcmp(i2c_buffer, &comp_buffer[offset], TEST_DATA_SIZE-offset)) { |
| to_display_format(i2c_buffer, TEST_DATA_SIZE-offset, |
| buffer_print_i2c); |
| to_display_format(&comp_buffer[offset], TEST_DATA_SIZE-offset, |
| buffer_print_eeprom); |
| SYS_LOG_ERR("Buffer contents are different: %s", |
| buffer_print_i2c); |
| SYS_LOG_ERR(" vs: %s", |
| buffer_print_eeprom); |
| |
| ztest_test_fail(); |
| } |
| } |
| |
| static void run_program_read(struct device *i2c, u8_t addr, unsigned int offset) |
| { |
| int ret, i; |
| |
| SYS_LOG_INF("Start program. Master: %s, address: 0x%x, off=%d", |
| i2c->config->name, addr, offset); |
| |
| for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) { |
| i2c_buffer[i] = i; |
| } |
| |
| ret = i2c_burst_write(i2c, addr, |
| offset, i2c_buffer, TEST_DATA_SIZE-offset); |
| zassert_equal(ret, 0, "Failed to write EEPROM"); |
| |
| memset(i2c_buffer, 0xFF, TEST_DATA_SIZE); |
| |
| /* Read back EEPROM from I2C Master requests, then compare */ |
| ret = i2c_burst_read(i2c, addr, |
| offset, i2c_buffer, TEST_DATA_SIZE-offset); |
| zassert_equal(ret, 0, "Failed to read EEPROM"); |
| |
| for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) { |
| if (i2c_buffer[i] != i) { |
| to_display_format(i2c_buffer, TEST_DATA_SIZE-offset, |
| buffer_print_i2c); |
| SYS_LOG_ERR("Invalid Buffer content: %s", |
| buffer_print_i2c); |
| |
| ztest_test_fail(); |
| } |
| } |
| } |
| |
| void test_eeprom_slave(void) |
| { |
| struct device *eeprom_0; |
| struct device *eeprom_1; |
| struct device *i2c_0; |
| struct device *i2c_1; |
| int ret, offset; |
| |
| i2c_0 = device_get_binding( |
| CONFIG_I2C_EEPROM_SLAVE_0_CONTROLLER_DEV_NAME); |
| zassert_not_null(i2c_0, "I2C device %s not found", |
| CONFIG_I2C_EEPROM_SLAVE_0_CONTROLLER_DEV_NAME); |
| |
| SYS_LOG_INF("Found I2C Master device %s", |
| CONFIG_I2C_EEPROM_SLAVE_0_CONTROLLER_DEV_NAME); |
| |
| i2c_1 = device_get_binding( |
| CONFIG_I2C_EEPROM_SLAVE_1_CONTROLLER_DEV_NAME); |
| zassert_not_null(i2c_1, "I2C device %s not found", |
| CONFIG_I2C_EEPROM_SLAVE_1_CONTROLLER_DEV_NAME); |
| |
| SYS_LOG_INF("Found I2C Master device %s", |
| CONFIG_I2C_EEPROM_SLAVE_1_CONTROLLER_DEV_NAME); |
| |
| eeprom_0 = device_get_binding(CONFIG_I2C_EEPROM_SLAVE_0_NAME); |
| zassert_not_null(eeprom_0, "EEPROM device %s not found", |
| CONFIG_I2C_EEPROM_SLAVE_0_NAME); |
| |
| SYS_LOG_INF("Found EEPROM device %s", CONFIG_I2C_EEPROM_SLAVE_0_NAME); |
| |
| eeprom_1 = device_get_binding(CONFIG_I2C_EEPROM_SLAVE_1_NAME); |
| zassert_not_null(eeprom_1, "EEPROM device %s not found", |
| CONFIG_I2C_EEPROM_SLAVE_1_NAME); |
| |
| SYS_LOG_INF("Found EEPROM device %s", CONFIG_I2C_EEPROM_SLAVE_1_NAME); |
| |
| /* Program dummy bytes */ |
| ret = eeprom_slave_program(eeprom_0, eeprom_0_data, TEST_DATA_SIZE); |
| zassert_equal(ret, 0, "Failed to program EEPROM %s", |
| CONFIG_I2C_EEPROM_SLAVE_0_NAME); |
| |
| ret = eeprom_slave_program(eeprom_1, eeprom_1_data, TEST_DATA_SIZE); |
| zassert_equal(ret, 0, "Failed to program EEPROM %s", |
| CONFIG_I2C_EEPROM_SLAVE_1_NAME); |
| |
| /* Attach EEPROM */ |
| ret = i2c_slave_driver_register(eeprom_0); |
| zassert_equal(ret, 0, "Failed to register EEPROM %s", |
| CONFIG_I2C_EEPROM_SLAVE_0_NAME); |
| |
| SYS_LOG_INF("EEPROM %s Attached !", CONFIG_I2C_EEPROM_SLAVE_0_NAME); |
| |
| ret = i2c_slave_driver_register(eeprom_1); |
| zassert_equal(ret, 0, "Failed to register EEPROM %s", |
| CONFIG_I2C_EEPROM_SLAVE_1_NAME); |
| |
| SYS_LOG_INF("EEPROM %s Attached !", CONFIG_I2C_EEPROM_SLAVE_1_NAME); |
| |
| /* Run Tests without bus access conflicts */ |
| run_full_read(i2c_0, CONFIG_I2C_EEPROM_SLAVE_1_ADDRESS, eeprom_1_data); |
| run_full_read(i2c_1, CONFIG_I2C_EEPROM_SLAVE_0_ADDRESS, eeprom_0_data); |
| |
| for (offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) { |
| run_partial_read(i2c_0, CONFIG_I2C_EEPROM_SLAVE_1_ADDRESS, |
| eeprom_1_data, offset); |
| } |
| |
| for (offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) { |
| run_partial_read(i2c_1, CONFIG_I2C_EEPROM_SLAVE_0_ADDRESS, |
| eeprom_0_data, offset); |
| } |
| |
| for (offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) { |
| run_program_read(i2c_0, CONFIG_I2C_EEPROM_SLAVE_1_ADDRESS, |
| offset); |
| } |
| |
| for (offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) { |
| run_program_read(i2c_1, CONFIG_I2C_EEPROM_SLAVE_0_ADDRESS, |
| offset); |
| } |
| |
| SYS_LOG_INF("Success !"); |
| |
| /* Detach EEPROM */ |
| ret = i2c_slave_driver_unregister(eeprom_0); |
| zassert_equal(ret, 0, "Failed to unregister EEPROM %s", |
| CONFIG_I2C_EEPROM_SLAVE_0_NAME); |
| |
| SYS_LOG_INF("EEPROM %s Detached !", |
| CONFIG_I2C_EEPROM_SLAVE_0_NAME); |
| |
| ret = i2c_slave_driver_unregister(eeprom_1); |
| zassert_equal(ret, 0, "Failed to unregister EEPROM %s", |
| CONFIG_I2C_EEPROM_SLAVE_1_NAME); |
| |
| SYS_LOG_INF("EEPROM %s Detached !", |
| CONFIG_I2C_EEPROM_SLAVE_1_NAME); |
| } |
| |
| void test_main(void) |
| { |
| ztest_test_suite(test_eeprom_slave, ztest_unit_test(test_eeprom_slave)); |
| ztest_run_test_suite(test_eeprom_slave); |
| } |