class SPI – a controller-driven serial protocol

SPI is a synchronous serial protocol driven by a controller. At the physical level it uses three lines (SCK, MOSI, MISO) plus a per-peripheral chip-select line.

Usage is similar to I2C; the main difference is the parameters passed when initialising the bus:

from pyb import SPI
spi = SPI(2, SPI.CONTROLLER, baudrate=600000, polarity=1, phase=0, crc=0x7)

The only required parameter is mode (SPI.CONTROLLER or SPI.PERIPHERAL). polarity is the idle level of SCK (0 or 1). phase selects whether data is sampled on the first (0) or second (1) clock edge. crc is either None (no CRC) or a CRC polynomial.

Transferring data:

data = spi.send_recv(b"1234")        # send 4 bytes and receive 4 bytes
buf = bytearray(4)
spi.send_recv(b"1234", buf)          # send 4 bytes and receive 4 into buf
spi.send_recv(buf, buf)              # send/receive 4 bytes through buf

Constructors

class pyb.SPI(bus: int | str, *args, **kwargs)

Construct an SPI object on the given bus (an integer SPI peripheral index, e.g. 2 for SPI2). With no additional parameters the object is created but not initialised (it retains the previous bus settings, if any); if extra arguments are given the bus is initialised with them. See init() for the available parameters.

SPI(2) is wired to the same header pins on every STM32 OpenMV Cam; the OpenMV Cam N6 additionally exposes SPI(4):

Bus

NSS

SCK

MISO

MOSI

SPI(2) (all STM32 OpenMV Cams)

P3

P2

P1

P0

SPI(4) (OpenMV Cam N6 only)

P15

P16

P17

P18

NSS is not driven by the SPI peripheral on either bus; it is free to use as a normal GPIO chip-select.

Methods

deinit() None

Turn off the SPI bus.

init(mode: int, baudrate: int = 328125, *, prescaler: int = -1, polarity: int = 1, phase: int = 0, bits: int = 8, firstbit: int = SPI.MSB, ti: bool = False, crc: int | None = None) None

Initialise the SPI bus with the given parameters:

  • mode must be either SPI.CONTROLLER or SPI.PERIPHERAL.

  • baudrate is the SCK clock rate (only sensible for a controller).

  • prescaler is the prescaler to use to derive SCK from the APB bus frequency; use of prescaler overrides baudrate.

  • polarity can be 0 or 1, and is the level the idle clock line sits at.

  • phase can be 0 or 1 to sample data on the first or second clock edge respectively.

  • bits can be 8 or 16, and is the number of bits in each transferred word.

  • firstbit can be SPI.MSB or SPI.LSB.

  • ti True indicates Texas Instruments, as opposed to Motorola, signal conventions.

  • crc can be None for no CRC, or a polynomial specifier.

The SPI clock frequency may not match baudrate exactly. The hardware only supports clocks that are the parent APB bus frequency divided by a power-of-two prescaler (2, 4, 8, 16, 32, 64, 128 or 256); the driver picks the highest one that does not exceed the requested baudrate. SPI(2) is on APB1. For precise control over the clock, set prescaler directly instead of baudrate.

Printing the SPI object shows the computed baud rate and chosen prescaler.

recv(recv: int | bytearray, *, timeout: int = 5000) bytes

Receive data on the bus:

  • recv can be an integer, which is the number of bytes to receive, or a mutable buffer, which will be filled with received bytes.

  • timeout is the timeout in milliseconds to wait for the receive.

Return value: if recv is an integer then a new buffer of the bytes received, otherwise the same buffer that was passed in to recv.

send(send: int | bytes | bytearray, *, timeout: int = 5000) None

Send data on the bus:

  • send is the data to send (an integer to send, or a buffer object).

  • timeout is the timeout in milliseconds to wait for the send.

send_recv(send: int | bytes | bytearray, recv: bytearray | None = None, *, timeout: int = 5000) bytes

Send and receive data on the bus at the same time:

  • send is the data to send (an integer to send, or a buffer object).

  • recv is a mutable buffer which will be filled with received bytes. It can be the same as send, or omitted. If omitted, a new buffer will be created.

  • timeout is the timeout in milliseconds to wait for the receive.

Return value: the buffer with the received bytes.

Constants

CONTROLLER: int

Initialise the SPI bus as master (controller) – the OpenMV Cam drives SCK and MOSI and is in charge of the transaction.

PERIPHERAL: int

Initialise the SPI bus as slave (peripheral) – the OpenMV Cam responds to clock pulses driven by a remote controller.

MSB: int

Pass to firstbit to transmit/receive the most-significant bit first (the most common ordering).

LSB: int

Pass to firstbit to transmit/receive the least-significant bit first.