/* Imported from Wayback Machine
Original URL : https://retrobrewcomputers.org/doku.php?id=builderpages:plasmo:zrc512:driving_ws2812 Snapshot date: 2025-10-15 Generator : wayback-archiver
*/
Driving WS2812 NeoPixel LED with ZRC512
The timing spec for WS2812 is fairly loose; it is nominally 800KHz 33%-67% pulse-width modulation. The 1.25uS period is divided into 3 phases. The first phase, nominally 400nS, is always high; the 2nd phase is also 400nS in duration and contains the actual information such that high denotes '1' or low denotes '0'; the third phase is 450nS and always low. The timing is fairly loose with tolerance of +/-150nS.
ZRC512 is designed for 22MHz clock which is too slow to software bit-bang WS2812 without hardware help. ZRC512 CPLD has enough spare logic to provide hardware assistance to generate timely output to drive WS2812. The schematic below shows a return-to-zero pulse generator that either generate a 363nS high pulse if D[7]=0, or a 726nS high pulse if D[7]=1. Ideally the software provides a new D[7] value every 1250nS, but WS2812 is fairly tolerant of timing variation in low pulse. The following routine will provide 1260nS pulse period when outputting the 8-bit color value, and 1935nS pulse period between 8-bit of colors. 1260nS period is exactly the correct timing and 1935nS appears to be adequate.
doGrn:
out (WS2812),a ;11
rla ;4
djnz doGrn ;13 or 8 B==0
ld b,8 ;7
inc hl ;6
ld a,(hl) ;7
doRed:
out (WS2812),a
rla
djnz doRed
ld b,8
inc hl
ld a,(hl)
doBlue:
out (WS2812),a
rla
djnz doBlue
ld b,8
inc hl
ld a,(hl)
;more LED, so on...
TO DO
upload picture of ZRC512 driving
upload demo program
