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: &'static mut [u8],
read_buffer: Option<&'static mut [u8]>,
len: usize
) -> Result<(), (ErrorCode, &'static mut [u8], Option<&'static mut [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
The SpiMaster
trait for interacting with SPI slave
devices at a byte or buffer level.
Using SpiMaster normally involves three steps:
- Configure the SPI bus for a peripheral 1a. Call set_chip_select to select which peripheral and turn on SPI 1b. Call set operations as needed to configure bus NOTE: You MUST select the chip select BEFORE configuring SPI settings.
- Invoke read, write, read_write on SpiMaster 3a. Call clear_chip_select to turn off bus, or 3b. Call set_chip_select to choose another peripheral, go to step 1b or 2.
The SPI configuration for a particular peripheral persists across changes to the chip select. For example, this set of calls
specify_chip_select(1); set_phase(SampleLeading); specify_chip_select(2); set_phase(SampleTrailing); specify_chip_select(1); write_byte(0); // Uses SampleLeading
will have a SampleLeading phase in the final 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(SampleLeading); pin_a.clear(); // Select A write_byte(0xaa); // Uses SampleLeading pin_a.set(); // Unselect A set_phase(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 are:
- 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
sourcefn set_client(&self, client: &'a dyn SpiMasterClient)
fn set_client(&self, client: &'a dyn SpiMasterClient)
Change the callback handler for read_write_bytes
calls.
sourcefn is_busy(&self) -> bool
fn is_busy(&self) -> bool
Return whether the SPI peripheral is busy with read_write_bytes
call.
sourcefn read_write_bytes(
&self,
write_buffer: &'static mut [u8],
read_buffer: Option<&'static mut [u8]>,
len: usize
) -> Result<(), (ErrorCode, &'static mut [u8], Option<&'static mut [u8]>)>
fn read_write_bytes( &self, write_buffer: &'static mut [u8], read_buffer: Option<&'static mut [u8]>, len: usize ) -> Result<(), (ErrorCode, &'static mut [u8], Option<&'static mut [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 mimumum of the length of
write_buffer
and the len
argument. If read_buffer
is Some
, the number of bytes read/written will be the
minimum of the len
argument, the length of write_buffer
,
and the length of read_buffer
.
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
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 written
- Err(OFF): the SPI bus is powered down
- Err(BUSY): the SPI bus is busy with a
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 byte
- Err(OFF): the SPI bus is powered down
- Err(BUSY): the SPI bus is busy with a
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 byte
- Err(OFF): the SPI bus is powered down
- Err(BUSY): the SPI bus is busy with a
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 passed
- Err(BUSY): the SPI bus is busy with a 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 a
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).
- Ok(()): the phase was set.
- Err(BUSY): the SPI bus is busy with a
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 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 read_write_bytes completes. This will complete the SPI operation.