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