1 // Copyright 2021 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 #include "pw_i2c/register_device.h"
15
16 #include <cstring>
17
18 #include "pw_assert/check.h"
19 #include "pw_bytes/byte_builder.h"
20 #include "pw_unit_test/framework.h"
21
22 namespace pw {
23 namespace i2c {
24 namespace {
25
26 using ::pw::Status;
27 using namespace std::literals::chrono_literals;
28
29 constexpr uint8_t kErrorValue = 0x11;
30 constexpr Address kTestDeviceAddress = Address::SevenBit<0x3F>();
31
32 constexpr chrono::SystemClock::duration kTimeout =
33 std::chrono::duration_cast<chrono::SystemClock::duration>(100ms);
34
35 // Default test object. Mimics closely to I2c devices.
36 class TestInitiator : public Initiator {
37 public:
TestInitiator()38 explicit TestInitiator() {}
39
GetWriteBuffer()40 ByteBuilder& GetWriteBuffer() { return write_buffer_; }
41
SetReadData(ByteSpan read_data)42 void SetReadData(ByteSpan read_data) {
43 read_buffer_.append(read_data.data(), read_data.size());
44 }
45
46 private:
DoWriteReadFor(Address,ConstByteSpan tx_data,ByteSpan rx_data,chrono::SystemClock::duration)47 Status DoWriteReadFor(Address,
48 ConstByteSpan tx_data,
49 ByteSpan rx_data,
50 chrono::SystemClock::duration) override {
51 // Write
52 if (!tx_data.empty()) {
53 write_buffer_.append(tx_data.data(), tx_data.size());
54 }
55
56 // Read
57 if (!rx_data.empty()) {
58 PW_CHECK_UINT_EQ(
59 read_buffer_.size(), rx_data.size(), "Buffer to read is too big");
60 for (uint32_t i = 0; i < rx_data.size(); i++) {
61 rx_data[i] = read_buffer_.data()[i];
62 }
63 }
64
65 return OkStatus();
66 }
67
68 ByteBuffer<10> write_buffer_;
69 ByteBuffer<10> read_buffer_;
70 };
71
TEST(RegisterDevice,Construction)72 TEST(RegisterDevice, Construction) {
73 TestInitiator initiator;
74 RegisterDevice device(initiator,
75 kTestDeviceAddress,
76 endian::little,
77 RegisterAddressSize::k1Byte);
78 }
79
TEST(RegisterDevice,WriteRegisters8With2RegistersAnd1ByteAddress)80 TEST(RegisterDevice, WriteRegisters8With2RegistersAnd1ByteAddress) {
81 TestInitiator initiator;
82 RegisterDevice device(initiator,
83 kTestDeviceAddress,
84 endian::little,
85 RegisterAddressSize::k1Byte);
86
87 std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
88 std::array<std::byte, 3> builder;
89 constexpr uint32_t kRegisterAddress = 0xAB;
90 EXPECT_EQ(
91 device.WriteRegisters(kRegisterAddress, register_data, builder, kTimeout),
92 pw::OkStatus());
93
94 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
95 EXPECT_EQ(sizeof(builder), test_device_builder.size());
96
97 // Check address.
98 EXPECT_EQ(kRegisterAddress,
99 static_cast<uint32_t>(test_device_builder.data()[0]));
100
101 // Check data.
102 constexpr uint32_t kAddressSize =
103 static_cast<uint32_t>(RegisterAddressSize::k1Byte);
104 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
105 EXPECT_EQ(register_data[i], test_device_builder.data()[i + kAddressSize]);
106 }
107 }
108
TEST(RegisterDevice,WriteRegisters8With2RegistersAnd2ByteAddress)109 TEST(RegisterDevice, WriteRegisters8With2RegistersAnd2ByteAddress) {
110 TestInitiator initiator;
111 RegisterDevice device(initiator,
112 kTestDeviceAddress,
113 endian::little,
114 RegisterAddressSize::k2Bytes);
115
116 constexpr uint32_t kRegisterAddress = 0x89AB;
117 std::byte register_data[2] = {std::byte{0xCD}, std::byte{0xEF}};
118 std::array<std::byte, 4> builder;
119 EXPECT_EQ(
120 device.WriteRegisters(kRegisterAddress, register_data, builder, kTimeout),
121 pw::OkStatus());
122
123 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
124 EXPECT_EQ(sizeof(builder), test_device_builder.size());
125
126 // Check address.
127 uint16_t kActualAddress;
128 std::memcpy(
129 &kActualAddress, test_device_builder.data(), sizeof(kActualAddress));
130 EXPECT_EQ(kRegisterAddress, kActualAddress);
131
132 // Check data.
133 constexpr uint32_t kAddressSize =
134 static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
135 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
136 EXPECT_EQ(register_data[i], test_device_builder.data()[i + kAddressSize]);
137 }
138 }
139
TEST(RegisterDevice,WriteRegisters16With2RegistersAnd2ByteAddress)140 TEST(RegisterDevice, WriteRegisters16With2RegistersAnd2ByteAddress) {
141 TestInitiator initiator;
142 RegisterDevice device(initiator,
143 kTestDeviceAddress,
144 endian::little,
145 RegisterAddressSize::k2Bytes);
146
147 constexpr uint32_t kRegisterAddress = 0x89AB;
148 std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
149 std::array<std::byte, 6> builder;
150 EXPECT_EQ(device.WriteRegisters16(
151 kRegisterAddress, register_data, builder, kTimeout),
152 pw::OkStatus());
153
154 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
155 EXPECT_EQ(sizeof(builder), test_device_builder.size());
156
157 // Check address.
158 uint16_t kActualAddress;
159 std::memcpy(
160 &kActualAddress, test_device_builder.data(), sizeof(kActualAddress));
161 EXPECT_EQ(kRegisterAddress, kActualAddress);
162
163 // Check data.
164 constexpr uint32_t kAddressSize =
165 static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
166
167 for (uint32_t i = kAddressSize, j = 0; i < test_device_builder.size();
168 i += kAddressSize, j++) {
169 uint16_t actualData;
170 std::memcpy(
171 &actualData, &test_device_builder.data()[i], sizeof(actualData));
172 EXPECT_EQ(register_data[j], actualData);
173 }
174 }
175
TEST(RegisterDevice,WriteRegisters16With2RegistersAnd2ByteAddressBigEndian)176 TEST(RegisterDevice, WriteRegisters16With2RegistersAnd2ByteAddressBigEndian) {
177 TestInitiator initiator;
178 RegisterDevice device(
179 initiator, kTestDeviceAddress, endian::big, RegisterAddressSize::k2Bytes);
180
181 constexpr uint32_t kRegisterAddress = 0x89AB;
182 std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
183 std::array<std::byte, 6> builder;
184 EXPECT_EQ(device.WriteRegisters16(
185 kRegisterAddress, register_data, builder, kTimeout),
186 pw::OkStatus());
187
188 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
189 EXPECT_EQ(sizeof(builder), test_device_builder.size());
190
191 // Check address.
192 uint16_t kActualAddress;
193 std::memcpy(
194 &kActualAddress, test_device_builder.data(), sizeof(kActualAddress));
195 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(endian::big, &kRegisterAddress),
196 kActualAddress);
197
198 // Check data.
199 constexpr uint32_t kAddressSize =
200 static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
201
202 for (uint32_t i = kAddressSize, j = 0; i < test_device_builder.size();
203 i += kAddressSize, j++) {
204 uint16_t actualData;
205 std::memcpy(
206 &actualData, &test_device_builder.data()[i], sizeof(actualData));
207 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(endian::big, ®ister_data[j]),
208 actualData);
209 }
210 }
211
TEST(RegisterDevice,WriteRegisters8BufferTooSmall)212 TEST(RegisterDevice, WriteRegisters8BufferTooSmall) {
213 TestInitiator initiator;
214 RegisterDevice device(initiator,
215 kTestDeviceAddress,
216 endian::little,
217 RegisterAddressSize::k2Bytes);
218
219 constexpr uint32_t kRegisterAddress = 0x89AB;
220 std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
221 std::array<std::byte, 2> builder;
222 EXPECT_EQ(
223 device.WriteRegisters(kRegisterAddress, register_data, builder, kTimeout),
224 pw::Status::OutOfRange());
225 }
226
TEST(RegisterDevice,WriteRegister16With1ByteAddress)227 TEST(RegisterDevice, WriteRegister16With1ByteAddress) {
228 TestInitiator initiator;
229 RegisterDevice device(initiator,
230 kTestDeviceAddress,
231 endian::little,
232 RegisterAddressSize::k1Byte);
233
234 constexpr uint32_t kRegisterAddress = 0xAB;
235 constexpr uint16_t kRegisterData = 0xBCDE;
236 EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
237 pw::OkStatus());
238
239 constexpr uint32_t kAddressSize =
240 static_cast<uint32_t>(RegisterAddressSize::k1Byte);
241 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
242 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
243
244 // Check address.
245 EXPECT_EQ(kRegisterAddress,
246 static_cast<uint32_t>(test_device_builder.data()[0]));
247
248 // Check data.
249 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
250 EXPECT_EQ(
251 (kRegisterData >> (8 * i)) & 0xFF,
252 static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
253 }
254 }
255
TEST(RegisterDevice,WriteRegister32With1ByteAddress)256 TEST(RegisterDevice, WriteRegister32With1ByteAddress) {
257 TestInitiator initiator;
258 RegisterDevice device(initiator,
259 kTestDeviceAddress,
260 endian::little,
261 RegisterAddressSize::k1Byte);
262
263 constexpr uint32_t kRegisterAddress = 0xAB;
264 constexpr uint32_t kRegisterData = 0xBCCDDEEF;
265 EXPECT_EQ(device.WriteRegister32(kRegisterAddress, kRegisterData, kTimeout),
266 pw::OkStatus());
267
268 constexpr uint32_t kAddressSize =
269 static_cast<uint32_t>(RegisterAddressSize::k1Byte);
270 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
271 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
272
273 // Check address.
274 EXPECT_EQ(kRegisterAddress,
275 static_cast<uint32_t>(test_device_builder.data()[0]));
276
277 // Check data.
278 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
279 EXPECT_EQ(
280 (kRegisterData >> (8 * i)) & 0xFF,
281 static_cast<uint32_t>(test_device_builder.data()[i + kAddressSize]));
282 }
283 }
284
TEST(RegisterDevice,WriteRegister16with2ByteAddress)285 TEST(RegisterDevice, WriteRegister16with2ByteAddress) {
286 TestInitiator initiator;
287 RegisterDevice device(initiator,
288 kTestDeviceAddress,
289 endian::little,
290 RegisterAddressSize::k2Bytes);
291
292 constexpr uint32_t kRegisterAddress = 0xAB23;
293 constexpr uint16_t kRegisterData = 0xBCDD;
294 EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
295 pw::OkStatus());
296
297 constexpr uint32_t kAddressSize =
298 static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
299 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
300 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
301
302 // Check address.
303 uint16_t kActualAddress;
304 std::memcpy(
305 &kActualAddress, test_device_builder.data(), sizeof(kActualAddress));
306 EXPECT_EQ(kRegisterAddress, kActualAddress);
307
308 // Check data.
309 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
310 EXPECT_EQ(
311 (kRegisterData >> (8 * i)) & 0xFF,
312 static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
313 }
314 }
315
TEST(RegisterDevice,WriteRegister16With1ByteAddressAndBigEndian)316 TEST(RegisterDevice, WriteRegister16With1ByteAddressAndBigEndian) {
317 TestInitiator initiator;
318 RegisterDevice device(
319 initiator, kTestDeviceAddress, endian::big, RegisterAddressSize::k1Byte);
320
321 constexpr uint32_t kRegisterAddress = 0xAB;
322 constexpr uint16_t kRegisterData = 0xBCDE;
323 EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
324 pw::OkStatus());
325
326 constexpr uint32_t kAddressSize =
327 static_cast<uint32_t>(RegisterAddressSize::k1Byte);
328 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
329 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
330
331 // Check address.
332 EXPECT_EQ(kRegisterAddress,
333 static_cast<uint32_t>(test_device_builder.data()[0]));
334
335 // Check data.
336 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
337 const uint32_t shift = test_device_builder.size() - kAddressSize - (i + 1);
338 EXPECT_EQ(
339 (kRegisterData >> (8 * shift)) & 0xFF,
340 static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
341 }
342 }
343
TEST(RegisterDevice,WriteRegister32With1ByteAddressAndBigEndian)344 TEST(RegisterDevice, WriteRegister32With1ByteAddressAndBigEndian) {
345 TestInitiator initiator;
346 RegisterDevice device(
347 initiator, kTestDeviceAddress, endian::big, RegisterAddressSize::k1Byte);
348
349 constexpr uint32_t kRegisterAddress = 0xAB;
350 constexpr uint32_t kRegisterData = 0xBCCDDEEF;
351 EXPECT_EQ(device.WriteRegister32(kRegisterAddress, kRegisterData, kTimeout),
352 pw::OkStatus());
353
354 constexpr uint32_t kAddressSize =
355 static_cast<uint32_t>(RegisterAddressSize::k1Byte);
356 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
357 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
358
359 // Check address.
360 EXPECT_EQ(kRegisterAddress,
361 static_cast<uint32_t>(test_device_builder.data()[0]));
362
363 // Check data.
364 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
365 const uint32_t shift = test_device_builder.size() - kAddressSize - (i + 1);
366 EXPECT_EQ(
367 (kRegisterData >> (8 * shift)) & 0xFF,
368 static_cast<uint32_t>(test_device_builder.data()[i + kAddressSize]));
369 }
370 }
371
TEST(RegisterDevice,WriteRegister16With2ByteAddressAndBigEndian)372 TEST(RegisterDevice, WriteRegister16With2ByteAddressAndBigEndian) {
373 TestInitiator initiator;
374 RegisterDevice device(
375 initiator, kTestDeviceAddress, endian::big, RegisterAddressSize::k2Bytes);
376
377 constexpr uint32_t kRegisterAddress = 0xAB11;
378 constexpr uint16_t kRegisterData = 0xBCDF;
379 EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
380 pw::OkStatus());
381
382 constexpr uint32_t kAddressSize =
383 static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
384 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
385 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
386
387 // Check address.
388 uint16_t kActualAddress;
389 std::memcpy(
390 &kActualAddress, test_device_builder.data(), sizeof(kActualAddress));
391 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(endian::big, &kRegisterAddress),
392 kActualAddress);
393
394 // Check data.
395 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
396 const uint32_t shift = test_device_builder.size() - kAddressSize - (i + 1);
397 EXPECT_EQ(
398 (kRegisterData >> (8 * shift)) & 0xFF,
399 static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
400 }
401 }
402
TEST(RegisterDevice,ReadRegisters8ByteWith2RegistersAnd1ByteAddress)403 TEST(RegisterDevice, ReadRegisters8ByteWith2RegistersAnd1ByteAddress) {
404 TestInitiator initiator;
405 RegisterDevice device(initiator,
406 kTestDeviceAddress,
407 endian::little,
408 RegisterAddressSize::k1Byte);
409
410 std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
411 initiator.SetReadData(register_data);
412
413 std::array<std::byte, 2> buffer;
414 constexpr uint32_t kRegisterAddress = 0xAB;
415 EXPECT_EQ(device.ReadRegisters(kRegisterAddress, buffer, kTimeout),
416 pw::OkStatus());
417
418 // Check address.
419 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
420 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
421 address_buffer.size());
422
423 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
424 const_cast<std::byte*>(address_buffer.data())));
425 EXPECT_EQ(kRegisterAddress, kActualAddress);
426
427 // Check data.
428 for (uint32_t i = 0; i < sizeof(buffer); i++) {
429 EXPECT_EQ(buffer[i], register_data[i]);
430 }
431 }
432
TEST(RegisterDevice,ReadRegisters8IntWith2RegistersAnd1ByteAddress)433 TEST(RegisterDevice, ReadRegisters8IntWith2RegistersAnd1ByteAddress) {
434 TestInitiator initiator;
435 RegisterDevice device(initiator,
436 kTestDeviceAddress,
437 endian::little,
438 RegisterAddressSize::k1Byte);
439
440 std::array<uint8_t, 2> register_data = {0xCD, 0xEF};
441 initiator.SetReadData(
442 as_writable_bytes(span(register_data.data(), register_data.size())));
443
444 std::array<uint8_t, 2> buffer;
445 constexpr uint32_t kRegisterAddress = 0xAB;
446 EXPECT_EQ(device.ReadRegisters8(kRegisterAddress, buffer, kTimeout),
447 pw::OkStatus());
448
449 // Check address.
450 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
451 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
452 address_buffer.size());
453
454 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
455 const_cast<std::byte*>(address_buffer.data())));
456 EXPECT_EQ(kRegisterAddress, kActualAddress);
457
458 // Check data.
459 for (uint32_t i = 0; i < sizeof(buffer); i++) {
460 EXPECT_EQ(buffer[i], register_data[i]);
461 }
462 }
463
TEST(RegisterDevice,ReadRegisters8ByteWith2RegistersAnd2ByteAddress)464 TEST(RegisterDevice, ReadRegisters8ByteWith2RegistersAnd2ByteAddress) {
465 TestInitiator initiator;
466 RegisterDevice device(initiator,
467 kTestDeviceAddress,
468 endian::little,
469 RegisterAddressSize::k2Bytes);
470
471 std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
472 initiator.SetReadData(register_data);
473
474 std::array<std::byte, 2> buffer;
475 constexpr uint32_t kRegisterAddress = 0xABBA;
476 EXPECT_EQ(device.ReadRegisters(kRegisterAddress, buffer, kTimeout),
477 pw::OkStatus());
478
479 // Check address.
480 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
481 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
482 address_buffer.size());
483
484 uint16_t kActualAddress;
485 std::memcpy(&kActualAddress, address_buffer.data(), sizeof(kActualAddress));
486 EXPECT_EQ(kRegisterAddress, kActualAddress);
487
488 // Check data.
489 for (uint32_t i = 0; i < sizeof(buffer); i++) {
490 EXPECT_EQ(buffer[i], register_data[i]);
491 }
492 }
493
TEST(RegisterDevice,ReadRegisters16With2RegistersAnd2ByteAddress)494 TEST(RegisterDevice, ReadRegisters16With2RegistersAnd2ByteAddress) {
495 TestInitiator initiator;
496 RegisterDevice device(initiator,
497 kTestDeviceAddress,
498 endian::little,
499 RegisterAddressSize::k2Bytes);
500
501 std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
502 initiator.SetReadData(
503 as_writable_bytes(span(register_data.data(), register_data.size())));
504
505 std::array<uint16_t, 2> buffer;
506 constexpr uint32_t kRegisterAddress = 0xAB;
507 EXPECT_EQ(device.ReadRegisters16(kRegisterAddress, buffer, kTimeout),
508 pw::OkStatus());
509
510 // Check address.
511 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
512 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
513 address_buffer.size());
514
515 uint16_t kActualAddress;
516 std::memcpy(&kActualAddress, address_buffer.data(), sizeof(kActualAddress));
517 EXPECT_EQ(kRegisterAddress, kActualAddress);
518
519 // Check data.
520 for (uint32_t i = 0; i < buffer.size(); i++) {
521 EXPECT_EQ(buffer[i], register_data[i]);
522 }
523 }
524
TEST(RegisterDevice,ReadRegisters16With2RegistersAnd2ByteAddressBigEndian)525 TEST(RegisterDevice, ReadRegisters16With2RegistersAnd2ByteAddressBigEndian) {
526 TestInitiator initiator;
527 RegisterDevice device(
528 initiator, kTestDeviceAddress, endian::big, RegisterAddressSize::k2Bytes);
529
530 std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
531 initiator.SetReadData(
532 as_writable_bytes(span(register_data.data(), register_data.size())));
533
534 std::array<uint16_t, 2> buffer;
535 constexpr uint32_t kRegisterAddress = 0xAB;
536 EXPECT_EQ(device.ReadRegisters16(kRegisterAddress, buffer, kTimeout),
537 pw::OkStatus());
538
539 // Check address.
540 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
541 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
542 address_buffer.size());
543
544 uint16_t kActualAddress;
545 std::memcpy(&kActualAddress, address_buffer.data(), sizeof(kActualAddress));
546 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(endian::big, &kRegisterAddress),
547 kActualAddress);
548
549 // Check data.
550 for (uint32_t i = 0; i < buffer.size(); i++) {
551 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(endian::big, ®ister_data[i]),
552 buffer[i]);
553 }
554 }
555
TEST(RegisterDevice,ReadRegister16With1ByteAddress)556 TEST(RegisterDevice, ReadRegister16With1ByteAddress) {
557 TestInitiator initiator;
558 RegisterDevice device(initiator,
559 kTestDeviceAddress,
560 endian::little,
561 RegisterAddressSize::k1Byte);
562
563 std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
564 initiator.SetReadData(register_data);
565
566 constexpr uint32_t kRegisterAddress = 0xAB;
567 Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
568 EXPECT_TRUE(result.ok());
569 uint16_t read_data = result.value_or(kErrorValue);
570
571 // Check address.
572 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
573 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
574 address_buffer.size());
575
576 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
577 const_cast<std::byte*>(address_buffer.data())));
578 EXPECT_EQ(kRegisterAddress, kActualAddress);
579
580 // Check data.
581 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
582 for (uint32_t i = 0; i < sizeof(read_data); i++) {
583 EXPECT_EQ(read_pointer[i], static_cast<uint8_t>(register_data[i]));
584 }
585 }
586
TEST(RegisterDevice,ReadRegister32With1ByteAddress)587 TEST(RegisterDevice, ReadRegister32With1ByteAddress) {
588 TestInitiator initiator;
589 RegisterDevice device(initiator,
590 kTestDeviceAddress,
591 endian::little,
592 RegisterAddressSize::k1Byte);
593
594 std::array<std::byte, 4> register_data = {
595 std::byte{0x98}, std::byte{0x76}, std::byte{0x54}, std::byte{0x32}};
596 initiator.SetReadData(register_data);
597
598 constexpr uint32_t kRegisterAddress = 0xAB;
599 Result<uint32_t> result = device.ReadRegister32(kRegisterAddress, kTimeout);
600 EXPECT_TRUE(result.ok());
601 uint32_t read_data = result.value_or(kErrorValue);
602
603 // Check address.
604 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
605 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
606 address_buffer.size());
607
608 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
609 const_cast<std::byte*>(address_buffer.data())));
610 EXPECT_EQ(kRegisterAddress, kActualAddress);
611
612 // Check data.
613 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
614 for (uint32_t i = 0; i < sizeof(read_data); i++) {
615 EXPECT_EQ(read_pointer[i], static_cast<uint8_t>(register_data[i]));
616 }
617 }
618
TEST(RegisterDevice,ReadRegister16With2ByteAddress)619 TEST(RegisterDevice, ReadRegister16With2ByteAddress) {
620 TestInitiator initiator;
621 RegisterDevice device(initiator,
622 kTestDeviceAddress,
623 endian::little,
624 RegisterAddressSize::k2Bytes);
625
626 std::array<std::byte, 2> register_data = {std::byte{0x98}, std::byte{0x76}};
627 initiator.SetReadData(register_data);
628
629 constexpr uint32_t kRegisterAddress = 0xA4AB;
630 Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
631 EXPECT_TRUE(result.ok());
632 uint16_t read_data = result.value_or(kErrorValue);
633
634 // Check address.
635 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
636 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
637 address_buffer.size());
638
639 uint16_t kActualAddress;
640 std::memcpy(&kActualAddress, address_buffer.data(), sizeof(kActualAddress));
641 EXPECT_EQ(kRegisterAddress, kActualAddress);
642
643 // Check data.
644 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
645 for (uint32_t i = 0; i < sizeof(read_data); i++) {
646 EXPECT_EQ(read_pointer[i], static_cast<uint8_t>(register_data[i]));
647 }
648 }
649
TEST(RegisterDevice,ReadRegister16With1ByteAddressAndBigEndian)650 TEST(RegisterDevice, ReadRegister16With1ByteAddressAndBigEndian) {
651 TestInitiator initiator;
652 RegisterDevice device(
653 initiator, kTestDeviceAddress, endian::big, RegisterAddressSize::k1Byte);
654
655 std::array<std::byte, 2> register_data = {std::byte{0x98}, std::byte{0x76}};
656 initiator.SetReadData(register_data);
657
658 constexpr uint32_t kRegisterAddress = 0xAB;
659 Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
660 EXPECT_TRUE(result.ok());
661 uint16_t read_data = result.value_or(kErrorValue);
662
663 // Check address.
664 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
665 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
666 address_buffer.size());
667
668 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
669 const_cast<std::byte*>(address_buffer.data())));
670 EXPECT_EQ(kRegisterAddress, kActualAddress);
671
672 // Check data.
673 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
674 for (uint32_t i = 0; i < sizeof(read_data); i++) {
675 const uint32_t kReadPointerIndex = sizeof(read_data) - 1 - i;
676 EXPECT_EQ(read_pointer[kReadPointerIndex],
677 static_cast<uint8_t>(register_data[i]));
678 }
679 }
680
TEST(RegisterDevice,ReadRegister32With1ByteAddressAndBigEndian)681 TEST(RegisterDevice, ReadRegister32With1ByteAddressAndBigEndian) {
682 TestInitiator initiator;
683 RegisterDevice device(
684 initiator, kTestDeviceAddress, endian::big, RegisterAddressSize::k1Byte);
685
686 std::array<std::byte, 4> register_data = {
687 std::byte{0x98}, std::byte{0x76}, std::byte{0x54}, std::byte{0x32}};
688 initiator.SetReadData(register_data);
689
690 constexpr uint32_t kRegisterAddress = 0xAB;
691 Result<uint32_t> result = device.ReadRegister32(kRegisterAddress, kTimeout);
692 EXPECT_TRUE(result.ok());
693 uint32_t read_data = result.value_or(kErrorValue);
694
695 // Check address.
696 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
697 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
698 address_buffer.size());
699
700 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
701 const_cast<std::byte*>(address_buffer.data())));
702 EXPECT_EQ(kRegisterAddress, kActualAddress);
703
704 // Check data.
705 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
706 for (uint32_t i = 0; i < sizeof(read_data); i++) {
707 const uint32_t kReadPointerIndex = sizeof(read_data) - 1 - i;
708 EXPECT_EQ(read_pointer[kReadPointerIndex],
709 static_cast<uint8_t>(register_data[i]));
710 }
711 }
712
TEST(RegisterDevice,ReadRegister16With2ByteAddressAndBigEndian)713 TEST(RegisterDevice, ReadRegister16With2ByteAddressAndBigEndian) {
714 TestInitiator initiator;
715 RegisterDevice device(
716 initiator, kTestDeviceAddress, endian::big, RegisterAddressSize::k2Bytes);
717
718 std::array<std::byte, 2> register_data = {std::byte{0x98}, std::byte{0x76}};
719 initiator.SetReadData(register_data);
720
721 constexpr uint32_t kRegisterAddress = 0xABEF;
722 Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
723 EXPECT_TRUE(result.ok());
724 uint16_t read_data = result.value_or(kErrorValue);
725
726 // Check address.
727 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
728 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
729 address_buffer.size());
730
731 uint16_t kActualAddress;
732 std::memcpy(&kActualAddress, address_buffer.data(), sizeof(kActualAddress));
733 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(endian::big, &kRegisterAddress),
734 kActualAddress);
735
736 // Check data.
737 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
738 for (uint32_t i = 0; i < sizeof(read_data); i++) {
739 const uint32_t kReadPointerIndex = sizeof(read_data) - 1 - i;
740 EXPECT_EQ(read_pointer[kReadPointerIndex],
741 static_cast<uint8_t>(register_data[i]));
742 }
743 }
744
TEST(RegisterDevice,ReadRegister16With2ByteBigEndianAddress)745 TEST(RegisterDevice, ReadRegister16With2ByteBigEndianAddress) {
746 TestInitiator initiator;
747 RegisterDevice device(initiator,
748 kTestDeviceAddress,
749 endian::big,
750 endian::little,
751 RegisterAddressSize::k2Bytes);
752
753 std::array<std::byte, 2> register_data = {std::byte{0x98}, std::byte{0x76}};
754 initiator.SetReadData(register_data);
755
756 constexpr uint32_t kRegisterAddress = 0xABEF;
757 Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
758 EXPECT_TRUE(result.ok());
759 uint16_t read_data = result.value_or(kErrorValue);
760
761 // Check address.
762 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
763 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
764 address_buffer.size());
765
766 uint16_t kActualAddress;
767 std::memcpy(&kActualAddress, address_buffer.data(), sizeof(kActualAddress));
768 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(endian::big, &kRegisterAddress),
769 kActualAddress);
770
771 // Check data.
772 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
773 for (uint32_t i = 0; i < sizeof(read_data); i++) {
774 EXPECT_EQ(read_pointer[i], static_cast<uint8_t>(register_data[i]));
775 }
776 }
777
TEST(RegisterDevice,WriteRegister16with2ByteBigEndianAddress)778 TEST(RegisterDevice, WriteRegister16with2ByteBigEndianAddress) {
779 TestInitiator initiator;
780 RegisterDevice device(initiator,
781 kTestDeviceAddress,
782 endian::big,
783 endian::little,
784 RegisterAddressSize::k2Bytes);
785
786 constexpr uint32_t kRegisterAddress = 0xAB11;
787 constexpr uint16_t kRegisterData = 0xBCDF;
788 EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
789 pw::OkStatus());
790
791 constexpr uint32_t kAddressSize =
792 static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
793 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
794 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
795
796 // Check address.
797 uint16_t kActualAddress;
798 std::memcpy(
799 &kActualAddress, test_device_builder.data(), sizeof(kActualAddress));
800 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(endian::big, &kRegisterAddress),
801 kActualAddress);
802
803 // Check data.
804 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
805 EXPECT_EQ(
806 (kRegisterData >> (8 * i)) & 0xFF,
807 static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
808 }
809 }
810
811 } // namespace
812 } // namespace i2c
813 } // namespace pw
814