Trait embedded_hal_async::spi::SpiDevice
source · 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
Required Methods
sourceasync 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 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>>,
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
sourceasync fn read<'a, Word>(
&'a mut self,
buf: &'a mut [Word]
) -> Result<(), Self::Error>where
Self::Bus: SpiBusRead<Word>,
Word: Copy + 'static,
async fn read<'a, Word>(
&'a mut self,
buf: &'a mut [Word]
) -> Result<(), Self::Error>where
Self::Bus: SpiBusRead<Word>,
Word: Copy + 'static,
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
sourceasync fn write<'a, Word>(
&'a mut self,
buf: &'a [Word]
) -> Result<(), Self::Error>where
Self::Bus: SpiBusWrite<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,
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
sourceasync 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<'a, Word>(
&'a mut self,
read: &'a mut [Word],
write: &'a [Word]
) -> Result<(), Self::Error>where
Self::Bus: SpiBus<Word>,
Word: Copy + 'static,
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
sourceasync fn transfer_in_place<'a, Word>(
&'a mut self,
buf: &'a mut [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,
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