Go to file
Xiretza 5fb8d3a176 gitignore: ignore __pycache__ 2022-07-14 15:59:32 +02:00
vhdl fix: workaround nextpnr-xilinx#42 2022-07-14 15:59:32 +02:00
.gitignore gitignore: ignore __pycache__ 2022-07-14 15:59:32 +02:00
.gitmodules Add ws2812 submodule 2022-06-05 10:21:44 +02:00
LICENSE fix: add license 2022-06-21 07:21:16 +02:00
Makefile chore: clean up makefile, remove unused targets 2022-06-20 13:24:31 +02:00
Makefile.nextpnr fix: suppress ghdl binding warnings during synthesis 2022-06-20 13:16:51 +02:00
Makefile.symbiflow fix(Makefile.symbiflow): fix read_verilog yosys command 2022-06-03 22:18:09 +02:00
README.md doc: add packet structure to README 2022-06-20 14:13:05 +02:00
arty_a7_35.xdc vhdl: rename clk_sys to sys_clk 2022-06-05 21:36:10 +02:00
gen_liteeth.py Pixel UDP port demo 2022-06-05 16:35:20 +02:00

README.md

WS2812 driver gateware for blinkenwall v3

At 100 FPS, a single strand of WS2812 can only be just over 300 LEDs long:

MAX_LENGTH = (1 / FPS - RESET_TIME) / BIT_TIME / BITS_PER_PIXEL
318 = (1 / 100 - 50e-6) / 1.3e-6 / 24

Because blinkenwall v3 has 64 * 96 = 6144 pixels, driving it at 100 FPS requires at least 6144 / 318 = 20 parallel drivers. For simplicity, the wall is devided into 24 strands of 256 LEDs. Unfortunately, most microcontrollers have at most a couple WS2812-capable interfaces (typically SPI), so this would require coordinating several microcontrollers in parallel. A much more integrated solution is to instantiate as many WS2812 drivers as desired in an FPGA, then point the entire video firehose at the FPGA.

Ethernet communication

The controller accepts UDP packets containing image data on port 61437 ("PIXEL"). Each packet contains color data for one strand of LEDs.

The packet structure is as follows:

00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
00 magic (0x5049_584c) strand number frame number 0 px1 R px1 G px1 B
10 0 px2 R px2 G px2 B 0 px3 R px3 G px3 B 0 px4 R px4 G px4 B ...

Every packet begins with a magic number 0x5049584c (ASCII for "PIXL"), followed by the strand number and the frame number. All numbers are big endian. After the header follows the pixel data, separated into one 4-byte word per LED.

Once all strands for a given frame number have been received and the video page has been flipped, the controller answers with a confirmation packet:

00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
00 frame number