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