Module esp32c3_hal::spi::slave

source ·
Expand description

Serial Peripheral Interface - Slave Mode

Overview

There are multiple ways to use SPI, depending on your needs. Regardless of which way you choose, you must first create an SPI instance with Spi::new.

Example

let io = IO::new(peripherals.GPIO, peripherals.IO_MUX);
let sclk = io.pins.gpio12;
let miso = io.pins.gpio11;
let mosi = io.pins.gpio13;
let cs = io.pins.gpio10;

let mut spi = hal::spi::slave::Spi::new(peripherals.SPI2, sclk, mosi, miso, cs, SpiMode::Mode0);

There are several options for working with the SPI peripheral in slave mode, but the code currently only supports single transfers (not segmented transfers), full duplex, single bit (not dual or quad SPI), and DMA mode (not CPU mode). It also does not support blocking operations, as the actual transfer is controlled by the SPI master; if these are necessary, then the DmaTransfer trait instance can be wait()ed on or polled for is_done().

let dma = Gdma::new(peripherals.DMA);
const N: usize = (buffer_size + 4091) / 4092;
let mut tx_descriptors = [0u32; N * 3];
let mut rx_descriptors = [0u32; N * 3];
let mut spi = spi.with_dma(dma.channel0.configure(
    /* circular = */ false,
    tx_descriptors,
    rx_descriptors,
    DmaPriority::Priority0,
));
// This is not legal rust, but any method of getting a &mut 'static is good.
let tx_buf = &'static [0u8; N * 4092];
let rx_buf = &mut 'static [0u8; N * 4092];
let transfer = spi.dma_transfer(tx_buf, rx_buf).unwrap();
// Do other operations, checking transfer.is_done()
// When the master sends enough clock pulses, is_done() will be true.
(tx_buf, rx_buf, spi) = transfer.wait();

TODO:

  • Notify the Spi user when the master wants to send or receive data, if possible
  • Blocking transfers
  • Half duplex
  • Segmented transfers
  • Interrupt support
  • Custom interrupts from segmented transfer commands
  • Dual and quad SPI
  • CPU mode

Modules

Structs

  • SPI peripheral driver

Traits