blob: 1d2ff7ce6e7b8cb0ecba732cab8c469db59fe821 [file] [log] [blame]
Kevin Zeng58b43d32021-04-16 00:36:16 -07001// 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 "gtest/gtest.h"
Wyatt Heplerf298de42021-03-19 15:06:36 -070017#include "pw_assert/check.h"
Kevin Zeng58b43d32021-04-16 00:36:16 -070018#include "pw_bytes/byte_builder.h"
19
20namespace pw {
21namespace i2c {
22namespace {
23
24using ::pw::Status;
25using namespace std::literals::chrono_literals;
26
27constexpr uint8_t kErrorValue = 0x11;
Rob Mohrecbdb692021-06-10 15:03:10 -070028constexpr Address kTestDeviceAddress = Address::SevenBit<0x3F>();
Kevin Zeng58b43d32021-04-16 00:36:16 -070029
30constexpr chrono::SystemClock::duration kTimeout =
31 std::chrono::duration_cast<chrono::SystemClock::duration>(100ms);
32
33// Default test object. Mimics closely to I2c devices.
34class TestInitiator : public Initiator {
35 public:
36 explicit TestInitiator() {}
37
38 ByteBuilder& GetWriteBuffer() { return write_buffer_; }
39
40 void SetReadData(ByteSpan read_data) {
41 read_buffer_.append(read_data.data(), read_data.size());
42 }
43
44 private:
45 Status DoWriteReadFor(Address,
46 ConstByteSpan tx_data,
47 ByteSpan rx_data,
48 chrono::SystemClock::duration) override {
49 // Write
50 if (tx_data.size() > 0) {
51 write_buffer_.append(tx_data.data(), tx_data.size());
52 }
53
54 // Read
55 if (rx_data.size() > 0) {
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
70TEST(RegisterDevice, Construction) {
71 TestInitiator initiator;
72 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -070073 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -070074 std::endian::little,
75 RegisterAddressSize::k1Byte);
76}
77
78TEST(RegisterDevice, WriteRegisters8With2RegistersAnd1ByteAddress) {
79 TestInitiator initiator;
80 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -070081 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -070082 std::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
107TEST(RegisterDevice, WriteRegisters8With2RegistersAnd2ByteAddress) {
108 TestInitiator initiator;
109 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700110 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700111 std::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
137TEST(RegisterDevice, WriteRegisters16With2RegistersAnd2ByteAddress) {
138 TestInitiator initiator;
139 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700140 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700141 std::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
172TEST(RegisterDevice, WriteRegisters16With2RegistersAnd2ByteAddressBigEndian) {
173 TestInitiator initiator;
174 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700175 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700176 std::endian::big,
177 RegisterAddressSize::k2Bytes);
178
179 constexpr uint32_t kRegisterAddress = 0x89AB;
180 std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
181 std::array<std::byte, 6> builder;
182 EXPECT_EQ(device.WriteRegisters16(
183 kRegisterAddress, register_data, builder, kTimeout),
184 pw::OkStatus());
185
186 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
187 EXPECT_EQ(sizeof(builder), test_device_builder.size());
188
189 // Check address.
190 const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
191 const_cast<std::byte*>(test_device_builder.data())));
192 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &kRegisterAddress),
193 kActualAddress);
194
195 // Check data.
196 constexpr uint32_t kAddressSize =
197 static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
198
199 const uint16_t* read_pointer = reinterpret_cast<const uint16_t*>(
200 test_device_builder.data() + kAddressSize);
201 for (uint32_t i = 0; i < (test_device_builder.size() - kAddressSize) /
202 sizeof(register_data[0]);
203 i++) {
204 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &register_data[i]),
205 read_pointer[i]);
206 }
207}
208
209TEST(RegisterDevice, WriteRegisters8BufferTooSmall) {
210 TestInitiator initiator;
211 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700212 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700213 std::endian::little,
214 RegisterAddressSize::k2Bytes);
215
216 constexpr uint32_t kRegisterAddress = 0x89AB;
217 std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
218 std::array<std::byte, 2> builder;
219 EXPECT_EQ(
220 device.WriteRegisters(kRegisterAddress, register_data, builder, kTimeout),
221 pw::Status::OutOfRange());
222}
223
224TEST(RegisterDevice, WriteRegister16With1ByteAddress) {
225 TestInitiator initiator;
226 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700227 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700228 std::endian::little,
229 RegisterAddressSize::k1Byte);
230
231 constexpr uint32_t kRegisterAddress = 0xAB;
232 constexpr uint16_t kRegisterData = 0xBCDE;
233 EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
234 pw::OkStatus());
235
236 constexpr uint32_t kAddressSize =
237 static_cast<uint32_t>(RegisterAddressSize::k1Byte);
238 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
239 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
240
241 // Check address.
242 EXPECT_EQ(kRegisterAddress,
243 static_cast<uint32_t>(test_device_builder.data()[0]));
244
245 // Check data.
246 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
247 EXPECT_EQ(
248 (kRegisterData >> (8 * i)) & 0xFF,
249 static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
250 }
251}
252
253TEST(RegisterDevice, WriteRegister32With1ByteAddress) {
254 TestInitiator initiator;
255 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700256 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700257 std::endian::little,
258 RegisterAddressSize::k1Byte);
259
260 constexpr uint32_t kRegisterAddress = 0xAB;
261 constexpr uint32_t kRegisterData = 0xBCCDDEEF;
262 EXPECT_EQ(device.WriteRegister32(kRegisterAddress, kRegisterData, kTimeout),
263 pw::OkStatus());
264
265 constexpr uint32_t kAddressSize =
266 static_cast<uint32_t>(RegisterAddressSize::k1Byte);
267 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
268 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
269
270 // Check address.
271 EXPECT_EQ(kRegisterAddress,
272 static_cast<uint32_t>(test_device_builder.data()[0]));
273
274 // Check data.
275 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
276 EXPECT_EQ(
277 (kRegisterData >> (8 * i)) & 0xFF,
278 static_cast<uint32_t>(test_device_builder.data()[i + kAddressSize]));
279 }
280}
281
282TEST(RegisterDevice, WriteRegister16with2ByteAddress) {
283 TestInitiator initiator;
284 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700285 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700286 std::endian::little,
287 RegisterAddressSize::k2Bytes);
288
289 constexpr uint32_t kRegisterAddress = 0xAB23;
290 constexpr uint16_t kRegisterData = 0xBCDD;
291 EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
292 pw::OkStatus());
293
294 constexpr uint32_t kAddressSize =
295 static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
296 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
297 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
298
299 // Check address.
300 const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
301 const_cast<std::byte*>(test_device_builder.data())));
302 EXPECT_EQ(kRegisterAddress, kActualAddress);
303
304 // Check data.
305 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
306 EXPECT_EQ(
307 (kRegisterData >> (8 * i)) & 0xFF,
308 static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
309 }
310}
311
312TEST(RegisterDevice, WriteRegister16With1ByteAddressAndBigEndian) {
313 TestInitiator initiator;
314 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700315 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700316 std::endian::big,
317 RegisterAddressSize::k1Byte);
318
319 constexpr uint32_t kRegisterAddress = 0xAB;
320 constexpr uint16_t kRegisterData = 0xBCDE;
321 EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
322 pw::OkStatus());
323
324 constexpr uint32_t kAddressSize =
325 static_cast<uint32_t>(RegisterAddressSize::k1Byte);
326 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
327 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
328
329 // Check address.
330 EXPECT_EQ(kRegisterAddress,
331 static_cast<uint32_t>(test_device_builder.data()[0]));
332
333 // Check data.
334 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
335 const uint32_t shift = test_device_builder.size() - kAddressSize - (i + 1);
336 EXPECT_EQ(
337 (kRegisterData >> (8 * shift)) & 0xFF,
338 static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
339 }
340}
341
342TEST(RegisterDevice, WriteRegister32With1ByteAddressAndBigEndian) {
343 TestInitiator initiator;
344 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700345 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700346 std::endian::big,
347 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
372TEST(RegisterDevice, WriteRegister16With2ByteAddressAndBigEndian) {
373 TestInitiator initiator;
374 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700375 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700376 std::endian::big,
377 RegisterAddressSize::k2Bytes);
378
379 constexpr uint32_t kRegisterAddress = 0xAB11;
380 constexpr uint16_t kRegisterData = 0xBCDF;
381 EXPECT_EQ(device.WriteRegister16(kRegisterAddress, kRegisterData, kTimeout),
382 pw::OkStatus());
383
384 constexpr uint32_t kAddressSize =
385 static_cast<uint32_t>(RegisterAddressSize::k2Bytes);
386 ByteBuilder& test_device_builder = initiator.GetWriteBuffer();
387 EXPECT_EQ(test_device_builder.size(), kAddressSize + sizeof(kRegisterData));
388
389 // Check address.
390 const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
391 const_cast<std::byte*>(test_device_builder.data())));
392 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &kRegisterAddress),
393 kActualAddress);
394
395 // Check data.
396 for (uint32_t i = 0; i < test_device_builder.size() - kAddressSize; i++) {
397 const uint32_t shift = test_device_builder.size() - kAddressSize - (i + 1);
398 EXPECT_EQ(
399 (kRegisterData >> (8 * shift)) & 0xFF,
400 static_cast<uint16_t>(test_device_builder.data()[i + kAddressSize]));
401 }
402}
403
404TEST(RegisterDevice, ReadRegisters8ByteWith2RegistersAnd1ByteAddress) {
405 TestInitiator initiator;
406 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700407 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700408 std::endian::little,
409 RegisterAddressSize::k1Byte);
410
411 std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
412 initiator.SetReadData(register_data);
413
414 std::array<std::byte, 2> buffer;
415 constexpr uint32_t kRegisterAddress = 0xAB;
416 EXPECT_EQ(device.ReadRegisters(kRegisterAddress, buffer, kTimeout),
417 pw::OkStatus());
418
419 // Check address.
420 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
421 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
422 address_buffer.size());
423
424 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
425 const_cast<std::byte*>(address_buffer.data())));
426 EXPECT_EQ(kRegisterAddress, kActualAddress);
427
428 // Check data.
429 for (uint32_t i = 0; i < sizeof(buffer); i++) {
430 EXPECT_EQ(buffer[i], register_data[i]);
431 }
432}
433
434TEST(RegisterDevice, ReadRegisters8IntWith2RegistersAnd1ByteAddress) {
435 TestInitiator initiator;
436 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700437 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700438 std::endian::little,
439 RegisterAddressSize::k1Byte);
440
441 std::array<uint8_t, 2> register_data = {0xCD, 0xEF};
442 initiator.SetReadData(std::as_writable_bytes(
443 std::span(register_data.data(), register_data.size())));
444
445 std::array<uint8_t, 2> buffer;
446 constexpr uint32_t kRegisterAddress = 0xAB;
447 EXPECT_EQ(device.ReadRegisters8(kRegisterAddress, buffer, kTimeout),
448 pw::OkStatus());
449
450 // Check address.
451 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
452 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
453 address_buffer.size());
454
455 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
456 const_cast<std::byte*>(address_buffer.data())));
457 EXPECT_EQ(kRegisterAddress, kActualAddress);
458
459 // Check data.
460 for (uint32_t i = 0; i < sizeof(buffer); i++) {
461 EXPECT_EQ(buffer[i], register_data[i]);
462 }
463}
464
465TEST(RegisterDevice, ReadRegisters8ByteWith2RegistersAnd2ByteAddress) {
466 TestInitiator initiator;
467 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700468 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700469 std::endian::little,
470 RegisterAddressSize::k2Bytes);
471
472 std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
473 initiator.SetReadData(register_data);
474
475 std::array<std::byte, 2> buffer;
476 constexpr uint32_t kRegisterAddress = 0xABBA;
477 EXPECT_EQ(device.ReadRegisters(kRegisterAddress, buffer, kTimeout),
478 pw::OkStatus());
479
480 // Check address.
481 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
482 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
483 address_buffer.size());
484
485 const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
486 const_cast<std::byte*>(address_buffer.data())));
487 EXPECT_EQ(kRegisterAddress, kActualAddress);
488
489 // Check data.
490 for (uint32_t i = 0; i < sizeof(buffer); i++) {
491 EXPECT_EQ(buffer[i], register_data[i]);
492 }
493}
494
495TEST(RegisterDevice, ReadRegisters16With2RegistersAnd2ByteAddress) {
496 TestInitiator initiator;
497 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700498 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700499 std::endian::little,
500 RegisterAddressSize::k2Bytes);
501
502 std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
503 initiator.SetReadData(std::as_writable_bytes(
504 std::span(register_data.data(), register_data.size())));
505
506 std::array<uint16_t, 2> buffer;
507 constexpr uint32_t kRegisterAddress = 0xAB;
508 EXPECT_EQ(device.ReadRegisters16(kRegisterAddress, buffer, kTimeout),
509 pw::OkStatus());
510
511 // Check address.
512 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
513 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
514 address_buffer.size());
515
516 const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
517 const_cast<std::byte*>(address_buffer.data())));
518 EXPECT_EQ(kRegisterAddress, kActualAddress);
519
520 // Check data.
521 for (uint32_t i = 0; i < buffer.size(); i++) {
522 EXPECT_EQ(buffer[i], register_data[i]);
523 }
524}
525
526TEST(RegisterDevice, ReadRegisters16With2RegistersAnd2ByteAddressBigEndian) {
527 TestInitiator initiator;
528 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700529 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700530 std::endian::big,
531 RegisterAddressSize::k2Bytes);
532
533 std::array<uint16_t, 2> register_data = {0xCDEF, 0x1234};
534 initiator.SetReadData(std::as_writable_bytes(
535 std::span(register_data.data(), register_data.size())));
536
537 std::array<uint16_t, 2> buffer;
538 constexpr uint32_t kRegisterAddress = 0xAB;
539 EXPECT_EQ(device.ReadRegisters16(kRegisterAddress, buffer, kTimeout),
540 pw::OkStatus());
541
542 // Check address.
543 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
544 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
545 address_buffer.size());
546
547 const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
548 const_cast<std::byte*>(address_buffer.data())));
549 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &kRegisterAddress),
550 kActualAddress);
551
552 // Check data.
553 for (uint32_t i = 0; i < buffer.size(); i++) {
554 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &register_data[i]),
555 buffer[i]);
556 }
557}
558
559TEST(RegisterDevice, ReadRegister16With1ByteAddress) {
560 TestInitiator initiator;
561 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700562 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700563 std::endian::little,
564 RegisterAddressSize::k1Byte);
565
566 std::array<std::byte, 2> register_data = {std::byte{0xCD}, std::byte{0xEF}};
567 initiator.SetReadData(register_data);
568
569 constexpr uint32_t kRegisterAddress = 0xAB;
570 Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
571 EXPECT_TRUE(result.ok());
572 uint16_t read_data = result.value_or(kErrorValue);
573
574 // Check address.
575 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
576 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
577 address_buffer.size());
578
579 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
580 const_cast<std::byte*>(address_buffer.data())));
581 EXPECT_EQ(kRegisterAddress, kActualAddress);
582
583 // Check data.
584 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
585 for (uint32_t i = 0; i < sizeof(read_data); i++) {
586 EXPECT_EQ(read_pointer[i], static_cast<uint8_t>(register_data[i]));
587 }
588}
589
590TEST(RegisterDevice, ReadRegister32With1ByteAddress) {
591 TestInitiator initiator;
592 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700593 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700594 std::endian::little,
595 RegisterAddressSize::k1Byte);
596
597 std::array<std::byte, 4> register_data = {
598 std::byte{0x98}, std::byte{0x76}, std::byte{0x54}, std::byte{0x32}};
599 initiator.SetReadData(register_data);
600
601 constexpr uint32_t kRegisterAddress = 0xAB;
602 Result<uint32_t> result = device.ReadRegister32(kRegisterAddress, kTimeout);
603 EXPECT_TRUE(result.ok());
604 uint32_t read_data = result.value_or(kErrorValue);
605
606 // Check address.
607 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
608 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
609 address_buffer.size());
610
611 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
612 const_cast<std::byte*>(address_buffer.data())));
613 EXPECT_EQ(kRegisterAddress, kActualAddress);
614
615 // Check data.
616 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
617 for (uint32_t i = 0; i < sizeof(read_data); i++) {
618 EXPECT_EQ(read_pointer[i], static_cast<uint8_t>(register_data[i]));
619 }
620}
621
622TEST(RegisterDevice, ReadRegister16With2ByteAddress) {
623 TestInitiator initiator;
624 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700625 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700626 std::endian::little,
627 RegisterAddressSize::k2Bytes);
628
629 std::array<std::byte, 2> register_data = {std::byte{0x98}, std::byte{0x76}};
630 initiator.SetReadData(register_data);
631
632 constexpr uint32_t kRegisterAddress = 0xA4AB;
633 Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
634 EXPECT_TRUE(result.ok());
635 uint16_t read_data = result.value_or(kErrorValue);
636
637 // Check address.
638 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
639 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
640 address_buffer.size());
641
642 const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
643 const_cast<std::byte*>(address_buffer.data())));
644 EXPECT_EQ(kRegisterAddress, kActualAddress);
645
646 // Check data.
647 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
648 for (uint32_t i = 0; i < sizeof(read_data); i++) {
649 EXPECT_EQ(read_pointer[i], static_cast<uint8_t>(register_data[i]));
650 }
651}
652
653TEST(RegisterDevice, ReadRegister16With1ByteAddressAndBigEndian) {
654 TestInitiator initiator;
655 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700656 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700657 std::endian::big,
658 RegisterAddressSize::k1Byte);
659
660 std::array<std::byte, 2> register_data = {std::byte{0x98}, std::byte{0x76}};
661 initiator.SetReadData(register_data);
662
663 constexpr uint32_t kRegisterAddress = 0xAB;
664 Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
665 EXPECT_TRUE(result.ok());
666 uint16_t read_data = result.value_or(kErrorValue);
667
668 // Check address.
669 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
670 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
671 address_buffer.size());
672
673 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
674 const_cast<std::byte*>(address_buffer.data())));
675 EXPECT_EQ(kRegisterAddress, kActualAddress);
676
677 // Check data.
678 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
679 for (uint32_t i = 0; i < sizeof(read_data); i++) {
680 const uint32_t kReadPointerIndex = sizeof(read_data) - 1 - i;
681 EXPECT_EQ(read_pointer[kReadPointerIndex],
682 static_cast<uint8_t>(register_data[i]));
683 }
684}
685
686TEST(RegisterDevice, ReadRegister32With1ByteAddressAndBigEndian) {
687 TestInitiator initiator;
688 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700689 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700690 std::endian::big,
691 RegisterAddressSize::k1Byte);
692
693 std::array<std::byte, 4> register_data = {
694 std::byte{0x98}, std::byte{0x76}, std::byte{0x54}, std::byte{0x32}};
695 initiator.SetReadData(register_data);
696
697 constexpr uint32_t kRegisterAddress = 0xAB;
698 Result<uint32_t> result = device.ReadRegister32(kRegisterAddress, kTimeout);
699 EXPECT_TRUE(result.ok());
700 uint32_t read_data = result.value_or(kErrorValue);
701
702 // Check address.
703 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
704 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k1Byte),
705 address_buffer.size());
706
707 const uint8_t kActualAddress = *(reinterpret_cast<uint8_t*>(
708 const_cast<std::byte*>(address_buffer.data())));
709 EXPECT_EQ(kRegisterAddress, kActualAddress);
710
711 // Check data.
712 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
713 for (uint32_t i = 0; i < sizeof(read_data); i++) {
714 const uint32_t kReadPointerIndex = sizeof(read_data) - 1 - i;
715 EXPECT_EQ(read_pointer[kReadPointerIndex],
716 static_cast<uint8_t>(register_data[i]));
717 }
718}
719
720TEST(RegisterDevice, ReadRegister16With2ByteAddressAndBigEndian) {
721 TestInitiator initiator;
722 RegisterDevice device(initiator,
Rob Mohrecbdb692021-06-10 15:03:10 -0700723 kTestDeviceAddress,
Kevin Zeng58b43d32021-04-16 00:36:16 -0700724 std::endian::big,
725 RegisterAddressSize::k2Bytes);
726
727 std::array<std::byte, 2> register_data = {std::byte{0x98}, std::byte{0x76}};
728 initiator.SetReadData(register_data);
729
730 constexpr uint32_t kRegisterAddress = 0xABEF;
731 Result<uint16_t> result = device.ReadRegister16(kRegisterAddress, kTimeout);
732 EXPECT_TRUE(result.ok());
733 uint16_t read_data = result.value_or(kErrorValue);
734
735 // Check address.
736 ByteBuilder& address_buffer = initiator.GetWriteBuffer();
737 EXPECT_EQ(static_cast<uint32_t>(RegisterAddressSize::k2Bytes),
738 address_buffer.size());
739
740 const uint16_t kActualAddress = *(reinterpret_cast<uint16_t*>(
741 const_cast<std::byte*>(address_buffer.data())));
742 EXPECT_EQ(bytes::ReadInOrder<uint16_t>(std::endian::big, &kRegisterAddress),
743 kActualAddress);
744
745 // Check data.
746 uint8_t* read_pointer = reinterpret_cast<uint8_t*>(&read_data);
747 for (uint32_t i = 0; i < sizeof(read_data); i++) {
748 const uint32_t kReadPointerIndex = sizeof(read_data) - 1 - i;
749 EXPECT_EQ(read_pointer[kReadPointerIndex],
750 static_cast<uint8_t>(register_data[i]));
751 }
752}
753
754} // namespace
755} // namespace i2c
756} // namespace pw