//! Non-blocking, chip-select-scoped SPI transfer contract. //! //! A selected device owns electrical chip-select behavior. A driver retains its //! transfer storage until a terminal completion event; implementations submit //! DMA or interrupt-driven work and never wait for a peripheral flag. #![no_std] /// Terminal outcome reported by a selected SPI device. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum SpiCompletion { /// The bound interrupt does not report a terminal event. NotPending, /// The submitted full-duplex transfer completed. Complete, /// The submitted transfer failed and its receive bytes are unusable. TransferFault, } /// Owns one chip-select-scoped, non-blocking SPI route. /// /// `start_transfer` begins a complete transfer and returns without waiting for /// a peripheral status flag. The caller owns both buffers until the board /// reports a terminal `SpiCompletion`; `complete_transfer` releases the route /// after that terminal outcome. pub trait SpiDevice { /// Failure to submit a transfer. type StartError; /// Starts one complete full-duplex transfer. /// /// Implementations assert chip select before submitting and deassert it on /// every terminal completion or submission failure. `receive` receives one /// octet for each `transmit` octet; the two ranges must have equal length. fn start_transfer( &mut self, transmit: &[u8], receive: &mut [u8], ) -> Result<(), Self::StartError>; /// Releases transport ownership after a hardware ISR acknowledged a /// terminal completion. This must not poll or wait. fn complete_transfer(&mut self, completion: SpiCompletion); }