Skip to content

Source: PinList.h

PinList

The light-domain half of pin and count list parsing for multi-output LED drivers.

Functions

Return Name Description
const char * assignCounts inline Fill one count per pin from the ledsPerPin text, returning null or an error literal.

assignCounts

inline

inline const char * assignCounts(const char * s, uint8_t nPins, nrOfLightsType totalLights, nrOfLightsType * counts, nrOfLightsType maxPerPin = 0, const char ** warn = nullptr)

Fill one count per pin from the ledsPerPin text, returning null or an error literal.

Variables

Return Name Description
constexpr nrOfLightsType kMaxWs2812LedsPerPin constexpr The per-pin light ceiling for a WS2812-class one-wire protocol, past which output is a slideshow.
constexpr const char * kClampedWarning constexpr The warning a caller shows when a pin's count was clamped to the ceiling.

kMaxWs2812LedsPerPin

constexpr

constexpr nrOfLightsType kMaxWs2812LedsPerPin = 2048

The per-pin light ceiling for a WS2812-class one-wire protocol, past which output is a slideshow.


kClampedWarning

constexpr

constexpr const char * kClampedWarning =
    "some LEDs not driven: over per-pin max; add pins or use start/count"

The warning a caller shows when a pin's count was clamped to the ceiling.

More info

[RmtLedDriver] takes one RMT channel per pin and [I80Peripheral] one i80 data lane per pin, each driving consecutive slices of the source buffer from two text controls. The GPIO CSV parser parsePinList is a domain-neutral core primitive, while the count distribution here speaks nrOfLightsType and so stays in the light layer. Both return null on success, or a static error literal for setStatus. unit_RmtLedDriver_pins.cpp pins them on the host.

How a count list is read

assignCounts fills one count per pin from the ledsPerPin text. It uses the broadcasting idiom NumPy and CSS share, where a scalar applies to all and a list maps element-wise, plus an auto-fit empty case.

Written What it means
empty an even split, the total over the pin count, the last pin taking the remainder
N that many on every pin, broadcast
3,4,5 mapped per pin in order, a list shorter than the pins even-splitting the rest over those unlisted

A list longer than the pin count ignores the extras, since a stale list after the pins shrank is not an error. Explicit counts are clamped so the running sum never exceeds the total.

The per-pin ceiling

maxPerPin is the driver's protocol ceiling on lights per data line. A pin exceeding it is clamped, so the driver drives the first maxPerPin and stays lit rather than choking on the rest.

It is per-protocol, so each driver passes its own. A WS2812-class one-wire line, whether RMT, LCD_CAM or Parlio, clocks a fixed 30 microseconds a light, so 2048 a pin is already about 16 frames a second. A clocked two-wire SPI type such as APA102 or SK9822 runs at tens of MHz and manages ten thousand or more a pin, so it passes a far higher cap. Passing 0 means no ceiling. The intended way to output fewer lights is the driver's start and count window rather than this safety cap.

On a clamp the caller's warn is set, a warning it shows while still running. That is distinct from the return value, which stays null, because clamping is not an error that idles the driver.

What clamping does to the later pins

Offsets accumulate from the clamped counts, so clamping one pin shifts every later pin's source slice down by the trimmed amount. For the headline case, a whole grid funneled onto one pin, that is exactly right: the pin drives the first maxPerPin and nothing follows it.

For the pathological case of several pins each over the ceiling, the later strips show a shifted window rather than a truncated one. That is accepted rather than fixed: it degrades rather than crashes, and nobody wires the misconfiguration on purpose. Preserving alignment would need a parallel array of unclamped counts, which is more state for a case the warning already flags.