|
| 1 | +/* |
| 2 | + * Copyright (c) 2017 BayLibre, SAS |
| 3 | + * |
| 4 | + * SPDX-License-Identifier: Apache-2.0 |
| 5 | + */ |
| 6 | + |
| 7 | +#include <errno.h> |
| 8 | +#include <string.h> |
| 9 | + |
| 10 | +#define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG |
| 11 | +#include <logging/sys_log.h> |
| 12 | + |
| 13 | +#include <zephyr.h> |
| 14 | +#include <device.h> |
| 15 | +#include <stdio.h> |
| 16 | +#include <misc/util.h> |
| 17 | + |
| 18 | +#include <i2c.h> |
| 19 | +#include <drivers/i2c/slave_eeprom.h> |
| 20 | + |
| 21 | +#define TEST_DATA_SIZE 20 |
| 22 | + |
| 23 | +static u8_t eeprom_data[TEST_DATA_SIZE] = "0123456789abcdefghij"; |
| 24 | +static u8_t i2c_buffer[TEST_DATA_SIZE]; |
| 25 | + |
| 26 | +/* |
| 27 | + * We need 5x(buffer size) + 1 to print a comma-separated list of each |
| 28 | + * byte in hex, plus a null. |
| 29 | + */ |
| 30 | +u8_t buffer_print_eeprom[TEST_DATA_SIZE * 5 + 1]; |
| 31 | +u8_t buffer_print_i2c[TEST_DATA_SIZE * 5 + 1]; |
| 32 | + |
| 33 | +static void to_display_format(const u8_t *src, size_t size, char *dst) |
| 34 | +{ |
| 35 | + size_t i; |
| 36 | + |
| 37 | + for (i = 0; i < size; i++) { |
| 38 | + sprintf(dst + 5 * i, "0x%02x,", src[i]); |
| 39 | + } |
| 40 | +} |
| 41 | + |
| 42 | +#define I2C_MASTER_DEV_NAME "I2C_2" |
| 43 | + |
| 44 | +static int run_full_read(struct device *i2c) |
| 45 | +{ |
| 46 | + int ret; |
| 47 | + |
| 48 | + SYS_LOG_INF("Start full read from EEPROM"); |
| 49 | + |
| 50 | + /* Read EEPROM from I2C Master requests, then compare */ |
| 51 | + ret = i2c_burst_read(i2c, CONFIG_I2C_SLAVE_EEPROM_ADDRESS, |
| 52 | + 0, i2c_buffer, TEST_DATA_SIZE); |
| 53 | + if (ret) { |
| 54 | + SYS_LOG_ERR("Failed to read EEPROM Code %d", ret); |
| 55 | + return -1; |
| 56 | + } |
| 57 | + |
| 58 | + if (memcmp(i2c_buffer, eeprom_data, TEST_DATA_SIZE)) { |
| 59 | + to_display_format(i2c_buffer, TEST_DATA_SIZE, |
| 60 | + buffer_print_i2c); |
| 61 | + to_display_format(eeprom_data, TEST_DATA_SIZE, |
| 62 | + buffer_print_eeprom); |
| 63 | + SYS_LOG_ERR("Buffer contents are different: %s", |
| 64 | + buffer_print_i2c); |
| 65 | + SYS_LOG_ERR(" vs: %s", |
| 66 | + buffer_print_eeprom); |
| 67 | + return -1; |
| 68 | + } |
| 69 | + |
| 70 | + return 0; |
| 71 | +} |
| 72 | + |
| 73 | +static int run_partial_read(struct device *i2c, unsigned int offset) |
| 74 | +{ |
| 75 | + int ret; |
| 76 | + |
| 77 | + SYS_LOG_INF("Start partial read from EEPROM (off=%d)", offset); |
| 78 | + |
| 79 | + ret = i2c_burst_read(i2c, CONFIG_I2C_SLAVE_EEPROM_ADDRESS, |
| 80 | + offset, i2c_buffer, TEST_DATA_SIZE-offset); |
| 81 | + if (ret) { |
| 82 | + SYS_LOG_ERR("Failed to read EEPROM Code %d", ret); |
| 83 | + return -1; |
| 84 | + } |
| 85 | + |
| 86 | + if (memcmp(i2c_buffer, &eeprom_data[offset], TEST_DATA_SIZE-offset)) { |
| 87 | + to_display_format(i2c_buffer, TEST_DATA_SIZE-offset, |
| 88 | + buffer_print_i2c); |
| 89 | + to_display_format(&eeprom_data[offset], TEST_DATA_SIZE-offset, |
| 90 | + buffer_print_eeprom); |
| 91 | + SYS_LOG_ERR("Buffer contents are different: %s", |
| 92 | + buffer_print_i2c); |
| 93 | + SYS_LOG_ERR(" vs: %s", |
| 94 | + buffer_print_eeprom); |
| 95 | + return -1; |
| 96 | + } |
| 97 | + |
| 98 | + return 0; |
| 99 | +} |
| 100 | + |
| 101 | +static int run_program_read(struct device *i2c, unsigned int offset) |
| 102 | +{ |
| 103 | + int ret, i; |
| 104 | + |
| 105 | + SYS_LOG_INF("Start program of EEPROM (off=%d)", offset); |
| 106 | + |
| 107 | + for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) |
| 108 | + i2c_buffer[i] = i; |
| 109 | + |
| 110 | + ret = i2c_burst_write(i2c, CONFIG_I2C_SLAVE_EEPROM_ADDRESS, |
| 111 | + offset, i2c_buffer, TEST_DATA_SIZE-offset); |
| 112 | + |
| 113 | + if (ret) { |
| 114 | + SYS_LOG_ERR("Failed to write EEPROM Code %d", ret); |
| 115 | + return -1; |
| 116 | + } |
| 117 | + |
| 118 | + memset(i2c_buffer, 0xFF, TEST_DATA_SIZE); |
| 119 | + |
| 120 | + /* Read back EEPROM from I2C Master requests, then compare */ |
| 121 | + ret = i2c_burst_read(i2c, CONFIG_I2C_SLAVE_EEPROM_ADDRESS, |
| 122 | + offset, i2c_buffer, TEST_DATA_SIZE-offset); |
| 123 | + if (ret) { |
| 124 | + SYS_LOG_ERR("Failed to read EEPROM Code %d", ret); |
| 125 | + return -1; |
| 126 | + } |
| 127 | + |
| 128 | + for (i = 0 ; i < TEST_DATA_SIZE-offset ; ++i) { |
| 129 | + if (i2c_buffer[i] != i) { |
| 130 | + to_display_format(i2c_buffer, TEST_DATA_SIZE-offset, |
| 131 | + buffer_print_i2c); |
| 132 | + SYS_LOG_ERR("Invalid Buffer content: %s", |
| 133 | + buffer_print_i2c); |
| 134 | + return -1; |
| 135 | + } |
| 136 | + } |
| 137 | + |
| 138 | + return 0; |
| 139 | +} |
| 140 | + |
| 141 | +void main(void) |
| 142 | +{ |
| 143 | + struct device *eeprom; |
| 144 | + struct device *i2c; |
| 145 | + const struct eeprom_slave_api *funcs; |
| 146 | + int ret, offset; |
| 147 | + |
| 148 | + i2c = device_get_binding(I2C_MASTER_DEV_NAME); |
| 149 | + if (i2c) { |
| 150 | + SYS_LOG_INF("Found I2C device %s", I2C_MASTER_DEV_NAME); |
| 151 | + } else { |
| 152 | + SYS_LOG_ERR("I2C device %s not found", |
| 153 | + I2C_MASTER_DEV_NAME); |
| 154 | + return; |
| 155 | + } |
| 156 | + |
| 157 | + eeprom = device_get_binding(CONFIG_I2C_SLAVE_EEPROM_NAME); |
| 158 | + if (eeprom) { |
| 159 | + SYS_LOG_INF("Found EEPROM device %s", CONFIG_I2C_SLAVE_EEPROM_NAME); |
| 160 | + } else { |
| 161 | + SYS_LOG_ERR("EEPROM device %s not found", |
| 162 | + CONFIG_I2C_SLAVE_EEPROM_NAME); |
| 163 | + return; |
| 164 | + } |
| 165 | + |
| 166 | + /* Get EEPROM funcs to read/write the internal memory */ |
| 167 | + funcs = i2c_slave_driver_get_funcs(eeprom); |
| 168 | + if (!funcs) { |
| 169 | + SYS_LOG_ERR("Failed to get EEPROM funcs"); |
| 170 | + return; |
| 171 | + } |
| 172 | + |
| 173 | + /* Program dummy bytes */ |
| 174 | + ret = funcs->program(eeprom, eeprom_data, TEST_DATA_SIZE); |
| 175 | + if (ret) { |
| 176 | + SYS_LOG_ERR("Failed to program EEPROM"); |
| 177 | + return; |
| 178 | + } |
| 179 | + |
| 180 | + /* Attach EEPROM */ |
| 181 | + ret = i2c_slave_driver_attach(eeprom); |
| 182 | + if (ret) { |
| 183 | + SYS_LOG_ERR("Failed to attach EEPROM"); |
| 184 | + return; |
| 185 | + } |
| 186 | + |
| 187 | + SYS_LOG_INF("EEPROM Attached !"); |
| 188 | + |
| 189 | + if (run_full_read(i2c)) |
| 190 | + goto out; |
| 191 | + |
| 192 | + for(offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) |
| 193 | + if (run_partial_read(i2c, offset)) |
| 194 | + goto out; |
| 195 | + |
| 196 | + for(offset = 0 ; offset < TEST_DATA_SIZE-1 ; ++offset) |
| 197 | + if (run_program_read(i2c, offset)) |
| 198 | + goto out; |
| 199 | + |
| 200 | + SYS_LOG_INF("Success !"); |
| 201 | + |
| 202 | +out: |
| 203 | + /* Detach EEPROM */ |
| 204 | + ret = i2c_slave_driver_detach(eeprom); |
| 205 | + if (ret) { |
| 206 | + SYS_LOG_ERR("Failed to detach EEPROM"); |
| 207 | + } |
| 208 | + |
| 209 | + SYS_LOG_INF("EEPROM Detached !"); |
| 210 | + |
| 211 | + return; |
| 212 | +} |
0 commit comments