Pigweed
 
Loading...
Searching...
No Matches
register_device.h
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#pragma once
15
16#include "pw_bytes/endian.h"
17#include "pw_bytes/span.h"
18#include "pw_chrono/system_clock.h"
19#include "pw_i2c/address.h"
20#include "pw_i2c/device.h"
21#include "pw_i2c/initiator.h"
22#include "pw_result/result.h"
23#include "pw_status/status.h"
24#include "pw_status/try.h"
25
26namespace pw {
27namespace i2c {
28
29enum class RegisterAddressSize {
30 k1Byte = 1,
31 k2Bytes = 2,
32 k4Bytes = 4,
33};
34
40class RegisterDevice : public Device {
41 public:
57 constexpr RegisterDevice(Initiator& initiator,
58 Address address,
59 endian register_address_order,
60 endian data_order,
61 RegisterAddressSize register_address_size)
62 : Device(initiator, address),
63 register_address_order_(register_address_order),
64 data_order_(data_order),
65 register_address_size_(register_address_size) {}
66
81 constexpr RegisterDevice(Initiator& initiator,
82 Address address,
83 endian order,
84 RegisterAddressSize register_address_size)
85 : Device(initiator, address),
86 register_address_order_(order),
87 data_order_(order),
88 register_address_size_(register_address_size) {}
89
133 Status WriteRegisters(uint32_t register_address,
134 ConstByteSpan register_data,
135 ByteSpan buffer,
137
140 Status WriteRegisters8(uint32_t register_address,
141 span<const uint8_t> register_data,
142 ByteSpan buffer,
144
147 Status WriteRegisters16(uint32_t register_address,
148 span<const uint16_t> register_data,
149 ByteSpan buffer,
151
154 Status WriteRegisters32(uint32_t register_address,
155 span<const uint32_t> register_data,
156 ByteSpan buffer,
158
196 Status ReadRegisters(uint32_t register_address,
197 ByteSpan return_data,
199
202 Status ReadRegisters8(uint32_t register_address,
203 span<uint8_t> return_data,
205
208 Status ReadRegisters16(uint32_t register_address,
209 span<uint16_t> return_data,
211
214 Status ReadRegisters32(uint32_t register_address,
215 span<uint32_t> return_data,
217
253 Status WriteRegister(uint32_t register_address,
254 std::byte register_data,
256
259 Status WriteRegister8(uint32_t register_address,
260 uint8_t register_data,
262
265 Status WriteRegister16(uint32_t register_address,
266 uint16_t register_data,
268
271 Status WriteRegister32(uint32_t register_address,
272 uint32_t register_data,
274
307 Result<std::byte> ReadRegister(uint32_t register_address,
309
312 Result<uint8_t> ReadRegister8(uint32_t register_address,
314
317 Result<uint16_t> ReadRegister16(uint32_t register_address,
319
322 Result<uint32_t> ReadRegister32(uint32_t register_address,
324
325 private:
326 // Helper write registers.
327 Status WriteRegisters(uint32_t register_address,
328 ConstByteSpan register_data,
329 const size_t register_data_size,
330 ByteSpan buffer,
332
333 const endian register_address_order_;
334 const endian data_order_;
335 const RegisterAddressSize register_address_size_;
336};
337
339 uint32_t register_address,
340 ConstByteSpan register_data,
341 ByteSpan buffer,
343 return WriteRegisters(register_address,
344 register_data,
345 sizeof(decltype(register_data)::value_type),
346 buffer,
347 timeout);
348}
349
351 uint32_t register_address,
352 span<const uint8_t> register_data,
353 ByteSpan buffer,
355 return WriteRegisters(register_address,
356 as_bytes(register_data),
357 sizeof(decltype(register_data)::value_type),
358 buffer,
359 timeout);
360}
361
363 uint32_t register_address,
364 span<const uint16_t> register_data,
365 ByteSpan buffer,
367 return WriteRegisters(register_address,
368 as_bytes(register_data),
369 sizeof(decltype(register_data)::value_type),
370 buffer,
371 timeout);
372}
373
375 uint32_t register_address,
376 span<const uint32_t> register_data,
377 ByteSpan buffer,
379 return WriteRegisters(register_address,
380 as_bytes(register_data),
381 sizeof(decltype(register_data)::value_type),
382 buffer,
383 timeout);
384}
385
387 uint32_t register_address,
388 std::byte register_data,
390 std::array<std::byte, sizeof(register_data) + sizeof(register_address)>
391 byte_buffer;
392 return WriteRegisters(register_address,
393 span(&register_data, 1),
394 sizeof(register_data),
395 byte_buffer,
396 timeout);
397}
398
400 uint32_t register_address,
401 uint8_t register_data,
403 std::array<std::byte, sizeof(register_data) + sizeof(register_address)>
404 byte_buffer;
405 return WriteRegisters(register_address,
406 as_bytes(span(&register_data, 1)),
407 sizeof(register_data),
408 byte_buffer,
409 timeout);
410}
411
413 uint32_t register_address,
414 uint16_t register_data,
416 std::array<std::byte, sizeof(register_data) + sizeof(register_address)>
417 byte_buffer;
418 return WriteRegisters(register_address,
419 as_bytes(span(&register_data, 1)),
420 sizeof(register_data),
421 byte_buffer,
422 timeout);
423}
424
426 uint32_t register_address,
427 uint32_t register_data,
429 std::array<std::byte, sizeof(register_data) + sizeof(register_address)>
430 byte_buffer;
431 return WriteRegisters(register_address,
432 as_bytes(span(&register_data, 1)),
433 sizeof(register_data),
434 byte_buffer,
435 timeout);
436}
437
439 uint32_t register_address,
440 span<uint8_t> return_data,
442 // For a single byte, there's no endian data, and so we can return the
443 // data as is.
444 return ReadRegisters(
445 register_address, as_writable_bytes(return_data), timeout);
446}
447
449 uint32_t register_address,
450 span<uint16_t> return_data,
452 PW_TRY(
453 ReadRegisters(register_address, as_writable_bytes(return_data), timeout));
454
455 // Post process endian information.
456 for (uint16_t& register_value : return_data) {
457 register_value = bytes::ReadInOrder<uint16_t>(data_order_, &register_value);
458 }
459
460 return pw::OkStatus();
461}
462
464 uint32_t register_address,
465 span<uint32_t> return_data,
467 PW_TRY(
468 ReadRegisters(register_address, as_writable_bytes(return_data), timeout));
469
470 // TODO: b/185952662 - Extend endian in pw_byte to support this conversion
471 // as optimization.
472 // Post process endian information.
473 for (uint32_t& register_value : return_data) {
474 register_value = bytes::ReadInOrder<uint32_t>(data_order_, &register_value);
475 }
476
477 return pw::OkStatus();
478}
479
480inline Result<std::byte> RegisterDevice::ReadRegister(
481 uint32_t register_address, chrono::SystemClock::duration timeout) {
482 std::byte data = {};
483 PW_TRY(ReadRegisters(register_address, span(&data, 1), timeout));
484 return data;
485}
486
487inline Result<uint8_t> RegisterDevice::ReadRegister8(
488 uint32_t register_address, chrono::SystemClock::duration timeout) {
489 uint8_t data = 0;
490 PW_TRY(ReadRegisters8(register_address, span(&data, 1), timeout));
491 return data;
492}
493
494inline Result<uint16_t> RegisterDevice::ReadRegister16(
495 uint32_t register_address, chrono::SystemClock::duration timeout) {
496 std::array<uint16_t, 1> data = {};
497 PW_TRY(ReadRegisters16(register_address, data, timeout));
498 return data[0];
499}
500
501inline Result<uint32_t> RegisterDevice::ReadRegister32(
502 uint32_t register_address, chrono::SystemClock::duration timeout) {
503 std::array<uint32_t, 1> data = {};
504 PW_TRY(ReadRegisters32(register_address, data, timeout));
505 return data[0];
506}
507
508} // namespace i2c
509} // namespace pw
510
511// TODO (zengk): Register modification.
Definition: status.h:85
Definition: address.h:39
Definition: device.h:36
The common, base driver interface for initiating thread-safe transactions with devices on an I2C bus....
Definition: initiator.h:49
Definition: register_device.h:40
Status WriteRegister8(uint32_t register_address, uint8_t register_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:399
Result< std::byte > ReadRegister(uint32_t register_address, chrono::SystemClock::duration timeout)
Definition: register_device.h:480
Status WriteRegisters8(uint32_t register_address, span< const uint8_t > register_data, ByteSpan buffer, chrono::SystemClock::duration timeout)
Definition: register_device.h:350
Status ReadRegisters(uint32_t register_address, ByteSpan return_data, chrono::SystemClock::duration timeout)
Result< uint16_t > ReadRegister16(uint32_t register_address, chrono::SystemClock::duration timeout)
Definition: register_device.h:494
Status WriteRegister(uint32_t register_address, std::byte register_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:386
Status ReadRegisters8(uint32_t register_address, span< uint8_t > return_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:438
constexpr RegisterDevice(Initiator &initiator, Address address, endian register_address_order, endian data_order, RegisterAddressSize register_address_size)
Definition: register_device.h:57
Result< uint32_t > ReadRegister32(uint32_t register_address, chrono::SystemClock::duration timeout)
Definition: register_device.h:501
Result< uint8_t > ReadRegister8(uint32_t register_address, chrono::SystemClock::duration timeout)
Definition: register_device.h:487
Status ReadRegisters32(uint32_t register_address, span< uint32_t > return_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:463
Status WriteRegister16(uint32_t register_address, uint16_t register_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:412
Status WriteRegisters16(uint32_t register_address, span< const uint16_t > register_data, ByteSpan buffer, chrono::SystemClock::duration timeout)
Definition: register_device.h:362
Status WriteRegisters(uint32_t register_address, ConstByteSpan register_data, ByteSpan buffer, chrono::SystemClock::duration timeout)
Definition: register_device.h:338
Status WriteRegisters32(uint32_t register_address, span< const uint32_t > register_data, ByteSpan buffer, chrono::SystemClock::duration timeout)
Definition: register_device.h:374
Status ReadRegisters16(uint32_t register_address, span< uint16_t > return_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:448
Status WriteRegister32(uint32_t register_address, uint32_t register_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:425
constexpr RegisterDevice(Initiator &initiator, Address address, endian order, RegisterAddressSize register_address_size)
Definition: register_device.h:81
Provides basic helpers for reading and writing UTF-8 encoded strings.
Definition: alignment.h:27
constexpr Status OkStatus()
Definition: status.h:234
std::chrono::duration< rep, period > duration
Alias for durations representable with this clock.
Definition: system_clock.h:86