OpenDisplay Flex
Configuration extension for the reference firmware — not a separate communication protocol.
What Flex is
OpenDisplay Flex is a YAML-based configuration schema. Tools compile it into a binary TLV blob that describes a specific board: host MCU, display panel(s), pin wiring, power options, optional Wi‑Fi credentials, encryption keys, sensors, and other peripherals.
The reference firmware uses Flex so one firmware binary can support many development boards and e-paper panels. Flash a preset from the Toolbox (a Flex tool), and the device advertises the correct capabilities to any OpenDisplay client.
Clients still speak the OpenDisplay communication protocol for configuration read/write, image transfer, and encryption. Flex only defines what is stored in the configuration blob — see the YAML schema for field detail.
Who needs Flex
| You are… | Read this |
|---|---|
| Building with reference firmware on a dev board | Flex config + Flex tools |
| Adding a new panel to reference firmware | Adding a new panel + YAML schema |
| Implementing OpenDisplay on a fixed product | OpenDisplay spec only — Flex is optional |
| Writing a sender (Python, HA, custom app) | Communication protocol + Display data format |
Schema and binary format
Canonical schema: firmware/toolbox/config.yaml (version 1.2 — major 1, minor 2).
The Toolbox and reference firmware share this file.
Configuration is transferred as an outer packet: 2-byte length, 1-byte version, a sequence of
inner packets, then a 2-byte CRC. The CRC is CRC-16/CCITT-FALSE (init 0xFFFF, poly 0x1021) computed over the
container excluding the trailing CRC, with the 2 length bytes treated as zero. Each inner packet has a sequential number, a type id,
and a typed payload. Full field definitions: YAML configuration reference.
On the wire, configuration uses OpenDisplay commands 0x0040 (read), 0x0041 (write / first chunk),
and 0x0042 (subsequent chunks). After a successful write, send 0x000F to reboot and apply.
Packet types in reference firmware
The table below lists Flex packet type IDs from the schema and whether the current reference firmware parses them
at boot (config_parser.cpp).
| ID | Name | Reference firmware |
|---|---|---|
1 (0x01) |
system_config |
✓ Required — MCU type, pins, communication modes |
2 (0x02) |
manufacturer_data |
✓ Manufacturer ID and product strings |
4 (0x04) |
power_option |
✓ Battery, deep sleep, power pins |
32 (0x20) |
display |
✓ Up to 4 panels — resolution, color scheme, bus |
33 (0x21) |
led |
✓ Up to 4 RGB/status LEDs |
35 (0x23) |
sensor_data |
✓ Up to 4 sensors (e.g. SHT40) |
36 (0x24) |
data_bus |
✓ SPI / I2C bus instances |
37 (0x25) |
binary_inputs |
✓ Buttons and GPIO inputs |
38 (0x26) |
wifi_config |
✓ ESP32 STA credentials + optional server URL/port |
39 (0x27) |
security_config |
✓ AES-128 PSK and encryption flag |
40 (0x28) |
touch_controller |
✓ Touch IC + MSD slot mapping |
41 (0x29) |
passive_buzzer |
✓ Buzzer instances |
42 (0x2A) |
nfc_config |
In schema only — not parsed by reference firmware yet |
43 (0x2B) |
flash_config |
In schema only — not parsed by reference firmware yet |
BLE advertising and discovery
Reference firmware uses BLE service and characteristic UUID 0x2446 (128-bit form
00002446-0000-1000-8000-00805F9B34FB). Manufacturer Specific Data uses company identifier
0x2446 with a 16-byte payload (dynamic status, touch, sensor slots, etc.).
Clients can read the live MSD with command 0x0044.
When communication_modes includes Wi‑Fi, the device joins the configured access point and listens on
TCP port 2446 by default, advertising _opendisplay._tcp via mDNS. LAN uses the same
command bytes as BLE — see LAN transport.
Image transfer (OpenDisplay protocol)
Flex configuration tells the device display dimensions, color scheme, and capabilities (packet type 32). Image bytes use the shared
display data format. Reference firmware implements
direct write (0x0070–0x0072). Full wire spec:
image transfer.
Streaming decompression: when transmission_modes has both streaming_decompression (bit 0)
and zip (bit 1), clients may send a zlib stream with a 512-byte DEFLATE window.
New senders must not use legacy large-window zlib — if streaming decompression is not advertised, use uncompressed direct write.
Legacy acceptance ends with firmware version 2. See
streaming decompression.
Partial updates: partial_update_support: 1 advertises 1 bpp region refresh via 0x0076;
2 requires the partial stream to cover the full panel (e.g. EP426 / Seeed EN05).
Main firmware only — variants.
Full schema reference
Every field, enum, and bit in the Flex configuration schema — packet types 1 through 43, CRC rules, and examples.
YAML configuration referenceFlex tools
Browser tools for flashing reference firmware and editing Flex presets. Not needed if you only implement or talk to a fixed OpenDisplay product.
Flex tools overview