Skip to main content

spi-master

Discrete SPI master: send a known byte pattern out MOSI, log whatever clocks back on MISO. This is the production starting point — replace the byte pattern with your chip's command + register sequence.

Contrasts with spi-loopback, which exercises both ends on the same chip as a single-bus self-test.

Source: examples/peripheral-io/spi-master/.

What it does

  1. alp_spi_open() on BOARD_SPI_ARDUINO at 1 MHz, ALP_SPI_MODE_0, 8 bits per word, ALP_SPI_NO_CS.
  2. alp_spi_write() — half-duplex TX-only, the command-style write. Sends {0xAA, 0x55, 0xDE, 0xAD}.
  3. alp_spi_transceive() — full-duplex TX + RX, the register read with an in-band response.
  4. alp_spi_read() — half-duplex RX-only, for draining a streaming target.
  5. alp_spi_close().

BOARD_SPI_ARDUINO is the portable cross-EVK alias: ALP_E1M_SPI1 on the E1M EVK, ALP_E1M_X_SPI1 on the E1M-X EVK.

SPI mode quick reference

ModeCPOLCPHAClock idleSample edge
MODE_000LowRising
MODE_101LowFalling
MODE_210HighFalling
MODE_311HighRising

MODE_0 is what most modern peripherals expect. Check your target's datasheet — a wrong mode produces "almost right" data that's off by one bit.

Wiring

The E1M-EVK routes the Arduino UNO header SPI to the SoM, which bridges the bus internally — app code just opens the E1M instance and never sees the physical termination.

  • No external target is required. Jumper MOSI to MISO and confirm transceive echoes the TX pattern.
  • For a real target, connect SCK, MOSI, MISO, and either let the controller drive its own /CS or wire a free GPIO to the target's /CS pin.
  • Add a common ground if the target isn't on the same board.

board.yaml

som:
sku: E1M-AEN801

preset: e1m-evk
supported_boards:
- e1m-evk
- e1m-x-evk

pins:
- { e1m: E1M_SPI1, macro: EVK_SPI_BUS_ARDUINO, doc: "Arduino UNO header SPI" }

cores:
m55_hp:
app: ./src
peripherals:
- spi

diagnostics:
log_level: info

Expected output

native_sim (emul SPI, no target registered):

[spi-master] open BOARD_SPI_ARDUINO @ 1 MHz mode 0
[spi-master] write -> 0
[spi-master] transceive -> 0 rx={00 00 00 00}
[spi-master] read -> 0 rx={00 00 00 00}
[spi-master] done

Real hardware with a MOSI → MISO loopback jumper:

[spi-master] transceive -> 0 rx={aa 55 de ad}

Real hardware with a register-mapped target — transceive returns the target's register echo and read drains streaming data.

Customising

KnobWhy
.freq_hzDrop to 100 kHz for long/noisy traces; raise to 10 MHz once you've confirmed the target's max and your wires are short.
.modeMost chips want MODE_0 — check the datasheet's timing diagram.
.cs_pin_idReplace ALP_SPI_NO_CS with a portable GPIO id routed on your board; the wrapper drives it active-low around each transfer.
.bits_per_wordSet 16 or 32 for word-oriented targets.

Status

Two twister rows, one per EVK route table, on native_sim/native/64; the harness latches on [spi-master] done.

See also

Questions about this page? Discuss in Community Forum