xref: /aosp_15_r20/external/pigweed/pw_spi/docs.rst (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker.. _module-pw_spi:
2*61c4878aSAndroid Build Coastguard Worker
3*61c4878aSAndroid Build Coastguard Worker======
4*61c4878aSAndroid Build Coastguard Workerpw_spi
5*61c4878aSAndroid Build Coastguard Worker======
6*61c4878aSAndroid Build Coastguard WorkerPigweed's SPI module provides a set of interfaces for communicating with SPI
7*61c4878aSAndroid Build Coastguard Workerresponders attached to a target. It also provides an interface for implementing
8*61c4878aSAndroid Build Coastguard WorkerSPI responders.
9*61c4878aSAndroid Build Coastguard Worker
10*61c4878aSAndroid Build Coastguard Worker--------
11*61c4878aSAndroid Build Coastguard WorkerOverview
12*61c4878aSAndroid Build Coastguard Worker--------
13*61c4878aSAndroid Build Coastguard WorkerThe ``pw_spi`` module provides a series of interfaces that facilitate the
14*61c4878aSAndroid Build Coastguard Workerdevelopment of SPI responder drivers that are abstracted from the target's
15*61c4878aSAndroid Build Coastguard WorkerSPI hardware implementation.  The interface consists of these main classes:
16*61c4878aSAndroid Build Coastguard Worker
17*61c4878aSAndroid Build Coastguard Worker- ``pw::spi::Initiator`` - Interface for configuring a SPI bus, and using it
18*61c4878aSAndroid Build Coastguard Worker  to transmit and receive data.
19*61c4878aSAndroid Build Coastguard Worker- ``pw::spi::ChipSelector`` - Interface for enabling/disabling a SPI
20*61c4878aSAndroid Build Coastguard Worker  responder attached to the bus.
21*61c4878aSAndroid Build Coastguard Worker- ``pw::spi::Device`` - primary HAL interface used to interact with a SPI
22*61c4878aSAndroid Build Coastguard Worker  responder.
23*61c4878aSAndroid Build Coastguard Worker- ``pw::spi::Responder`` - Interface for implementing a SPI responder.
24*61c4878aSAndroid Build Coastguard Worker
25*61c4878aSAndroid Build Coastguard Worker``pw_spi`` relies on a target-specific implementations of
26*61c4878aSAndroid Build Coastguard Worker``pw::spi::Initiator`` and ``pw::spi::ChipSelector`` to be defined, and
27*61c4878aSAndroid Build Coastguard Workerinjected into ``pw::spi::Device`` objects which are used to communicate with a
28*61c4878aSAndroid Build Coastguard Workergiven responder attached to a target's SPI bus.
29*61c4878aSAndroid Build Coastguard Worker
30*61c4878aSAndroid Build Coastguard Worker--------
31*61c4878aSAndroid Build Coastguard WorkerExamples
32*61c4878aSAndroid Build Coastguard Worker--------
33*61c4878aSAndroid Build Coastguard Worker
34*61c4878aSAndroid Build Coastguard WorkerConstructing a SPI Device
35*61c4878aSAndroid Build Coastguard Worker=========================
36*61c4878aSAndroid Build Coastguard Worker
37*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
38*61c4878aSAndroid Build Coastguard Worker
39*61c4878aSAndroid Build Coastguard Worker   constexpr pw::spi::Config kConfig = {
40*61c4878aSAndroid Build Coastguard Worker       .polarity = pw::spi::ClockPolarity::kActiveHigh,
41*61c4878aSAndroid Build Coastguard Worker       .phase = pw::spi::ClockPhase::kRisingEdge,
42*61c4878aSAndroid Build Coastguard Worker       .bits_per_word = pw::spi::BitsPerWord(8),
43*61c4878aSAndroid Build Coastguard Worker       .bit_order = pw::spi::BitOrder::kLsbFirst,
44*61c4878aSAndroid Build Coastguard Worker   };
45*61c4878aSAndroid Build Coastguard Worker
46*61c4878aSAndroid Build Coastguard Worker   auto initiator = pw::spi::MyInitator();
47*61c4878aSAndroid Build Coastguard Worker   auto mutex = pw::sync::VirtualMutex();
48*61c4878aSAndroid Build Coastguard Worker   auto selector = pw::spi::MyChipSelector();
49*61c4878aSAndroid Build Coastguard Worker
50*61c4878aSAndroid Build Coastguard Worker   auto device = pw::spi::Device(
51*61c4878aSAndroid Build Coastguard Worker      pw::sync::Borrowable<Initiator>(initiator, mutex), kConfig, selector);
52*61c4878aSAndroid Build Coastguard Worker
53*61c4878aSAndroid Build Coastguard WorkerThis example demonstrates the construction of a ``pw::spi::Device`` from its
54*61c4878aSAndroid Build Coastguard Workerobject dependencies and configuration data; where ``MyDevice`` and
55*61c4878aSAndroid Build Coastguard Worker``MyChipSelector`` are concrete implementations of the ``pw::spi::Initiator``
56*61c4878aSAndroid Build Coastguard Workerand ``pw::spi::ChipSelector`` interfaces, respectively.
57*61c4878aSAndroid Build Coastguard Worker
58*61c4878aSAndroid Build Coastguard WorkerThe use of ``pw::sync::Borrowable`` in the interface provides a
59*61c4878aSAndroid Build Coastguard Workermutual-exclusion wrapper for the injected ``pw::spi::Initiator``, ensuring
60*61c4878aSAndroid Build Coastguard Workerthat transactions cannot be interrupted or corrupted by other concurrent
61*61c4878aSAndroid Build Coastguard Workerworkloads making use of the same SPI bus.
62*61c4878aSAndroid Build Coastguard Worker
63*61c4878aSAndroid Build Coastguard WorkerOnce constructed, the ``device`` object can then be passed to functions used to
64*61c4878aSAndroid Build Coastguard Workerperform SPI transfers with a target responder.
65*61c4878aSAndroid Build Coastguard Worker
66*61c4878aSAndroid Build Coastguard WorkerPerforming a Transfer
67*61c4878aSAndroid Build Coastguard Worker=====================
68*61c4878aSAndroid Build Coastguard Worker
69*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
70*61c4878aSAndroid Build Coastguard Worker
71*61c4878aSAndroid Build Coastguard Worker   pw::Result<SensorData> ReadSensorData(pw::spi::Device& device) {
72*61c4878aSAndroid Build Coastguard Worker     std::array<std::byte, 16> raw_sensor_data;
73*61c4878aSAndroid Build Coastguard Worker     constexpr std::array<std::byte, 2> kAccelReportCommand = {
74*61c4878aSAndroid Build Coastguard Worker         std::byte{0x13}, std::byte{0x37}};
75*61c4878aSAndroid Build Coastguard Worker
76*61c4878aSAndroid Build Coastguard Worker     // This device supports full-duplex transfers
77*61c4878aSAndroid Build Coastguard Worker     PW_TRY(device.WriteRead(kAccelReportCommand, raw_sensor_data));
78*61c4878aSAndroid Build Coastguard Worker     return UnpackSensorData(raw_sensor_data);
79*61c4878aSAndroid Build Coastguard Worker   }
80*61c4878aSAndroid Build Coastguard Worker
81*61c4878aSAndroid Build Coastguard WorkerThe ``ReadSensorData()`` function implements a driver function for a contrived
82*61c4878aSAndroid Build Coastguard WorkerSPI accelerometer.  The function performs a full-duplex transfer with the
83*61c4878aSAndroid Build Coastguard Workerdevice to read its current data.
84*61c4878aSAndroid Build Coastguard Worker
85*61c4878aSAndroid Build Coastguard WorkerAs this function relies on the ``device`` object that abstracts the details
86*61c4878aSAndroid Build Coastguard Workerof bus-access and chip-selection, the function is portable to any target
87*61c4878aSAndroid Build Coastguard Workerthat implements its underlying interfaces.
88*61c4878aSAndroid Build Coastguard Worker
89*61c4878aSAndroid Build Coastguard WorkerPerforming a Multi-part Transaction
90*61c4878aSAndroid Build Coastguard Worker===================================
91*61c4878aSAndroid Build Coastguard Worker
92*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
93*61c4878aSAndroid Build Coastguard Worker
94*61c4878aSAndroid Build Coastguard Worker   pw::Result<SensorData> ReadSensorData(pw::spi::Device& device) {
95*61c4878aSAndroid Build Coastguard Worker     std::array<std::byte, 16> raw_sensor_data;
96*61c4878aSAndroid Build Coastguard Worker     constexpr std::array<std::byte, 2> kAccelReportCommand = {
97*61c4878aSAndroid Build Coastguard Worker         std::byte{0x13}, std::byte{0x37}};
98*61c4878aSAndroid Build Coastguard Worker
99*61c4878aSAndroid Build Coastguard Worker     // Creation of the RAII `transaction` acquires exclusive access to the bus
100*61c4878aSAndroid Build Coastguard Worker     pw::spi::Device::Transaction transaction =
101*61c4878aSAndroid Build Coastguard Worker       device.StartTransaction(pw::spi::ChipSelectBehavior::kPerTransaction);
102*61c4878aSAndroid Build Coastguard Worker
103*61c4878aSAndroid Build Coastguard Worker     // This device only supports half-duplex transfers
104*61c4878aSAndroid Build Coastguard Worker     PW_TRY(transaction.Write(kAccelReportCommand));
105*61c4878aSAndroid Build Coastguard Worker     PW_TRY(transaction.Read(raw_sensor_data))
106*61c4878aSAndroid Build Coastguard Worker
107*61c4878aSAndroid Build Coastguard Worker     return UnpackSensorData(raw_sensor_data);
108*61c4878aSAndroid Build Coastguard Worker
109*61c4878aSAndroid Build Coastguard Worker     // Destruction of RAII `transaction` object releases lock on the bus
110*61c4878aSAndroid Build Coastguard Worker   }
111*61c4878aSAndroid Build Coastguard Worker
112*61c4878aSAndroid Build Coastguard WorkerThe code above is similar to the previous example, but makes use of the
113*61c4878aSAndroid Build Coastguard Worker``Transaction`` API in ``pw::spi::Device`` to perform separate, half-duplex
114*61c4878aSAndroid Build Coastguard Worker``Write()`` and ``Read()`` transfers, as is required by the sensor in this
115*61c4878aSAndroid Build Coastguard Workerexample.
116*61c4878aSAndroid Build Coastguard Worker
117*61c4878aSAndroid Build Coastguard WorkerThe use of the RAII ``transaction`` object in this example guarantees that
118*61c4878aSAndroid Build Coastguard Workerno other thread can perform transfers on the same SPI bus
119*61c4878aSAndroid Build Coastguard Worker(``pw::spi::Initiator``) until it goes out-of-scope.
120*61c4878aSAndroid Build Coastguard Worker
121*61c4878aSAndroid Build Coastguard Worker------------------
122*61c4878aSAndroid Build Coastguard Workerpw::spi Interfaces
123*61c4878aSAndroid Build Coastguard Worker------------------
124*61c4878aSAndroid Build Coastguard WorkerThe SPI API consists of the following components:
125*61c4878aSAndroid Build Coastguard Worker
126*61c4878aSAndroid Build Coastguard Worker- The ``pw::spi::Initiator`` interface, and its associated configuration data
127*61c4878aSAndroid Build Coastguard Worker  structs.
128*61c4878aSAndroid Build Coastguard Worker- The ``pw::spi::ChipSelector`` interface.
129*61c4878aSAndroid Build Coastguard Worker- The ``pw::spi::Device`` class.
130*61c4878aSAndroid Build Coastguard Worker- The ``pw::spi::Responder`` interface.
131*61c4878aSAndroid Build Coastguard Worker
132*61c4878aSAndroid Build Coastguard Workerpw::spi::Initiator
133*61c4878aSAndroid Build Coastguard Worker==================
134*61c4878aSAndroid Build Coastguard WorkerThe common interface for configuring a SPI bus, and initiating transfers using
135*61c4878aSAndroid Build Coastguard Workerit.
136*61c4878aSAndroid Build Coastguard Worker
137*61c4878aSAndroid Build Coastguard WorkerA concrete implementation of this interface class *must* be defined in order
138*61c4878aSAndroid Build Coastguard Workerto use ``pw_spi`` with a specific target.
139*61c4878aSAndroid Build Coastguard Worker
140*61c4878aSAndroid Build Coastguard WorkerThe ``spi::Initiator`` object configures the SPI bus to communicate with a
141*61c4878aSAndroid Build Coastguard Workerdefined set of common bus parameters that include:
142*61c4878aSAndroid Build Coastguard Worker
143*61c4878aSAndroid Build Coastguard Worker- clock polarity/phase
144*61c4878aSAndroid Build Coastguard Worker- bits-per-word (between 3-32 bits)
145*61c4878aSAndroid Build Coastguard Worker- bit ordering (LSB or MSB first)
146*61c4878aSAndroid Build Coastguard Worker
147*61c4878aSAndroid Build Coastguard WorkerThese bus configuration parameters are aggregated in the ``pw::spi::Config``
148*61c4878aSAndroid Build Coastguard Workerstructure, and passed to the ``pw::spi::Initiator`` via its ``Configure()``
149*61c4878aSAndroid Build Coastguard Workermethod.
150*61c4878aSAndroid Build Coastguard Worker
151*61c4878aSAndroid Build Coastguard Worker.. inclusive-language: disable
152*61c4878aSAndroid Build Coastguard Worker
153*61c4878aSAndroid Build Coastguard Worker.. Note:
154*61c4878aSAndroid Build Coastguard Worker
155*61c4878aSAndroid Build Coastguard Worker   Throughout ``pw_spi``, the terms "initiator" and "responder" are used to
156*61c4878aSAndroid Build Coastguard Worker   describe the two roles SPI devices can implement.  These terms correspond
157*61c4878aSAndroid Build Coastguard Worker   to the  "master" and "slave" roles described in legacy documentation
158*61c4878aSAndroid Build Coastguard Worker   related to the SPI protocol.
159*61c4878aSAndroid Build Coastguard Worker
160*61c4878aSAndroid Build Coastguard Worker.. inclusive-language: enable
161*61c4878aSAndroid Build Coastguard Worker
162*61c4878aSAndroid Build Coastguard Worker.. cpp:class:: pw::spi::Initiator
163*61c4878aSAndroid Build Coastguard Worker
164*61c4878aSAndroid Build Coastguard Worker   .. cpp:function:: Status Configure(const Config& config)
165*61c4878aSAndroid Build Coastguard Worker
166*61c4878aSAndroid Build Coastguard Worker      Configure the SPI bus to communicate using a specific set of properties,
167*61c4878aSAndroid Build Coastguard Worker      including the clock polarity, clock phase, bit-order, and bits-per-word.
168*61c4878aSAndroid Build Coastguard Worker
169*61c4878aSAndroid Build Coastguard Worker      Returns OkStatus() on success, and implementation-specific values on
170*61c4878aSAndroid Build Coastguard Worker      failure conditions
171*61c4878aSAndroid Build Coastguard Worker
172*61c4878aSAndroid Build Coastguard Worker   .. cpp:function:: Status WriteRead(ConstByteSpan write_buffer, ByteSpan read_buffer) = 0;
173*61c4878aSAndroid Build Coastguard Worker
174*61c4878aSAndroid Build Coastguard Worker      Perform a synchronous read/write operation on the SPI bus.  Data from the
175*61c4878aSAndroid Build Coastguard Worker      `write_buffer` object is written to the bus, while the `read_buffer` is
176*61c4878aSAndroid Build Coastguard Worker      populated with incoming data on the bus.  The operation will ensure that
177*61c4878aSAndroid Build Coastguard Worker      all requested data is written-to and read-from the bus. In the event the
178*61c4878aSAndroid Build Coastguard Worker      read buffer is smaller than the write buffer (or zero-size), any
179*61c4878aSAndroid Build Coastguard Worker      additional input bytes are discarded. In the event the write buffer is
180*61c4878aSAndroid Build Coastguard Worker      smaller than the read buffer (or zero size), the output is padded with
181*61c4878aSAndroid Build Coastguard Worker      0-bits for the remainder of the transfer.
182*61c4878aSAndroid Build Coastguard Worker
183*61c4878aSAndroid Build Coastguard Worker      Returns OkStatus() on success, and implementation-specific values on
184*61c4878aSAndroid Build Coastguard Worker      failure.
185*61c4878aSAndroid Build Coastguard Worker
186*61c4878aSAndroid Build Coastguard Workerpw::spi::ChipSelector
187*61c4878aSAndroid Build Coastguard Worker=====================
188*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::spi::ChipSelector
189*61c4878aSAndroid Build Coastguard Worker   :members:
190*61c4878aSAndroid Build Coastguard Worker
191*61c4878aSAndroid Build Coastguard Workerpw::spi::DigitalOutChipSelector
192*61c4878aSAndroid Build Coastguard Worker===============================
193*61c4878aSAndroid Build Coastguard Worker.. doxygenclass:: pw::spi::DigitalOutChipSelector
194*61c4878aSAndroid Build Coastguard Worker   :members:
195*61c4878aSAndroid Build Coastguard Worker
196*61c4878aSAndroid Build Coastguard Workerpw::spi::Device
197*61c4878aSAndroid Build Coastguard Worker===============
198*61c4878aSAndroid Build Coastguard WorkerThis is primary object used by a client to interact with a target SPI device.
199*61c4878aSAndroid Build Coastguard WorkerIt provides a wrapper for an injected ``pw::spi::Initiator`` object, using
200*61c4878aSAndroid Build Coastguard Workerits methods to configure the bus and perform individual SPI transfers.  The
201*61c4878aSAndroid Build Coastguard Workerinjected ``pw::spi::ChipSelector`` object is used internally to activate and
202*61c4878aSAndroid Build Coastguard Workerde-activate the device on-demand from within the data transfer methods.
203*61c4878aSAndroid Build Coastguard Worker
204*61c4878aSAndroid Build Coastguard WorkerThe ``Read()``/``Write()``/``WriteRead()`` methods provide support for
205*61c4878aSAndroid Build Coastguard Workerperforming individual transfers:  ``Read()`` and ``Write()`` perform
206*61c4878aSAndroid Build Coastguard Workerhalf-duplex operations, where ``WriteRead()`` provides support for
207*61c4878aSAndroid Build Coastguard Workerfull-duplex transfers.
208*61c4878aSAndroid Build Coastguard Worker
209*61c4878aSAndroid Build Coastguard WorkerThe ``StartTransaction()`` method provides support for performing multi-part
210*61c4878aSAndroid Build Coastguard Workertransfers consisting of a series of ``Read()``/``Write()``/``WriteRead()``
211*61c4878aSAndroid Build Coastguard Workercalls, during which the caller is guaranteed exclusive access to the
212*61c4878aSAndroid Build Coastguard Workerunderlying bus.  The ``Transaction`` objects returned from this method
213*61c4878aSAndroid Build Coastguard Workerimplements the RAII layer providing exclusive access to the bus; exclusive
214*61c4878aSAndroid Build Coastguard Workeraccess locking is released when the ``Transaction`` object is destroyed/goes
215*61c4878aSAndroid Build Coastguard Workerout of scope.
216*61c4878aSAndroid Build Coastguard Worker
217*61c4878aSAndroid Build Coastguard WorkerMutual-exclusion to the ``pw::spi::Initiator`` object is provided by the use of
218*61c4878aSAndroid Build Coastguard Workerthe ``pw::sync::Borrowable`` object, where the ``pw::spi::Initiator`` object is
219*61c4878aSAndroid Build Coastguard Worker"borrowed" for the duration of a transaction.
220*61c4878aSAndroid Build Coastguard Worker
221*61c4878aSAndroid Build Coastguard Worker.. cpp:class:: pw::spi::Device
222*61c4878aSAndroid Build Coastguard Worker
223*61c4878aSAndroid Build Coastguard Worker   .. cpp:function:: Status Read(Bytespan read_buffer)
224*61c4878aSAndroid Build Coastguard Worker
225*61c4878aSAndroid Build Coastguard Worker      Synchronously read data from the SPI responder until the provided
226*61c4878aSAndroid Build Coastguard Worker      `read_buffer` is full.
227*61c4878aSAndroid Build Coastguard Worker      This call will configure the bus and activate/deactivate chip select
228*61c4878aSAndroid Build Coastguard Worker      for the transfer
229*61c4878aSAndroid Build Coastguard Worker
230*61c4878aSAndroid Build Coastguard Worker      Note: This call will block in the event that other clients are currently
231*61c4878aSAndroid Build Coastguard Worker      performing transactions using the same SPI Initiator.
232*61c4878aSAndroid Build Coastguard Worker
233*61c4878aSAndroid Build Coastguard Worker      Returns OkStatus() on success, and implementation-specific values on
234*61c4878aSAndroid Build Coastguard Worker      failure.
235*61c4878aSAndroid Build Coastguard Worker
236*61c4878aSAndroid Build Coastguard Worker   .. cpp:function:: Status Write(ConstByteSpan write_buffer)
237*61c4878aSAndroid Build Coastguard Worker
238*61c4878aSAndroid Build Coastguard Worker      Synchronously write the contents of `write_buffer` to the SPI responder.
239*61c4878aSAndroid Build Coastguard Worker      This call will configure the bus and activate/deactivate chip select
240*61c4878aSAndroid Build Coastguard Worker      for the transfer
241*61c4878aSAndroid Build Coastguard Worker
242*61c4878aSAndroid Build Coastguard Worker      Note: This call will block in the event that other clients are currently
243*61c4878aSAndroid Build Coastguard Worker      performing transactions using the same SPI Initiator.
244*61c4878aSAndroid Build Coastguard Worker
245*61c4878aSAndroid Build Coastguard Worker      Returns OkStatus() on success, and implementation-specific values on
246*61c4878aSAndroid Build Coastguard Worker      failure.
247*61c4878aSAndroid Build Coastguard Worker
248*61c4878aSAndroid Build Coastguard Worker   .. cpp:function:: Status WriteRead(ConstByteSpan write_buffer, ByteSpan read_buffer)
249*61c4878aSAndroid Build Coastguard Worker
250*61c4878aSAndroid Build Coastguard Worker      Perform a synchronous read/write transfer with the SPI responder. Data
251*61c4878aSAndroid Build Coastguard Worker      from the `write_buffer` object is written to the bus, while the
252*61c4878aSAndroid Build Coastguard Worker      `read_buffer` is populated with incoming data on the bus.  In the event
253*61c4878aSAndroid Build Coastguard Worker      the read buffer is smaller than the write buffer (or zero-size), any
254*61c4878aSAndroid Build Coastguard Worker      additional input bytes are discarded. In the event the write buffer is
255*61c4878aSAndroid Build Coastguard Worker      smaller than the read buffer (or zero size), the output is padded with
256*61c4878aSAndroid Build Coastguard Worker      0-bits for the remainder of the transfer.
257*61c4878aSAndroid Build Coastguard Worker      This call will configure the bus and activate/deactivate chip select
258*61c4878aSAndroid Build Coastguard Worker      for the transfer
259*61c4878aSAndroid Build Coastguard Worker
260*61c4878aSAndroid Build Coastguard Worker      Note: This call will block in the event that other clients are currently
261*61c4878aSAndroid Build Coastguard Worker      performing transactions using the same SPI Initiator.
262*61c4878aSAndroid Build Coastguard Worker
263*61c4878aSAndroid Build Coastguard Worker      Returns OkStatus() on success, and implementation-specific values on
264*61c4878aSAndroid Build Coastguard Worker      failure.
265*61c4878aSAndroid Build Coastguard Worker
266*61c4878aSAndroid Build Coastguard Worker   .. cpp:function:: Transaction StartTransaction(ChipSelectBehavior behavior)
267*61c4878aSAndroid Build Coastguard Worker
268*61c4878aSAndroid Build Coastguard Worker      Begin a transaction with the SPI device.  This creates an RAII
269*61c4878aSAndroid Build Coastguard Worker      `Transaction` object that ensures that only one entity can access the
270*61c4878aSAndroid Build Coastguard Worker      underlying SPI bus (Initiator) for the object's duration. The `behavior`
271*61c4878aSAndroid Build Coastguard Worker      parameter provides a means for a client to select how the chip-select
272*61c4878aSAndroid Build Coastguard Worker      signal will be applied on Read/Write/WriteRead calls taking place with
273*61c4878aSAndroid Build Coastguard Worker      the Transaction object. A value of `kPerWriteRead` will activate/deactivate
274*61c4878aSAndroid Build Coastguard Worker      chip-select on each operation, while `kPerTransaction` will hold the
275*61c4878aSAndroid Build Coastguard Worker      chip-select active for the duration of the Transaction object.
276*61c4878aSAndroid Build Coastguard Worker
277*61c4878aSAndroid Build Coastguard Worker.. cpp:class:: pw::spi::Device::Transaction
278*61c4878aSAndroid Build Coastguard Worker
279*61c4878aSAndroid Build Coastguard Worker   .. cpp:function:: Status Read(Bytespan read_buffer)
280*61c4878aSAndroid Build Coastguard Worker
281*61c4878aSAndroid Build Coastguard Worker      Synchronously read data from the SPI responder until the provided
282*61c4878aSAndroid Build Coastguard Worker      `read_buffer` is full.
283*61c4878aSAndroid Build Coastguard Worker
284*61c4878aSAndroid Build Coastguard Worker      Returns OkStatus() on success, and implementation-specific values on
285*61c4878aSAndroid Build Coastguard Worker      failure.
286*61c4878aSAndroid Build Coastguard Worker
287*61c4878aSAndroid Build Coastguard Worker   .. cpp:function:: Status Write(ConstByteSpan write_buffer)
288*61c4878aSAndroid Build Coastguard Worker
289*61c4878aSAndroid Build Coastguard Worker      Synchronously write the contents of `write_buffer` to the SPI responder
290*61c4878aSAndroid Build Coastguard Worker
291*61c4878aSAndroid Build Coastguard Worker      Returns OkStatus() on success, and implementation-specific values on
292*61c4878aSAndroid Build Coastguard Worker      failure.
293*61c4878aSAndroid Build Coastguard Worker
294*61c4878aSAndroid Build Coastguard Worker   .. cpp:function:: Status WriteRead(ConstByteSpan write_buffer, ByteSpan read_buffer)
295*61c4878aSAndroid Build Coastguard Worker
296*61c4878aSAndroid Build Coastguard Worker      Perform a synchronous read/write transfer on the SPI bus.  Data from the
297*61c4878aSAndroid Build Coastguard Worker      `write_buffer` object is written to the bus, while the `read_buffer` is
298*61c4878aSAndroid Build Coastguard Worker      populated with incoming data on the bus.  The operation will ensure that
299*61c4878aSAndroid Build Coastguard Worker      all requested data is written-to and read-from the bus. In the event the
300*61c4878aSAndroid Build Coastguard Worker      read buffer is smaller than the write buffer (or zero-size), any
301*61c4878aSAndroid Build Coastguard Worker      additional input bytes are discarded. In the event the write buffer is
302*61c4878aSAndroid Build Coastguard Worker      smaller than the read buffer (or zero size), the output is padded with
303*61c4878aSAndroid Build Coastguard Worker      0-bits for the remainder of the transfer.
304*61c4878aSAndroid Build Coastguard Worker
305*61c4878aSAndroid Build Coastguard Worker      Returns OkStatus() on success, and implementation-specific values on
306*61c4878aSAndroid Build Coastguard Worker      failure.
307*61c4878aSAndroid Build Coastguard Worker
308*61c4878aSAndroid Build Coastguard Workerpw::spi::MockInitiator
309*61c4878aSAndroid Build Coastguard Worker======================
310*61c4878aSAndroid Build Coastguard WorkerA generic mocked backend for ``pw::spi::Initiator``. This is specifically
311*61c4878aSAndroid Build Coastguard Workerintended for use when developing drivers for SPI devices. This is structured
312*61c4878aSAndroid Build Coastguard Workeraround a set of 'transactions' where each transaction contains a write, read and
313*61c4878aSAndroid Build Coastguard Workera status. A transaction list can then be passed to the ``MockInitiator``, where
314*61c4878aSAndroid Build Coastguard Workereach consecutive call to read/write will iterate to the next transaction in the
315*61c4878aSAndroid Build Coastguard Workerlist. An example of this is shown below:
316*61c4878aSAndroid Build Coastguard Worker
317*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
318*61c4878aSAndroid Build Coastguard Worker
319*61c4878aSAndroid Build Coastguard Worker   using pw::spi::MakeExpectedTransactionlist;
320*61c4878aSAndroid Build Coastguard Worker   using pw::spi::MockInitiator;
321*61c4878aSAndroid Build Coastguard Worker   using pw::spi::MockWriteTransaction;
322*61c4878aSAndroid Build Coastguard Worker
323*61c4878aSAndroid Build Coastguard Worker   constexpr auto kExpectWrite1 = pw::bytes::Array<1, 2, 3, 4, 5>();
324*61c4878aSAndroid Build Coastguard Worker   constexpr auto kExpectWrite2 = pw::bytes::Array<3, 4, 5>();
325*61c4878aSAndroid Build Coastguard Worker   auto expected_transactions = MakeExpectedTransactionArray(
326*61c4878aSAndroid Build Coastguard Worker       {MockWriteTransaction(pw::OkStatus(), kExpectWrite1),
327*61c4878aSAndroid Build Coastguard Worker        MockWriteTransaction(pw::OkStatus(), kExpectWrite2)});
328*61c4878aSAndroid Build Coastguard Worker   MockInitiator spi_mock(expected_transactions);
329*61c4878aSAndroid Build Coastguard Worker
330*61c4878aSAndroid Build Coastguard Worker   // Begin driver code
331*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan write1 = kExpectWrite1;
332*61c4878aSAndroid Build Coastguard Worker   // write1 is ok as spi_mock expects {1, 2, 3, 4, 5} == {1, 2, 3, 4, 5}
333*61c4878aSAndroid Build Coastguard Worker   Status status = spi_mock.WriteRead(write1, ConstByteSpan());
334*61c4878aSAndroid Build Coastguard Worker
335*61c4878aSAndroid Build Coastguard Worker   // Takes the first two bytes from the expected array to build a mismatching
336*61c4878aSAndroid Build Coastguard Worker   // span to write.
337*61c4878aSAndroid Build Coastguard Worker   ConstByteSpan write2 = pw::span(kExpectWrite2).first(2);
338*61c4878aSAndroid Build Coastguard Worker   // write2 fails as spi_mock expects {3, 4, 5} != {3, 4}
339*61c4878aSAndroid Build Coastguard Worker   status = spi_mock.WriteRead(write2, ConstByteSpan());
340*61c4878aSAndroid Build Coastguard Worker   // End driver code
341*61c4878aSAndroid Build Coastguard Worker
342*61c4878aSAndroid Build Coastguard Worker   // Optionally check if the mocked transaction list has been exhausted.
343*61c4878aSAndroid Build Coastguard Worker   // Alternatively this is also called from MockInitiator::~MockInitiator().
344*61c4878aSAndroid Build Coastguard Worker   EXPECT_EQ(spi_mock.Finalize(), OkStatus());
345*61c4878aSAndroid Build Coastguard Worker
346*61c4878aSAndroid Build Coastguard Workerpw::spi::Responder
347*61c4878aSAndroid Build Coastguard Worker==================
348*61c4878aSAndroid Build Coastguard WorkerThe common interface for implementing a SPI responder. It provides a way to
349*61c4878aSAndroid Build Coastguard Workerrespond to SPI transactions coming from a SPI initiator in a non-target specific
350*61c4878aSAndroid Build Coastguard Workerway. A concrete implementation of the ``Responder`` class should be provided for
351*61c4878aSAndroid Build Coastguard Workerthe target hardware. Applications can then use it to implement their specific
352*61c4878aSAndroid Build Coastguard Workerprotocols.
353*61c4878aSAndroid Build Coastguard Worker
354*61c4878aSAndroid Build Coastguard Worker.. code-block:: cpp
355*61c4878aSAndroid Build Coastguard Worker
356*61c4878aSAndroid Build Coastguard Worker   MyResponder responder;
357*61c4878aSAndroid Build Coastguard Worker   responder.SetCompletionHandler([](ByteSpan rx_data, Status status) {
358*61c4878aSAndroid Build Coastguard Worker     // Handle incoming data from initiator.
359*61c4878aSAndroid Build Coastguard Worker     // ...
360*61c4878aSAndroid Build Coastguard Worker     // Prepare data to send back to initiator during next SPI transaction.
361*61c4878aSAndroid Build Coastguard Worker     responder.WriteReadAsync(tx_data, rx_data);
362*61c4878aSAndroid Build Coastguard Worker   });
363*61c4878aSAndroid Build Coastguard Worker
364*61c4878aSAndroid Build Coastguard Worker   // Prepare data to send back to initiator during next SPI transaction.
365*61c4878aSAndroid Build Coastguard Worker   responder.WriteReadAsync(tx_data, rx_data)
366*61c4878aSAndroid Build Coastguard Worker
367*61c4878aSAndroid Build Coastguard Worker.. toctree::
368*61c4878aSAndroid Build Coastguard Worker   :hidden:
369*61c4878aSAndroid Build Coastguard Worker   :maxdepth: 1
370*61c4878aSAndroid Build Coastguard Worker
371*61c4878aSAndroid Build Coastguard Worker   Backends <backends>
372