Skip to content

PanelCardDriver

Source: PanelCardDriver.h

PanelCardDriver

class PanelCardDriver
src/light/drivers/PanelCardDriver.h:28

Inherits: DriverBase

Output driver: streams the buffer to LED panel cards over raw Ethernet frames, below IP.

These cards take a sender-card feed, so they need an L2 seam rather than a socket. The wire format lives in [ColorLight5A75Packet.h], and this driver owns the window, the correction and the chunking. The board renders and sends, making the device a complete panel controller.

Prior art: FPP (Falcon Player), which drives these cards from a Raspberry Pi, and the ColorLight 5A-75 documented byte layout. The wiring, the vendors and the host setup are on the panel cards page.

Public Attributes

uint8_t format = 0 : Wire format (index into kFormatOptions).

uint8_t firmware = 0 : Card firmware generation (index into kFirmwareOptions): 0 is v12-and-older, 1 is v13+.

uint8_t interfaceSel_ = 0 : Host NIC to send from, row 0 being capture-only. Not built on ESP32.

char chosenIf_ = {} : The label behind the selected row, so a reordered list restores the same NIC.

uint8_t lastResolvedSel_ = 0 : The row the last rebuild settled on, which tells a user's pick from a re-enumeration.

uint8_t fps = 40 : Send-rate ceiling (Hz); [tick()] rate-limits so a fast render tick doesn't saturate the link.

Public Methods

inline PanelCardDriver() : Default to the RGB preset, as the network sinks do, rather than the strips' GRB.

virtual inline void defineDriverControls() override : Bind the format, the host interface and the shared window, after the correction block.

virtual inline bool affectsPrepare(const char * name) const override : Which controls re-run the prepare sweep: the geometry, the window and the interface.

virtual inline void release() override : Drop back to capture mode so a disabled driver holds no raw socket, then chain to the base.

virtual inline void setSourceBuffer(Buffer * buf) override : Take the shared source buffer and size the corrected_ buffer for it.

virtual inline void prepare() override : Bind the raw interface, size the corrected buffer, and publish the link status.

virtual inline void tick1s() override : Refresh the link status once a second, so a cable plugged in later is picked up.

virtual inline void onCorrectionChanged() override : A preset toggle changes correction_.outChannels without a structural rebuild.

virtual inline void tick() override : Correct the window, emit it row by row, and latch it with one sync frame.

inline void writeLinkStatus() : Report what the wire is doing: no link, a link too slow, or the packet rate reaching it.

inline const Buffer & correctedBuffer() const : Test-only accessor for the corrected buffer, pinning the no-allocation contract.

Public Static Attributes

constexpr uint8_t kCardGain = 0xFF : The card's own gain, held at full so it does not compound our own brightness.

constexpr const char * kFormatOptions = {"ColorLight 5A-75"} : Wire formats; the control exists because the category is panel cards, not one vendor.

constexpr uint8_t kFormatCount = 1 : How many wire formats the selector offers.

constexpr const char * kFirmwareOptions = {"v12 and older", "v13 and newer"} : Card firmware generation, which decides whether the sync frame goes out once or twice.

constexpr uint8_t kFirmwareCount = 2 : How many card firmware generations the selector offers.

More info

The cards require a 1000 Mbps link, for wire time rather than bandwidth. They latch on the sync frame with no buffering, so a whole frame must arrive inside the inter-frame window. At 100 Mbit the same bytes overrun the frame budget and break the timing the sync depends on.

A slow link is silent: frames go out, the link is up, and the panels tear or never latch. The driver reads the negotiated speed and says so, then sends anyway, since a small panel may be fine.

No geometry controls

The panel arrangement belongs to the Layout. It states the count, size, wiring order and snaking, and maps every light to an (x, y). This driver reads the finished picture and cuts it into card rows. So a wall is described in exactly one place.

PanelCardDriver card