PinsModule
Source:
PinsModule.h
Claim¶
src/core/PinsModule.h:74Public Attributes¶
uint8_t gpio
char owner
char role
constchar * severity
constchar * reason
platform::GpioLiveState live
PinListSource¶
src/core/PinsModule.h:70Inherits:
ListSource
The pin ownership map: a ListSource over a fixed snapshot rebuilt on tick1s.
A claim is one GPIO staked by one control; multiple claims on the same GPIO are kept (a conflict must stay visible, not be merged away). No allocation — a fixed Claim[kMaxClaims], filled or left at count 0.
Public Attributes¶
Claim claims_
uint8_t count_ = 0
Public Methods¶
inline void refresh()
inline void flagConflicts()
inline uint8_t listRowCount() const override
inline void writeListRow(JsonSink & sink, uint8_t row) const override
inline void writeListRowDetail(JsonSink & sink, uint8_t row) const override
Public Static Attributes¶
constexpruint8_t kMaxClaims = 64
Public Static Methods¶
static inline constchar * driveLabel(uint8_t cap)
static inline constchar * dirLabel(const platform::GpioLiveState & live)
PinsModule¶
src/core/PinsModule.h:50Inherits:
MoonModule
A core, domain-neutral diagnostic that shows which module owns each GPIO, for what role, whether that pin is safe for it, and what it's doing right now — the device's pin ownership map, keyed by physical GPIO the way an OS Device Manager, a Tasmota template, or a GPIOViewer diagram is.
It walks the live module tree and collects every claimed pin: each ControlType::Pin control (a mic's sckPin/wsPin/sdPin, an Ethernet PHY's ethMdcGpio, a driver's loopbackTxPin) and each "pins" text control (an LED driver's "18,19,20" lane CSV). Per claim it adds a severity flag (a claim on a reserved/strap/input-only pin, or a double-claim, via platform::gpioCapability) and the live state (level + drive strength, via platform::gpioLiveState — the see-the-wire HAL check). A disabled module's pins drop out (the map reflects release-on-disable intent).
One nested list: pins. Each row is a claimed GPIO (gpio, owner, role); a GPIO claimed by more than one control shows the first owner in the summary and every claimant in the row detail, so a double-claim is visible at a glance — the exact class of bug the GPIO-46 loopback corruption was (an output role driven onto a strap). Surfacing only: this reads the tree, it does not arbitrate. The controls are already the pin registry; this module is a reader over them, holding no state of its own.
Inversion vs the central-manager pattern. MoonLight's ModuleIO (https://github.com/MoonModules/MoonLight) is the central pin manager — it owns a JSON pin table and assigns GPIOs. projectMM inverts that: each module owns its own pins (as its own controls), and this one central module only observes and coordinates. So the reusable idea taken from ModuleIO is its per-pin report — owner + usage — not its ownership mechanism; here the owner and role are read back out of the live controls, never from a central table. The role column is name-derived (see roleFor), projectMM's equivalent of ModuleIO's usage enum without a central vocabulary.
Fixed System module. Wired by code as a child of SystemModule in main.cpp (like Tasks and I2cScan), not user-added — you don't delete the pin map. Base Generic role so no container accepts it as a user-editable child; markWiredByCode() exempts it from the persistence trim. Read-only: no editable controls. The list refreshes on [tick1s()] (a periodic sample, never the hot path), so a live pin change shows on the next second with no reboot. The list uses ControlType::List + ListSource, the read-only data-source/adapter shape (UITableView's data source, Qt's QAbstractItemModel) as TasksModule.
Public Methods¶
virtual inline void defineControls() override
: defineControls MUST be idempotent and pure: only controls_.clear() + controls_.addX().
virtual inline void tick1s() override
: Re-walk the tree once a second (off the hot path) to rebuild the claim map.