axp192
X-Powers AXP192 — the power-management IC on the M5Stack Core2 (and the M5StickC family).
Layer 3: it knows the PMIC, not the chip or board driving it, and talks
through a [BusHandle] on I2C at [ADDR]. What each rail powers is a
board fact and lives in the board manifest, not here — the same DCDC3 that
is the Core2’s LCD backlight is something else on another board.
The five rails
Section titled “The five rails”The AXP192 has three buck converters (DCDC1–3) and two LDOs (LDO2–3), each
enabled by one bit of the output-control register (0x12) and set by a
voltage register. This driver models them as [Rail] and a const config
table transliterated from the hardware-agnostic reference driver
tuupola/axp192 (MIT) — min/max/step in millivolts, the voltage register,
and where the value sits in it:
| Rail | enable bit (0x12) |
voltage reg | range / step |
|---|---|---|---|
| DCDC1 | 0 | 0x26[6:0] |
700–3500 / 25 mV |
| DCDC2 | 4 | 0x23[5:0] |
700–2275 / 25 mV |
| DCDC3 | 1 | 0x27[6:0] |
700–3500 / 25 mV |
| LDO2 | 2 | 0x28[7:4] |
1800–3300 / 100 mV |
| LDO3 | 3 | 0x28[3:0] |
1800–3300 / 100 mV |
LDO2 and LDO3 share one register (0x28), one in each nibble, so setting
one must preserve the other — hence every voltage write is read-modify-write
and masked to the rail’s field. The same is true of the single enable
register, which is why enabling a rail reads 0x12 first rather than
writing a fresh byte.
DCDC1 is the system rail — this driver never asserts a policy about it
Section titled “DCDC1 is the system rail — this driver never asserts a policy about it”On the Core2, DCDC1 powers the ESP32 running this code. Turning it off or
moving its voltage under the CPU browns the board out. This driver exposes
DCDC1 like any other rail because it is one, but a board must never list
it for automatic bring-up; that invariant is enforced where the board’s rail
list is applied (see the board crate’s power_init), not here — a driver
that silently refused a rail would be lying about what the part can do.
No floats
Section titled “No floats”Voltages are u16 millivolts and the encode/decode is integer arithmetic,
for the same reason the IMU driver keeps to integers: a float in a driver is
a float in whatever calls it, and on Xtensa that pulls the FPU into every
context switch that touches it.
Structs
Section titled “Structs”Axp192
Section titled “Axp192”struct Axp192<'a> { /* private fields */ }An AXP192 on a bus already addressed to [ADDR].
AxpError
Section titled “AxpError”enum AxpError { Bus(api::bus::BusError), VoltageOutOfRange { rail: Rail, millivolts: u16 }, UnsupportedGpio(u8),}Why an AXP192 operation failed.
Implements: Clone, Copy, Debug, Eq, From, PartialEq, StructuralPartialEq
enum Rail { Dcdc1, Dcdc2, Dcdc3, Ldo2, Ldo3,}One of the AXP192’s five switchable outputs.
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
Constants
Section titled “Constants”const ADDR: u8;I2C address of the AXP192. Fixed in the part; not a board fact.
Type Aliases
Section titled “Type Aliases”AxpResult
Section titled “AxpResult”type AxpResult<T> = Result<T, AxpError>;Result of an AXP192 operation.
References: AxpError