Drv FPP Interfaces
The Drv interfaces are a set of .fpp files that define FPP interfaces for driver components to implement. An FPP interface is an FPP file that defines a set of ports. A component that implements an FPP interface must implement handlers for the input ports and has access to the output ports of the interface.
Drv.ByteStreamDriver
The Drv.ByteStreamDriver is an interface for writing and reading to a driver that acts as a byte stream, such as TCP/UDP/UART. The Drv::TcpClient driver implements this interface.
Drv.Gpio
The Drv.Gpio is an interface for writing and reading a single GPIO bit, and signaling a GPIO interrupt. The Drv::LinuxGpioDriver driver implements this interface.
Drv.I2c
The Drv.I2c is an interface for writing, reading, or writeRead to an I2C device. The Drv::LinuxI2cDriver driver implements this interface.
Drv.Spi
The Drv.Spi is an interface for writing and reading to an SPI device. The Drv::LinuxSpiDriver driver implements this interface.
Drv.AsyncSpi, Drv.AsyncGuardedSpi
The Drv.AsyncSpi and Drv.AsyncGuardedSpi interfaces are the asynchronous counterparts of Drv.Spi, following the pattern of Drv.AsyncI2c and Drv.AsyncGuardedI2c. A client requests a write/read transaction on the SpiWriteRead input port and continues; the driver performs the transfer (typically by DMA or interrupt) and reports completion on the SpiWriteReadComplete output port, handing both buffers back with the data pointer and size they had in the request. No driver in the core framework implements these interfaces; they are intended for platform packages (e.g. DMA-driven baremetal SPI drivers), which previously had to carry a private copy of this contract.
The two variants differ only in the kind of the request port, so that a driver can pick the one matching its execution model:
| Interface | SpiWriteRead port kind |
Implementing component |
|---|---|---|
Drv.AsyncSpi |
async input |
queued or active |
Drv.AsyncGuardedSpi |
guarded input |
any, including passive no-RTOS drivers |
Both use the same port types: Drv.SpiWriteReadRequest for the request and Drv.SpiWriteReadCallback for the completion.
Port indexing. Both ports are arrays of size Drv.AsyncSpiCfg.SpiDriverPorts (default 10, configurable in config/AsyncSpiCfg.fpp). The index is the device slot, i.e. the chip select the transaction targets, and the completion for a request received on index n is always sent on SpiWriteReadComplete[n]. Each client reserves one index and connects its request output and its completion input to that same index.
Every request is completed. Like Drv.I2cRequest, Drv.SpiWriteReadRequest has no return value: the driver answers every request with exactly one SpiWriteReadComplete call carrying the outcome in status (SPI_OK on success). A request the driver cannot take, e.g. SPI_BUSY_ERR while another transaction is in flight or SPI_CONFIG_ERR before the driver is configured, is reported the same way, and both buffers are handed back unchanged. With the guarded variant such a refusal may be delivered re-entrantly, from inside the client's own request call, so a client must be prepared for the completion before the request port returns. There is deliberately no sync input variant: a passive component may import Drv.AsyncGuardedSpi, and on no-RTOS targets the guard reduces to the platform Os::Mutex implementation (typically a flag).
Completion context. An implementing driver must invoke SpiWriteReadComplete from a non-interrupt context: it is the driver's responsibility to leave ISR context (e.g. by deferring to a scheduled or queued handler) before calling downstream components. In the normal asynchronous flow the request handler has long returned when the transfer finishes, so the completion is naturally outside the driver's guard; a driver must not fire it from inside another guarded handler of its own (e.g. a guarded run that polls for DMA completion), because the component mutex is not recursive and a client issuing its next request from inside the completion handler would assert.
Drv.Tick
The Drv.Tick is an interface for outputting a system tick along with a RawTime timestamp. The Svc::LinuxTimer driver is an example of a Linux-based timer that implements this interface.