pub unsafe trait SpiDevice: ErrorType {
    type Bus: ErrorType;

    async fn transaction<R, F, Fut>(&mut self, f: F) -> Result<R, Self::Error>
    where
        F: FnOnce(*mut Self::Bus) -> Fut,
        Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>>
; async fn read<'a, Word>(
        &'a mut self,
        buf: &'a mut [Word]
    ) -> Result<(), Self::Error>
    where
        Self::Bus: SpiBusRead<Word>,
        Word: Copy + 'static
, { ... } async fn write<'a, Word>(
        &'a mut self,
        buf: &'a [Word]
    ) -> Result<(), Self::Error>
    where
        Self::Bus: SpiBusWrite<Word>,
        Word: Copy + 'static
, { ... } async fn transfer<'a, Word>(
        &'a mut self,
        read: &'a mut [Word],
        write: &'a [Word]
    ) -> Result<(), Self::Error>
    where
        Self::Bus: SpiBus<Word>,
        Word: Copy + 'static
, { ... } async fn transfer_in_place<'a, Word>(
        &'a mut self,
        buf: &'a mut [Word]
    ) -> Result<(), Self::Error>
    where
        Self::Bus: SpiBus<Word>,
        Word: Copy + 'static
, { ... } }
Expand description

SPI device trait

SpiDevice represents ownership over a single SPI device on a (possibly shared) bus, selected with a CS (Chip Select) pin.

See (the docs on embedded-hal)[embedded_hal::spi::blocking] for important information on SPI Bus vs Device traits.

Safety

See SpiDevice::transaction for details.

Required Associated Types

SPI Bus type for this device.

Required Methods

Perform a transaction against the device.

NOTE: It is not recommended to use this method directly, because it requires unsafe code to dereference the raw pointer. Instead, the transaction! macro should be used, which handles this safely inside the macro.

  • Locks the bus
  • Asserts the CS (Chip Select) pin.
  • Calls f with an exclusive reference to the bus, which can then be used to do transfers against the device.
  • Flushes the bus.
  • Deasserts the CS pin.
  • Unlocks the bus.

The locking mechanism is implementation-defined. The only requirement is it must prevent two transactions from executing concurrently against the same bus. Examples of implementations are: critical sections, blocking mutexes, async mutexes, returning an error or panicking if the bus is already busy.

On bus errors the implementation should try to deassert CS. If an error occurs while deasserting CS the bus error should take priority as the return value.

Safety

The current state of the Rust typechecker doesn’t allow expressing the necessary lifetime constraints, so the f closure receives a lifetime-less *mut Bus raw pointer instead.

Implementers of the SpiDevice trait must guarantee that the pointer is valid and dereferencable for the entire duration of the closure.

Provided Methods

Do a read within a transaction.

This is a convenience method equivalent to device.transaction(|bus| bus.read(buf)).

See also: SpiDevice::transaction, SpiBusRead::read

Do a write within a transaction.

This is a convenience method equivalent to device.transaction(|bus| bus.write(buf)).

See also: SpiDevice::transaction, SpiBusWrite::write

Do a transfer within a transaction.

This is a convenience method equivalent to device.transaction(|bus| bus.transfer(read, write)).

See also: SpiDevice::transaction, SpiBus::transfer

Do an in-place transfer within a transaction.

This is a convenience method equivalent to device.transaction(|bus| bus.transfer_in_place(buf)).

See also: SpiDevice::transaction, SpiBus::transfer_in_place

Implementations on Foreign Types

Implementors