Skip to content

esp32_template

Skeleton Layer-1 esp32 driver — copy this, don’t ship it.

This crate is not linked into any image. It exists so a new physical-driver author has one small, compiling example of every convention the tree settled on. The prose lives in drivers/README.md; this is the same thing said in code. Read them together.

The peripheral is fictional: a single 32-bit “scratch” register you can write and read back. That is enough to show the shape and nothing more, so the shape is all you see.

The conventions, and where each one is below

Section titled “The conventions, and where each one is below”
  • One constructor: [Esp32Scratch::open](&[ScratchPort]) -> [hal::Result]<Self>. It claims the controller exactly once (a static [AtomicBool]), brings the hardware up, and hands back an owned handle. A second open returns an error rather than a second alias to the same registers.
  • unsafe fn new(base) only for self-tests. The on-target self-test harness needs to point a driver at loopback pads or a scratch address without the claim; nothing else may call it.
  • Registers through [soc_esp32::reg], never a hand-rolled fn reg(&self, off). reg::at turns base + offset into a pointer; reg::{read,write,modify,set,clear} do the access. See drivers/README.md for the seven drivers that still carry the private copy this avoids.
  • The driver’s own error type, with From into [hal::Error] — see [ScratchError] and its impl — so an application can ? a driver call into its one error type.
  • Pad routing lives in open, never in the caller. This scratch block has no pads, so there is nothing to route; a peripheral with pins routes them here through Esp32PinMux, exactly as esp32-i2c does. See drivers/README.md.
struct Esp32Scratch { /* private fields */ }

An owned handle to the scratch block.

Implements: Drop

struct ScratchPort {
pub seed: u32,
}

How to bring the scratch block up.

Mirrors the *Port structs in soc_esp32::ctrl (I2cPort, SpiPort, UartPort): one Copy value that carries everything open needs, so a board can name it as a const and an app passes it by reference. A real port also names its controller and pin configuration; this one only has a value to seed the register with.

Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq

enum ScratchError {
InUse,
}

What can go wrong bringing this driver up.

Small and specific — a driver says precisely what failed. The From below is what lets an application ? it into hal::Error without a map_err.

Implements: Clone, Copy, Debug, Eq, From, PartialEq, StructuralPartialEq