C/C++ API Reference
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
30
31enum class RegisterAddressSize {
32 k1Byte = 1,
33 k2Bytes = 2,
34 k4Bytes = 4,
35};
36
42class RegisterDevice : public Device {
43 public:
59 constexpr RegisterDevice(Initiator& initiator,
60 Address address,
61 endian register_address_order,
62 endian data_order,
63 RegisterAddressSize register_address_size)
64 : Device(initiator, address),
65 register_address_order_(register_address_order),
66 data_order_(data_order),
67 register_address_size_(register_address_size) {}
68
83 constexpr RegisterDevice(Initiator& initiator,
84 Address address,
85 endian order,
86 RegisterAddressSize register_address_size)
87 : Device(initiator, address),
88 register_address_order_(order),
89 data_order_(order),
90 register_address_size_(register_address_size) {}
91
124 Status WriteRegisters(uint32_t register_address,
125 ConstByteSpan register_data,
126 ByteSpan buffer,
128
131 Status WriteRegisters8(uint32_t register_address,
132 span<const uint8_t> register_data,
133 ByteSpan buffer,
135
138 Status WriteRegisters16(uint32_t register_address,
139 span<const uint16_t> register_data,
140 ByteSpan buffer,
142
145 Status WriteRegisters32(uint32_t register_address,
146 span<const uint32_t> register_data,
147 ByteSpan buffer,
149
177 Status ReadRegisters(uint32_t register_address,
178 ByteSpan return_data,
180
183 Status ReadRegisters8(uint32_t register_address,
184 span<uint8_t> return_data,
186
189 Status ReadRegisters16(uint32_t register_address,
190 span<uint16_t> return_data,
192
195 Status ReadRegisters32(uint32_t register_address,
196 span<uint32_t> return_data,
198
224 Status WriteRegister(uint32_t register_address,
225 std::byte register_data,
227
230 Status WriteRegister8(uint32_t register_address,
231 uint8_t register_data,
233
236 Status WriteRegister16(uint32_t register_address,
237 uint16_t register_data,
239
242 Status WriteRegister32(uint32_t register_address,
243 uint32_t register_data,
245
268 Result<std::byte> ReadRegister(uint32_t register_address,
270
273 Result<uint8_t> ReadRegister8(uint32_t register_address,
275
278 Result<uint16_t> ReadRegister16(uint32_t register_address,
280
283 Result<uint32_t> ReadRegister32(uint32_t register_address,
285
286 private:
287 // Helper write registers.
288 Status WriteRegisters(uint32_t register_address,
289 ConstByteSpan register_data,
290 const size_t register_data_size,
291 ByteSpan buffer,
293
294 const endian register_address_order_;
295 const endian data_order_;
296 const RegisterAddressSize register_address_size_;
297};
298
300 uint32_t register_address,
301 ConstByteSpan register_data,
302 ByteSpan buffer,
304 return WriteRegisters(register_address,
305 register_data,
306 sizeof(decltype(register_data)::value_type),
307 buffer,
308 timeout);
309}
310
312 uint32_t register_address,
313 span<const uint8_t> register_data,
314 ByteSpan buffer,
316 return WriteRegisters(register_address,
317 as_bytes(register_data),
318 sizeof(decltype(register_data)::value_type),
319 buffer,
320 timeout);
321}
322
324 uint32_t register_address,
325 span<const uint16_t> register_data,
326 ByteSpan buffer,
328 return WriteRegisters(register_address,
329 as_bytes(register_data),
330 sizeof(decltype(register_data)::value_type),
331 buffer,
332 timeout);
333}
334
336 uint32_t register_address,
337 span<const uint32_t> register_data,
338 ByteSpan buffer,
340 return WriteRegisters(register_address,
341 as_bytes(register_data),
342 sizeof(decltype(register_data)::value_type),
343 buffer,
344 timeout);
345}
346
348 uint32_t register_address,
349 std::byte register_data,
351 std::array<std::byte, sizeof(register_data) + sizeof(register_address)>
352 byte_buffer;
353 return WriteRegisters(register_address,
354 span(&register_data, 1),
355 sizeof(register_data),
356 byte_buffer,
357 timeout);
358}
359
361 uint32_t register_address,
362 uint8_t register_data,
364 std::array<std::byte, sizeof(register_data) + sizeof(register_address)>
365 byte_buffer;
366 return WriteRegisters(register_address,
367 as_bytes(span(&register_data, 1)),
368 sizeof(register_data),
369 byte_buffer,
370 timeout);
371}
372
374 uint32_t register_address,
375 uint16_t register_data,
377 std::array<std::byte, sizeof(register_data) + sizeof(register_address)>
378 byte_buffer;
379 return WriteRegisters(register_address,
380 as_bytes(span(&register_data, 1)),
381 sizeof(register_data),
382 byte_buffer,
383 timeout);
384}
385
387 uint32_t register_address,
388 uint32_t register_data,
390 std::array<std::byte, sizeof(register_data) + sizeof(register_address)>
391 byte_buffer;
392 return WriteRegisters(register_address,
393 as_bytes(span(&register_data, 1)),
394 sizeof(register_data),
395 byte_buffer,
396 timeout);
397}
398
400 uint32_t register_address,
401 span<uint8_t> return_data,
403 // For a single byte, there's no endian data, and so we can return the
404 // data as is.
405 return ReadRegisters(
406 register_address, as_writable_bytes(return_data), timeout);
407}
408
410 uint32_t register_address,
411 span<uint16_t> return_data,
413 PW_TRY(
414 ReadRegisters(register_address, as_writable_bytes(return_data), timeout));
415
416 // Post process endian information.
417 for (uint16_t& register_value : return_data) {
418 register_value = bytes::ReadInOrder<uint16_t>(data_order_, &register_value);
419 }
420
421 return pw::OkStatus();
422}
423
425 uint32_t register_address,
426 span<uint32_t> return_data,
428 PW_TRY(
429 ReadRegisters(register_address, as_writable_bytes(return_data), timeout));
430
431 // TODO: b/185952662 - Extend endian in pw_byte to support this conversion
432 // as optimization.
433 // Post process endian information.
434 for (uint32_t& register_value : return_data) {
435 register_value = bytes::ReadInOrder<uint32_t>(data_order_, &register_value);
436 }
437
438 return pw::OkStatus();
439}
440
442 uint32_t register_address, chrono::SystemClock::duration timeout) {
443 std::byte data = {};
444 PW_TRY(ReadRegisters(register_address, span(&data, 1), timeout));
445 return data;
446}
447
449 uint32_t register_address, chrono::SystemClock::duration timeout) {
450 uint8_t data = 0;
451 PW_TRY(ReadRegisters8(register_address, span(&data, 1), timeout));
452 return data;
453}
454
456 uint32_t register_address, chrono::SystemClock::duration timeout) {
457 std::array<uint16_t, 1> data = {};
458 PW_TRY(ReadRegisters16(register_address, data, timeout));
459 return data[0];
460}
461
463 uint32_t register_address, chrono::SystemClock::duration timeout) {
464 std::array<uint32_t, 1> data = {};
465 PW_TRY(ReadRegisters32(register_address, data, timeout));
466 return data[0];
467}
468
469} // namespace i2c
470} // namespace pw
471
472// TODO (zengk): Register modification.
Definition: result.h:143
Definition: status.h:120
Definition: address.h:42
Definition: device.h:38
The common, base driver interface for initiating thread-safe transactions with devices on an I2C bus....
Definition: initiator.h:52
Definition: register_device.h:42
std::chrono::duration< rep, period > duration
Alias for durations representable with this clock.
Definition: system_clock.h:90
Status WriteRegister8(uint32_t register_address, uint8_t register_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:360
Result< std::byte > ReadRegister(uint32_t register_address, chrono::SystemClock::duration timeout)
Definition: register_device.h:441
Status WriteRegisters8(uint32_t register_address, span< const uint8_t > register_data, ByteSpan buffer, chrono::SystemClock::duration timeout)
Definition: register_device.h:311
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:455
Status WriteRegister(uint32_t register_address, std::byte register_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:347
Status ReadRegisters8(uint32_t register_address, span< uint8_t > return_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:399
constexpr RegisterDevice(Initiator &initiator, Address address, endian register_address_order, endian data_order, RegisterAddressSize register_address_size)
Definition: register_device.h:59
Result< uint32_t > ReadRegister32(uint32_t register_address, chrono::SystemClock::duration timeout)
Definition: register_device.h:462
Result< uint8_t > ReadRegister8(uint32_t register_address, chrono::SystemClock::duration timeout)
Definition: register_device.h:448
Status ReadRegisters32(uint32_t register_address, span< uint32_t > return_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:424
Status WriteRegister16(uint32_t register_address, uint16_t register_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:373
Status WriteRegisters16(uint32_t register_address, span< const uint16_t > register_data, ByteSpan buffer, chrono::SystemClock::duration timeout)
Definition: register_device.h:323
Status WriteRegisters(uint32_t register_address, ConstByteSpan register_data, ByteSpan buffer, chrono::SystemClock::duration timeout)
Definition: register_device.h:299
Status WriteRegisters32(uint32_t register_address, span< const uint32_t > register_data, ByteSpan buffer, chrono::SystemClock::duration timeout)
Definition: register_device.h:335
Status ReadRegisters16(uint32_t register_address, span< uint16_t > return_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:409
Status WriteRegister32(uint32_t register_address, uint32_t register_data, chrono::SystemClock::duration timeout)
Definition: register_device.h:386
constexpr RegisterDevice(Initiator &initiator, Address address, endian order, RegisterAddressSize register_address_size)
Definition: register_device.h:83
#define PW_TRY(expr)
Returns early if expr is a non-OK Status or Result.
Definition: try.h:27
constexpr Status OkStatus()
Definition: status.h:450
The Pigweed namespace.
Definition: alignment.h:27