Trait kernel::hil::spi::SpiMaster

source ·
pub trait SpiMaster<'a> {
    type ChipSelect: Copy;

Show 16 methods // Required methods fn init(&self) -> Result<(), ErrorCode>; fn set_client(&self, client: &'a dyn SpiMasterClient); fn is_busy(&self) -> bool; fn read_write_bytes( &self, write_buffer: SubSliceMut<'static, u8>, read_buffer: Option<SubSliceMut<'static, u8>>, ) -> Result<(), (ErrorCode, SubSliceMut<'static, u8>, Option<SubSliceMut<'static, u8>>)>; fn write_byte(&self, val: u8) -> Result<(), ErrorCode>; fn read_byte(&self) -> Result<u8, ErrorCode>; fn read_write_byte(&self, val: u8) -> Result<u8, ErrorCode>; fn specify_chip_select(&self, cs: Self::ChipSelect) -> Result<(), ErrorCode>; fn set_rate(&self, rate: u32) -> Result<u32, ErrorCode>; fn get_rate(&self) -> u32; fn set_polarity(&self, polarity: ClockPolarity) -> Result<(), ErrorCode>; fn get_polarity(&self) -> ClockPolarity; fn set_phase(&self, phase: ClockPhase) -> Result<(), ErrorCode>; fn get_phase(&self) -> ClockPhase; fn hold_low(&self); fn release_low(&self);
}
Expand description

Trait for interacting with SPI peripheral devices at a byte or buffer level.

Using SpiMaster normally involves three steps:

  1. Configure the SPI bus for a peripheral.

    1. Call SpiMaster::specify_chip_select to select which peripheral and turn on SPI.

    2. Call set operations as needed to configure the bus. NOTE: You MUST select the chip select BEFORE configuring SPI settings.

  2. Invoke SpiMaster::read_write_bytes on SpiMaster.

  3. Go back to step 2 to complete another transaction, or call SpiMaster::specify_chip_select to choose another peripheral and go to step 1.2 or 2.

The SPI configuration for a particular peripheral persists across changes to the chip select. For example, this set of calls:

SpiMaster::specify_chip_select(1);
SpiMaster::set_phase(ClockPhase::SampleLeading);
SpiMaster::specify_chip_select(2);
SpiMaster::set_phase(ClockPhase::SampleTrailing);
SpiMaster::specify_chip_select(1);
SpiMaster::write_byte(0); // Uses SampleLeading

will have a ClockPhase::SampleLeading phase in the final SpiMaster::write_byte call, because the configuration of chip select 1 is saved, and restored when chip select is set back to 1.

If additional chip selects are needed, they can be performed with GPIO and manual re-initialization of settings. Note that a SPI chip select (CS) line is usually active low.

specify_chip_select(0);
set_phase(ClockPhase::SampleLeading);
pin_a.clear(); // Select A
write_byte(0xaa); // Uses SampleLeading
pin_a.set(); // Unselect A
set_phase(ClockPhase::SampleTrailing);
pin_b.clear(); // Select B
write_byte(0xaa); // Uses SampleTrailing

Required Associated Types§

source

type ChipSelect: Copy

Chip select is an associated type because different SPI buses may have different numbers of chip selects. This allows peripheral implementations to define their own type.

Required Methods§

source

fn init(&self) -> Result<(), ErrorCode>

Initialize this SPI interface. Call this once before invoking any other operations.

§Return values
  • Ok(()): initialized correctly
  • Err(OFF): not currently powered so can’t be initialized
  • Err(RESERVE): no clock is configured yet
  • Err(FAIL): other failure condition
source

