spi-i2c-baremetal
Helps developers connect sensors and devices to tiny computers using serial communication.
Installation
Paste this into Claude Code, Cursor, or any agent that can run commands.
SKILL.mdShow the author's original SKILL.md
---
name: spi-i2c-baremetal
description: Bare-metal SPI and I2C skill for serial peripheral buses. Use when implementing master-mode transfers, register read/write protocols, or debugging bus stalls. Activates on queries about SPI bare-metal, I2C START/STOP, sensor register read, or clock phase/polarity.
---
# SPI and I2C (Bare-Metal)
## Purpose
Implement SPI and I2C master drivers for sensor and memory chips: clock configuration, phase/polarity (SPI), START/ACK sequences (I2C), and common register-oriented transaction patterns.
## When to Use
- Reading an I2C sensor (WHO_AM_I register)
- SPI flash or display bring-up
- Debugging NACK or stuck SCL
- Replacing HAL_I2C/SPI with minimal code
## Workflow
### 1. SPI master (STM32)
```c
/* Mode 0: CPOL=0, CPHA=0 — check slave datasheet */
SPI1->CR1 = SPI_CR1_MSTR | SPI_CR1_SSM | SPI_CR1_SSI
| (3 << SPI_CR1_BR_Pos); /* baud divider */
SPI1->CR1 |= SPI_CR1_SPE;
uint8_t spi_xfer(SPI_TypeDef *spi, uint8_t tx) {
while (!(spi->SR & SPI_SR_TXE))
;
*(volatile uint8_t *)&spi->DR = tx;
while (!(spi->SR & SPI_SR_RXNE))
;
return *(volatile uint8_t *)&spi->DR;
}
```
CS (GPIO bit-bang):
```c
GPIO_CS_LOW();
spi_xfer(SPI1, reg | 0x80); /* read */
uint8_t val = spi_xfer(SPI1, 0xFF);
GPIO_CS_HIGH();
```
### 2. I2C master — register read
```c
/* START → addr+W → reg → repeated START → addr+R → data → STOP */
bool i2c_read_reg(I2C_TypeDef *i2c, uint8_t dev7, uint8_t reg, uint8_t *out) {
if (!i2c_start(i2c)) return false;
if (!i2c_tx(i2c, (dev7 << 1) | 0)) return false;
if (!i2c_tx(i2c, reg)) return false;
if (!i2c_restart(i2c)) return false;
if (!i2c_tx(i2c, (dev7 << 1) | 1)) return false;
*out = i2c_rx(i2c, false); /* NACK last byte */
i2c_stop(i2c);
return true;
}
```
Poll `SB`, `ADDR`, `TXE`, `RXNE`, `BTF` per reference manual.
### 3. Common protocols
| Pattern | Bus |
|---------|-----|
| `reg + write data` | I2C/SPI |
| `0x80|reg` read (MSB set) | SPI sensors |
| 16-bit big-endian length prefix | SPI flash |
### 4. Agent usage
```
/spi-i2c-baremetal I2C read of register 0x0F from device 0x68
```
## Common Problems
| Symptom | Cause | Fix |
|---------|-------|-----|
| I2C NACK | Wrong 7-bit addr (8-bit in datasheet) | Shift addr; check R/W bit |
| SPI garbage | CPOL/CPHA mismatch | Match slave mode table |
| Bus stuck SCL low | Slave clock stretch / fault | Bus recovery (clock pulses) |
| CS glitch | CS timing vs clock | Assert CS before first SCK |
## Related Skills
- `skills/baremetal/gpio-baremetal` — CS, SDA, SCL pins
- `skills/baremetal/peripherals-from-datasheet` — timing requirements
- `skills/kernel-dev/bus-drivers-i2c-spi` — Linux kernel sideMirrored from the author's public source. Install counts from the open skills registry.