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
alp_spi_open()onBOARD_SPI_ARDUINOat 1 MHz,ALP_SPI_MODE_0, 8 bits per word,ALP_SPI_NO_CS.alp_spi_write()— half-duplex TX-only, the command-style write. Sends{0xAA, 0x55, 0xDE, 0xAD}.alp_spi_transceive()— full-duplex TX + RX, the register read with an in-band response.alp_spi_read()— half-duplex RX-only, for draining a streaming target.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
| Mode | CPOL | CPHA | Clock idle | Sample edge |
|---|---|---|---|---|
MODE_0 | 0 | 0 | Low | Rising |
MODE_1 | 0 | 1 | Low | Falling |
MODE_2 | 1 | 0 | High | Falling |
MODE_3 | 1 | 1 | High | Rising |
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
transceiveechoes 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
| Knob | Why |
|---|---|
.freq_hz | Drop to 100 kHz for long/noisy traces; raise to 10 MHz once you've confirmed the target's max and your wires are short. |
.mode | Most chips want MODE_0 — check the datasheet's timing diagram. |
.cs_pin_id | Replace ALP_SPI_NO_CS with a portable GPIO id routed on your board; the wrapper drives it active-low around each transfer. |
.bits_per_word | Set 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
<alp/peripheral.h>reference — SPIspi-loopback— single-chip self-testspi-slave— target-mode companion- Examples overview