xref: /aosp_15_r20/external/pigweed/pw_i2c/public/pw_i2c/device.h (revision 61c4878ac05f98d0ceed94b57d316916de578985)
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 //
15 #pragma once
16 
17 #include "pw_bytes/span.h"
18 #include "pw_chrono/system_clock.h"
19 #include "pw_i2c/address.h"
20 #include "pw_i2c/initiator.h"
21 #include "pw_status/status.h"
22 
23 namespace pw {
24 namespace i2c {
25 
26 /// The common interface for generic I2C devices. Reads and writes arbitrary
27 /// chunks of data over an I2C bus to an I2C device. This class contains
28 /// `pw::i2c::Address` and wraps the `pw::i2c::Initiator` API. Only works
29 /// with devices that have a single device address.
30 ///
31 /// `pw::i2c::Device` is intended to represent ownership of a specific
32 /// responder. Individual transactions are atomic but there's no synchronization
33 /// for sequences of transactions. Therefore, shared access should be faciliated
34 /// with higher-level application abstractions. To help enforce this,
35 /// `pw::i2c::Device` instances are only movable and not copyable.
36 class Device {
37  public:
38   /// Creates a `pw::i2c::Device` instance.
39   ///
40   /// The address for the I2C device is set in this constructor and can't be
41   /// modified later.
42   ///
43   /// @param[in] initiator A reference to a `pw::i2c::Initiator` instance.
44   ///
45   /// @param[in] device_address The address of the I2C device.
46   ///
47   /// @returns A `pw::i2c::Device` instance.
Device(Initiator & initiator,Address device_address)48   constexpr Device(Initiator& initiator, Address device_address)
49       : initiator_(initiator), device_address_(device_address) {}
50 
51   Device(const Device&) = delete;
52   Device(Device&&) = default;
53   ~Device() = default;
54 
55   /// Wraps `pw::i2c::Initiator::WriteReadFor`.
WriteReadFor(ConstByteSpan tx_buffer,ByteSpan rx_buffer,chrono::SystemClock::duration timeout)56   Status WriteReadFor(ConstByteSpan tx_buffer,
57                       ByteSpan rx_buffer,
58                       chrono::SystemClock::duration timeout) {
59     return initiator_.WriteReadFor(
60         device_address_, tx_buffer, rx_buffer, timeout);
61   }
62   /// Wraps the variation of `pw::i2c::Initiator::WriteReadFor` that accepts
63   /// explicit sizes for the amount of bytes to write to the device and read
64   /// from the device.
WriteReadFor(const void * tx_buffer,size_t tx_size_bytes,void * rx_buffer,size_t rx_size_bytes,chrono::SystemClock::duration timeout)65   Status WriteReadFor(const void* tx_buffer,
66                       size_t tx_size_bytes,
67                       void* rx_buffer,
68                       size_t rx_size_bytes,
69                       chrono::SystemClock::duration timeout) {
70     return initiator_.WriteReadFor(device_address_,
71                                    tx_buffer,
72                                    tx_size_bytes,
73                                    rx_buffer,
74                                    rx_size_bytes,
75                                    timeout);
76   }
77 
78   /// Wraps `pw::i2c::Initiator::WriteFor`.
WriteFor(ConstByteSpan tx_buffer,chrono::SystemClock::duration timeout)79   Status WriteFor(ConstByteSpan tx_buffer,
80                   chrono::SystemClock::duration timeout) {
81     return initiator_.WriteFor(device_address_, tx_buffer, timeout);
82   }
83   /// Wraps the variation of `pw::i2c::Initiator::WriteFor` that accepts an
84   /// explicit size for the amount of bytes to write to the device.
WriteFor(const void * tx_buffer,size_t tx_size_bytes,chrono::SystemClock::duration timeout)85   Status WriteFor(const void* tx_buffer,
86                   size_t tx_size_bytes,
87                   chrono::SystemClock::duration timeout) {
88     return initiator_.WriteFor(
89         device_address_, tx_buffer, tx_size_bytes, timeout);
90   }
91 
92   /// Wraps `pw::i2c::Initiator::ReadFor`.
ReadFor(ByteSpan rx_buffer,chrono::SystemClock::duration timeout)93   Status ReadFor(ByteSpan rx_buffer, chrono::SystemClock::duration timeout) {
94     return initiator_.ReadFor(device_address_, rx_buffer, timeout);
95   }
96   /// Wraps the variation of `pw::i2c::Initiator::ReadFor` that accepts an
97   /// explicit size for the amount of bytes to read from the device.
ReadFor(void * rx_buffer,size_t rx_size_bytes,chrono::SystemClock::duration timeout)98   Status ReadFor(void* rx_buffer,
99                  size_t rx_size_bytes,
100                  chrono::SystemClock::duration timeout) {
101     return initiator_.ReadFor(
102         device_address_, rx_buffer, rx_size_bytes, timeout);
103   }
104 
105   /// Wraps `pw::i2c::Initiator::ProbeDeviceFor`.
ProbeFor(chrono::SystemClock::duration timeout)106   Status ProbeFor(chrono::SystemClock::duration timeout) {
107     return initiator_.ProbeDeviceFor(device_address_, timeout);
108   }
109 
110  private:
111   Initiator& initiator_;
112   const Address device_address_;
113 };
114 
115 }  // namespace i2c
116 }  // namespace pw
117