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:
-
Configure the SPI bus for a peripheral.
-
Call
SpiMaster::specify_chip_select
to select which peripheral and turn on SPI. -
Call set operations as needed to configure the bus. NOTE: You MUST select the chip select BEFORE configuring SPI settings.
-
-
Invoke
SpiMaster::read_write_bytes
onSpiMaster
. -
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§
sourcetype ChipSelect: Copy
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§
sourcefn init(&self) -> Result<(), ErrorCode>
fn init(&self) -> Result<(), ErrorCode>
Initialize this SPI interface. Call this once before invoking any other operations.
§Return values
Ok(())
: initialized correctlyErr(OFF)
: not currently powered so can’t be initializedErr(RESERVE)
: no clock is configured yetErr(FAIL)
: other failure condition
sourcefn set_client(&self, client: &'a dyn SpiMasterClient)
fn set_client(&self, client: &'a dyn SpiMasterClient)
Change the callback handler for SpiMaster::read_write_bytes
calls.
sourcefn is_busy(&self) -> bool
fn is_busy(&self) -> bool
Return whether the SPI peripheral is busy with a
SpiMaster::read_write_bytes
operation.
sourcefn 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 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 0Err(BUSY)
: the SPI bus is busy with a priorSpiMaster::read_write_bytes
operation whose callback hasn’t been called yet.
sourcefn write_byte(&self, val: u8) -> Result<(), ErrorCode>
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 writtenErr(OFF)
: the SPI bus is powered downErr(BUSY)
: the SPI bus is busy with aSpiMaster::read_write_bytes
operation whose callback hasn’t been called yet.Err(FAIL)
: other failure
sourcefn read_byte(&self) -> Result<u8, ErrorCode>
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 byteErr(OFF)
: the SPI bus is powered downErr(BUSY)
: the SPI bus is busy with aSpiMaster::read_write_bytes
operation whose callback hasn’t been called yet.Err(FAIL)
: other failure
sourcefn read_write_byte(&self, val: u8) -> Result<u8, ErrorCode>
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 byteErr(OFF)
: the SPI bus is powered downErr(BUSY)
: the SPI bus is busy with aSpiMaster::read_write_bytes
operation whose callback hasn’t been called yet.Err(FAIL)
: other failure
sourcefn specify_chip_select(&self, cs: Self::ChipSelect) -> Result<(), ErrorCode>
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.
sourcefn set_rate(&self, rate: u32) -> Result<u32, ErrorCode>
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 passedErr(BUSY)
: the SPI bus is busy with aSpiMaster::read_write_bytes
operation whose callback hasn’t been called yet.Err(FAIL)
: other failure
sourcefn set_polarity(&self, polarity: ClockPolarity) -> Result<(), ErrorCode>
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 aSpiMaster::read_write_bytes
operation whose callback hasn’t been called yet.Err(FAIL)
: other failure
sourcefn get_polarity(&self) -> ClockPolarity
fn get_polarity(&self) -> ClockPolarity
Return the current bus polarity.
sourcefn set_phase(&self, phase: ClockPhase) -> Result<(), ErrorCode>
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 aSpiMaster::read_write_bytes
operation whose callback hasn’t been called yet.Err(FAIL)
: other failure
sourcefn get_phase(&self) -> ClockPhase
fn get_phase(&self) -> ClockPhase
Get the current bus phase for the current chip select.
sourcefn hold_low(&self)
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
.
sourcefn release_low(&self)
fn release_low(&self)
Raise the chip select line after a SpiMaster::read_write_bytes
completes. This will complete the SPI operation.