Skip to content

soc_esp32

ESP32 SoC support.

This crate owns what is true of the chip rather than of the board or of the CPU core:

  • [addr] — peripheral base addresses and interrupt source numbers
  • [ctrl] — the I2C/SPI/UART controllers as enums, each attribute a const fn of the variant, plus the *Port structs that pair one with its pin configuration
  • [dport] — peripheral clock gating and reset
  • [io_mux] — the pad configuration registers and their non-linear offset table
  • [gpio_matrix] — signal routing, and the signal index map
  • [pinmux] — [Esp32PinMux], the chip’s implementation of [hal::PinMux]

What is deliberately not here: peripherals. RMT, the watchdogs and the RNG were modules of this crate and are now drivers/physical/esp32/*, because a peripheral is something you write a driver for, while this crate holds what every one of those drivers needs underneath it. The test is whether a second peripheral would want it: an address map and a pin router yes, a pulse generator no.

It sits between the arch layer (Xtensa LX6: traps, context switch, tick, which the ESP32 shares with other Xtensa parts) and the board layer (which pin is wired to what, which differs between two boards carrying the same chip). Before this split existed, board manifests carried peripheral base addresses and every physical driver kept its own private copy of the IO_MUX offset table.

Everything here is specific to the classic ESP32 (and the PICO-D4 SiP built on it). The S2, S3 and C3 have different peripheral maps and, in the C3’s case, a different core entirely; they get their own crates.

  • addr — ESP32 peripheral base addresses and interrupt sources.
  • app_desc — The ESP-IDF application image header. A chip-boot artifact, not a CPU
  • appcpu — Starting the second core.
  • cpu_clk — Raising the CPU clock from the 80 MHz boot default to 240 MHz.
  • crosscore — Interrupting the other core.
  • ctrl — Peripheral controllers as types, and the ports that bind one to a pin
  • dma — The shared DMA channels, and who owns them.
  • dport — DPORT: peripheral clock gating, reset, and safe access to the block.
  • efuse — eFuse block 0, and the factory MAC address in it.
  • gpio_matrix — The GPIO matrix: routing peripheral signals to arbitrary pads.
  • intr_map — Peripheral interrupt routing: which CPU interrupt a peripheral fires on.
  • io_mux — IO_MUX: per-pad configuration.
  • pinmux — [Esp32PinMux] — the chip’s implementation of [PinMux].
  • poll — Busy-wait on a hardware condition, with a bound, spelled once.
  • reg — Read-modify-write on a memory-mapped register, spelled once.
  • reset — Why the chip last reset.
  • rtc — The RTC_CNTL register block.
  • sar — SAR ADC facts shared by ADC1, ADC2 and any future SAR user.
  • sleep — Low-power sleep: the RTC_CNTL sleep FSM, timer wake only.
struct Esp32;

Classic ESP32 implementation of the kernel’s selected-SoC contract.

Implements: LowPower, PanicRecovery, SystemOnChip

const APB_HZ: u32;

APB clock, which every peripheral in this crate is timed against.

Fixed at 80 MHz regardless of the CPU frequency: the ESP32’s CPU clock can be 80, 160 or 240 MHz, but APB stays at 80 unless the chip is put into a low-power mode this kernel does not use. Baud-rate and I2C divisors derive from this, not from the measured CPU frequency.

const MAX_GPIO: u8;

The chip’s IO_MUX-capable GPIO count. Pins 0-39 exist; 34-39 are input-only, and 20, 24, 28-31 are not bonded out at all.