Notes / Communication Protocols
SPI: exchanging data on every clock
Fast communication over four wires: SCK, MOSI, MISO and CS. The four modes, connecting several slaves, and practical debugging points.
Four wires
| Wire | Direction | Role |
|---|---|---|
| SCK | Master → slave | Clock |
| MOSI (COPI) | Master → slave | Data |
| MISO (CIPO) | Slave → master | Data |
| CS (NSS) | Master → slave | Chip select, active LOW |
On each clock both sides exchange one bit at the same time. Even if you only want to read, the master has to send dummy bytes for the clock to run.
Four modes
| Mode | CPOL (idle clock) | CPHA (sampling edge) |
|---|---|---|
| 0 | LOW | First edge |
| 1 | LOW | Second edge |
| 2 | HIGH | First edge |
| 3 | HIGH | Second edge |
Match it to the timing diagram in the slave chip's datasheet. With the wrong mode the values are shifted by one bit or come out as garbage.
Several slaves
SCK, MOSI and MISO are shared and each chip gets its own CS. A chip that is not selected releases MISO (high impedance), so there is no conflict.
Practical points
- CS is often driven as a software GPIO. Raise CS only after the transfer has completely finished (BSY flag).
- Above a few MHz, look at trace length and ringing. A series resistor on the clock output helps.
- Typical uses are shift registers, displays, external Flash and fast ADCs.
In a picture: one byte going back and forth (mode 0)
SPI is two shift registers connected in a ring. On the very clock where the master shifts out one bit, the slave shifts out one too. That is why the master has to send something (usually 0x00 or 0xFF) even when it only wants to read.
The four modes
| Mode | CPOL (idle clock) | CPHA (when to read) |
|---|---|---|
| 0 | LOW | First edge (rising) |
| 1 | LOW | Second edge (falling) |
| 2 | HIGH | First edge (falling) |
| 3 | HIGH | Second edge (rising) |
A wrong mode does not stop communication altogether; the values are read shifted by one bit. If you sent 0xA5 and read 0x52 or 0xD2, suspect the mode. Check directly in the chip's timing diagram which level the clock idles at and on which edge the data is stable.
Reading a sensor register
uint8_t spi_read_reg(uint8_t reg) {
uint8_t v;
CS_LOW();
spi_xfer(reg | 0x80); // top bit 1 = read (differs by chip)
v = spi_xfer(0x00); // send a dummy and receive the reply
CS_HIGH();
return v;
}
One transaction lasts as long as CS stays low. If CS goes up and down between the address and the data, the chip treats what follows as a new command.
Compared with UART and I2C
| SPI | I2C | UART | |
|---|---|---|---|
| Wires | 4 (one more CS per device) | 2 | 2 |
| Speed | Tens of MHz | 100 k to 3.4 Mbps | Usually a few Mbps or less |
| Addressing | None (selected by CS) | 7-bit address | None (1:1) |
| Acknowledgement | None | ACK | None |
| Use | Flash, displays, fast ADCs | Sensors, EEPROM | PC, modules |
Problems that come up in practice
- CS raised too early: raising CS before the last bit has gone out corrupts the last byte. Raise it after the busy flag (BSY) clears.
- Speed on long wires: 10 MHz over jumper wires longer than 10 cm is too much. Check whether lowering the speed fixes it immediately.
- Sharing MISO: a slave that is not selected must release MISO. Modules that do not will clash on a shared bus.
- Bit order: most chips send MSB first, but some send LSB first.
- 3.3 V and 5 V: connecting chips of different voltages directly can damage inputs.
Check yourself
- How many master pins do you need to connect three slaves?
- Why does the master have to send dummy bytes even for a read-only operation?