Datasheet

Table Of Contents
NOTE
These programs do not control the chip select line; chip select is often implemented as a software-controlled GPIO,
due to wildly different behaviour between different SPI hardware. The full spi.pio source linked above contains some
examples how PIO can implement a hardware chip select line.
A C helper function configures the state machine, connects the GPIOs, and sets the state machine running. Note that the
SPI frame sizethat is, the number of bits transferred for each FIFO recordcan be programmed to any value from 1 to
32, without modifying the program. Once configured, the state machine is set running.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/pre_release/pio/spi/spi.pio Lines 46 - 72
46 static inline void pio_spi_init(PIO pio, uint sm, uint prog_offs, uint n_bits,
47 float clkdiv, bool cpha, bool cpol, uint pin_sck, uint pin_mosi, uint pin_miso) {
48 pio_sm_config c = cpha ? spi_cpha1_program_get_default_config(prog_offs) :
Ê spi_cpha0_program_get_default_config(prog_offs);
49 sm_config_set_out_pins(&c, pin_mosi, 1);
50 sm_config_set_in_pins(&c, pin_miso);
51 sm_config_set_sideset_pins(&c, pin_sck);
52 // Only support MSB-first in this example code (shift to left, auto push/pull,
Ê threshold=nbits)
53 sm_config_set_out_shift(&c, false, true, n_bits);
54 sm_config_set_in_shift(&c, false, true, n_bits);
55 sm_config_set_clkdiv(&c, clkdiv);
56
57 // MOSI, SCK output are low, MISO is input
58 pio_sm_set_pins_with_mask(pio, sm, 0, (1u << pin_sck) | (1u << pin_mosi));
59 pio_sm_set_pindirs_with_mask(pio, sm, (1u << pin_sck) | (1u << pin_mosi), (1u <<
Ê pin_sck) | (1u << pin_mosi) | (1u << pin_miso));
60 pio_gpio_select(pio, pin_mosi);
61 pio_gpio_select(pio, pin_miso);
62 pio_gpio_select(pio, pin_sck);
63
64 // The pin muxes can be configured to invert the output (among other things,
65 // thank you Terry) and this is a cheesy way to get CPOL=1
66 gpio_set_outover(pin_sck, cpol ? GPIO_OVERRIDE_INVERT : GPIO_OVERRIDE_NORMAL);
67 // SPI is synchronous, so bypass input synchroniser to reduce input delay.
68 hw_set_bits(&pio->input_sync_bypass, 1u << pin_miso);
69
70 pio_sm_init(pio, sm, prog_offs, &c);
71 pio_sm_enable(pio, sm, true);
72 }
The state machine will now immediately begin to shift out any data appearing in the TX FIFO, and push received data into
the RX FIFO.
Pico Examples: https://github.com/raspberrypi/pico-examples/tree/pre_release/pio/spi/pio_spi.c Lines 18 - 34
18 void __time_critical_func(pio_spi_write8_blocking)(const pio_spi_inst_t *spi, const uint8_t
Ê *src, size_t len) {
19 size_t tx_remain = len, rx_remain = len;
20 // Do 8 bit accesses on FIFO, so that write data is byte-replicated. This
21 // gets us the left-justification for free (for MSB-first shift-out)
22 io_rw_8 *txfifo = (io_rw_8 *) &spi->pio->txf[spi->sm];
23 io_rw_8 *rxfifo = (io_rw_8 *) &spi->pio->rxf[spi->sm];
24 while (tx_remain || rx_remain) {
25 if (tx_remain && !pio_sm_is_tx_full(spi->pio, spi->sm)) {
26 *txfifo = *src++;
27 --tx_remain;
RP2040 Datasheet
3.6. Examples 345