• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &register_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, &register_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