1 /*
2  * Copyright (c) 2019 Vestas Wind Systems A/S
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/eeprom.h>
9 #include <zephyr/ztest.h>
10 
11 /* There is no obvious way to pass this to tests, so use a global */
12 ZTEST_BMEM static const struct device *eeprom;
13 
14 /* Test retrieval of eeprom size */
ZTEST_USER(eeprom,test_size)15 ZTEST_USER(eeprom, test_size)
16 {
17 	size_t size;
18 
19 	size = eeprom_get_size(eeprom);
20 	zassert_not_equal(0, size, "Unexpected size of zero bytes");
21 }
22 
23 /* Test write outside eeprom area */
ZTEST_USER(eeprom,test_out_of_bounds)24 ZTEST_USER(eeprom, test_out_of_bounds)
25 {
26 	const uint8_t data[4] = { 0x01, 0x02, 0x03, 0x03 };
27 	size_t size;
28 	int rc;
29 
30 	size = eeprom_get_size(eeprom);
31 
32 	rc = eeprom_write(eeprom, size - 1, data, sizeof(data));
33 	zassert_equal(-EINVAL, rc, "Unexpected error code (%d)", rc);
34 }
35 
36 /* Test write and rewrite */
ZTEST_USER(eeprom,test_write_rewrite)37 ZTEST_USER(eeprom, test_write_rewrite)
38 {
39 	const uint8_t wr_buf1[4] = { 0xFF, 0xEE, 0xDD, 0xCC };
40 	const uint8_t wr_buf2[sizeof(wr_buf1)] = { 0xAA, 0xBB, 0xCC, 0xDD };
41 	uint8_t rd_buf[sizeof(wr_buf1)];
42 	size_t size;
43 	off_t address;
44 	int rc;
45 
46 	size = eeprom_get_size(eeprom);
47 
48 	address = 0;
49 	while (address < MIN(size, 16)) {
50 		rc = eeprom_write(eeprom, address, wr_buf1, sizeof(wr_buf1));
51 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
52 
53 		rc = eeprom_read(eeprom, address, rd_buf, sizeof(rd_buf));
54 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
55 
56 		rc = memcmp(wr_buf1, rd_buf, sizeof(wr_buf1));
57 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
58 
59 		address += sizeof(wr_buf1);
60 	}
61 
62 	address = 0;
63 	while (address < MIN(size, 16)) {
64 		rc = eeprom_write(eeprom, address, wr_buf2, sizeof(wr_buf2));
65 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
66 
67 		rc = eeprom_read(eeprom, address, rd_buf, sizeof(rd_buf));
68 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
69 
70 		rc = memcmp(wr_buf2, rd_buf, sizeof(wr_buf2));
71 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
72 
73 		address += sizeof(wr_buf2);
74 	}
75 }
76 
77 /* Test write at fixed address */
ZTEST_USER(eeprom,test_write_at_fixed_address)78 ZTEST_USER(eeprom, test_write_at_fixed_address)
79 {
80 	const uint8_t wr_buf1[4] = { 0xFF, 0xEE, 0xDD, 0xCC };
81 	uint8_t rd_buf[sizeof(wr_buf1)];
82 	size_t size;
83 	const off_t address = 0;
84 	int rc;
85 
86 	size = eeprom_get_size(eeprom);
87 
88 	for (int i = 0; i < 16; i++) {
89 		rc = eeprom_write(eeprom, address, wr_buf1, sizeof(wr_buf1));
90 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
91 
92 		rc = eeprom_read(eeprom, address, rd_buf, sizeof(rd_buf));
93 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
94 
95 		rc = memcmp(wr_buf1, rd_buf, sizeof(wr_buf1));
96 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
97 	}
98 }
99 
100 /* Test write one byte at a time */
ZTEST_USER(eeprom,test_write_byte)101 ZTEST_USER(eeprom, test_write_byte)
102 {
103 	const uint8_t wr = 0x00;
104 	uint8_t rd = 0xff;
105 	int rc;
106 
107 	for (off_t address = 0; address < 16; address++) {
108 		rc = eeprom_write(eeprom, address, &wr, 1);
109 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
110 
111 		rc = eeprom_read(eeprom, address, &rd, 1);
112 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
113 
114 		zassert_equal(wr - rd, rc, "Unexpected error code (%d)", rc);
115 	}
116 }
117 
118 /* Test write a pattern of bytes at increasing address */
ZTEST_USER(eeprom,test_write_at_increasing_address)119 ZTEST_USER(eeprom, test_write_at_increasing_address)
120 {
121 	const uint8_t wr_buf1[8] = {0xEE, 0xDD, 0xCC, 0xBB, 0xFF, 0xEE, 0xDD,
122 				    0xCC };
123 	uint8_t rd_buf[sizeof(wr_buf1)];
124 	int rc;
125 
126 	for (off_t address = 0; address < 4; address++) {
127 		rc = eeprom_write(eeprom, address, wr_buf1, sizeof(wr_buf1));
128 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
129 
130 		rc = eeprom_read(eeprom, address, rd_buf, sizeof(rd_buf));
131 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
132 
133 		rc = memcmp(wr_buf1, rd_buf, sizeof(wr_buf1));
134 		zassert_equal(0, rc, "Unexpected error code (%d)", rc);
135 	}
136 }
137 
138 /* Test writing zero length data */
ZTEST_USER(eeprom,test_zero_length_write)139 ZTEST_USER(eeprom, test_zero_length_write)
140 {
141 	const uint8_t wr_buf1[4] = { 0x10, 0x20, 0x30, 0x40 };
142 	const uint8_t wr_buf2[sizeof(wr_buf1)] = { 0xAA, 0xBB, 0xCC, 0xDD };
143 	uint8_t rd_buf[sizeof(wr_buf1)];
144 	int rc;
145 
146 	rc = eeprom_write(eeprom, 0, wr_buf1, sizeof(wr_buf1));
147 	zassert_equal(0, rc, "Unexpected error code (%d)", rc);
148 
149 	rc = eeprom_read(eeprom, 0, rd_buf, sizeof(rd_buf));
150 	zassert_equal(0, rc, "Unexpected error code (%d)", rc);
151 
152 	rc = memcmp(wr_buf1, rd_buf, sizeof(wr_buf1));
153 	zassert_equal(0, rc, "Unexpected error code (%d)", rc);
154 
155 	rc = eeprom_write(eeprom, 0, wr_buf2, 0);
156 	zassert_equal(0, rc, "Unexpected error code (%d)", rc);
157 
158 	rc = eeprom_read(eeprom, 0, rd_buf, sizeof(rd_buf));
159 	zassert_equal(0, rc, "Unexpected error code (%d)", rc);
160 
161 	rc = memcmp(wr_buf1, rd_buf, sizeof(wr_buf1));
162 	zassert_equal(0, rc, "Unexpected error code (%d)", rc);
163 }
164 
eeprom_setup(void)165 static void *eeprom_setup(void)
166 {
167 	zassert_true(device_is_ready(eeprom), "EEPROM device not ready");
168 
169 	return NULL;
170 }
171 
172 ZTEST_SUITE(eeprom, NULL, eeprom_setup, NULL, NULL, NULL);
173 
174 /* Run all of our tests on the given EEPROM device */
run_tests_on_eeprom(const struct device * dev)175 static void run_tests_on_eeprom(const struct device *dev)
176 {
177 	eeprom = dev;
178 
179 	printk("Running tests on device \"%s\"\n", eeprom->name);
180 	k_object_access_grant(eeprom, k_current_get());
181 	ztest_run_all(NULL, false, 1, 1);
182 }
183 
test_main(void)184 void test_main(void)
185 {
186 	run_tests_on_eeprom(DEVICE_DT_GET(DT_ALIAS(eeprom_0)));
187 
188 #if DT_NODE_HAS_STATUS(DT_ALIAS(eeprom_1), okay)
189 	run_tests_on_eeprom(DEVICE_DT_GET(DT_ALIAS(eeprom_1)));
190 #endif /* DT_NODE_HAS_STATUS(DT_ALIAS(eeprom_1), okay) */
191 
192 	ztest_verify_all_test_suites_ran();
193 }
194