In embedded-hal 1.0, SPI traits are split into SpiBus (the raw bus with SCK, MOSI, MISO) and SpiDevice (a single device on a bus managed by a CS pin).
For HAL Implementors
- If you do not manage a CS pin automatically, implement
SpiBus. - If your API does manage a CS pin automatically, implement
SpiDevice. - Never implement both
SpiBus and SpiDevice on the same struct.
For Driver Authors
- If your device has a CS pin, use
SpiDevice. Do not take the CS pin as a separate OutputPin; SpiDevice manages it for you. - If your device only has SCK, MOSI, MISO, use
SpiBus. - If using SPI to bitbang non-SPI protocols (e.g., WS2812), use
SpiBus.
For End Users (Converting SpiBus to SpiDevice)
If your HAL provides SpiBus but your driver requires SpiDevice, wrap the bus using embedded_hal_bus::spi::ExclusiveDevice along with a CS pin.
use embedded_hal_bus::spi::{ExclusiveDevice, NoDelay};
// Create the SPI from the HAL. This implements SpiBus, not SpiDevice!
let spi_bus = my_hal::spi::Spi::new(...);
// Create the CS. This must implement OutputPin.
let cs = my_hal::gpio::Output::new(...);
// Combine the SPI bus and the CS pin into a SPI device. This now does implement SpiDevice!
let spi_device = ExclusiveDevice::new(spi_bus, cs, NoDelay);
// Now you can create your driver with it!
let driver = my_driver::Driver::new(spi_device, ...);