fn set_client(&self, client: &'a dyn SpiMasterClient)

Change the callback handler for SpiMaster::read_write_bytes calls.

source

fn is_busy(&self) -> bool

Return whether the SPI peripheral is busy with a SpiMaster::read_write_bytes operation.

source

fn read_write_bytes( &self, write_buffer: SubSliceMut<'static, u8>, read_buffer: Option<SubSliceMut<'static, u8>>, ) -> Result<(), (ErrorCode, SubSliceMut<'static, u8>, Option<SubSliceMut<'static, u8>>)>

Perform an asynchronous read/write operation, whose completion is signaled by invoking SpiMasterClient on the client. Write-only operations may pass None for read_buffer, while read-write operations pass Some for read_buffer.

If read_buffer is None, the number of bytes written will be the the length of write_buffer. If read_buffer is Some, the number of bytes read/written will be the minimum of the length of write_buffer and the length of read_buffer.

§Return values

If read_write_bytes returns Ok(()), the operation will be attempted and a callback will be called. If it returns Err, no callback will be called and the buffers are returned.

  • Ok(()): the operation will be attempted and the callback will be called.
  • Err(OFF): the SPI bus is powered down.
  • Err(INVAL): length is 0
  • Err(BUSY): the SPI bus is busy with a prior SpiMaster::read_write_bytes operation whose callback hasn’t been called yet.
source

fn write_byte(&self, val: u8) -> Result<(), ErrorCode>

Synchronously write a single byte on the bus. Not for general use because it is blocking: intended for debugging.

§Return values
  • Ok(()): the byte was written
  • Err(OFF): the SPI bus is powered down
  • Err(BUSY): the SPI bus is busy with a SpiMaster::read_write_bytes operation whose callback hasn’t been called yet.
  • Err(FAIL): other failure
source

fn read_byte(&self) -> Result<u8, ErrorCode>

Synchronously write a 0 and read a single byte from the bus. Not for general use because it is blocking: intended for debugging.

§Return values
  • Ok(u8): the read byte
  • Err(OFF): the SPI bus is powered down
  • Err(BUSY): the SPI bus is busy with a SpiMaster::read_write_bytes operation whose callback hasn’t been called yet.
  • Err(FAIL): other failure
source

fn read_write_byte(&self, val: u8) -> Result<u8, ErrorCode>

Synchronously write and read a single byte. Not for general use because it is blocking: intended for debugging.

§Return values
  • Ok(u8): the read byte
  • Err(OFF): the SPI bus is powered down
  • Err(BUSY): the SPI bus is busy with a SpiMaster::read_write_bytes operation whose callback hasn’t been called yet.
  • Err(FAIL): other failure
source

fn specify_chip_select(&self, cs: Self::ChipSelect) -> Result<(), ErrorCode>

Specify which chip select to use. Configuration settings (rate, polarity, phase) are chip-select specific and are stored for that chip select.

source

fn set_rate(&self, rate: u32) -> Result<u32, ErrorCode>

Set the clock/data rate for the current chip select.

§Return values
  • Ok(u32): the actual data rate set (limited by clock precision)
  • Err(INVAL): a rate outside the bounds of the bus was passed
  • Err(BUSY): the SPI bus is busy with a SpiMaster::read_write_bytes operation whose callback hasn’t been called yet.
  • Err(FAIL): other failure
source

fn get_rate(&self) -> u32

Return the current chip select’s clock rate.

source

fn set_polarity(&self, polarity: ClockPolarity) -> Result<(), ErrorCode>

Set the bus polarity (whether idle is high or low) for the current chip select.

§Return values
  • Ok(()): the polarity was set.
  • Err(BUSY): the SPI bus is busy with a SpiMaster::read_write_bytes operation whose callback hasn’t been called yet.
  • Err(FAIL): other failure
source

fn get_polarity(&self) -> ClockPolarity

Return the current bus polarity.

source

fn set_phase(&self, phase: ClockPhase) -> Result<(), ErrorCode>

Set the bus phase for the current chip select (whether data is sent/received on leading or trailing edges).

§Return values
  • Ok(()): the phase was set.
  • Err(BUSY): the SPI bus is busy with a SpiMaster::read_write_bytes operation whose callback hasn’t been called yet.
  • Err(FAIL): other failure
source

fn get_phase(&self) -> ClockPhase

Get the current bus phase for the current chip select.

source

fn hold_low(&self)

Hold the chip select line low after a SpiMaster::read_write_bytes completes. This allows a client to make one long SPI read/write with multiple calls to read_write_bytes.

source

fn release_low(&self)

Raise the chip select line after a SpiMaster::read_write_bytes completes. This will complete the SPI operation.

Implementors§