# 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 |