WS2812 - easy and reliable

  • A UART can provide the perfect timing for the WS2812.

    One bit of the WS2812 stream is built from 3 bits of the UART. A zero is transmitted with 1 of 3 bits set. A one is transmitted with 2 of 3 bits set.

    With 2.4MBaud the timing is 417us / 833us. This matches perfectly the specification.
    Each WS2812 bit is formed with 3 UART Bits. The first is always 1, the last always 0. The Bit in the middle defines the State.
    Three of these WS2812 bits (WB) require 9 UART bits. This is 1 Start- 7 Data- and 1 Stopbit.
    STA /WB0 0 1 /WB1 0 1 /WB2 STO

    The output signal must be inverted for proper polarity of STA and STO. Since a HCT driver is needed anyway, the only difference is to use an inverting buffer (NAND / NOR)

    Only 8 Bytes are required to drive 1 LED. TxFIFO if available reduces ISR rate furthermore.

    I'd be glad to help improving the support for WS2812. I use this kind of driver with CortexM3 devices LPC1343, LPC1517. It works fine !

    Can anyone confirm that the Pi UART supports a Baudrate between 2.25MBaud and 2.4MBaud ?

  • It will probably only work if the uart driver in the kernel supports back to back transfers with dma to keep it fed.

    On an simple MCU this is easy as you have complete control over the hardware and there is no kernel scheduling your process to sleep.

    What you describe is nearly exactly what I wrote using the SPI device - it supports dma on the Pi. I was too lazy to do lots of bit shifting so I used 4 spi bits per ws2812 bit.

    If the Pi supports DMA and doesn't require hitting the hardware directly this could be another good option.

  • Hi penfold, Thanks for your reply.

    Even the UART has no DMA it has a 16Byte TxFIFO with selectable trigger levels. If set to 1/2 it would call the ISR when still 8 bytes are in the TxFIFO. There are another 36us until the TxBuf runs empty. With 7/8 level it would be 60us. Is the ISR latency longer ?

    The documentation says that WS281X-PWM often causes problems. Is this related to LedDeviceWS281x.cpp or LedDeviceWs2812SPI.cpp ? Are these two independendent implementations or do they belong together ?

    A possible source of problems in LedDeviceWs2812SPI could be the timing violation. The resulting duty cycle is 0.25 or 0.5. Following the specs it should be 0.33 or 0.67. This is easily done with a multiple of 3 bits. The SPI Interface supports a 4 entry FIFO with 24 bit transfers. One transfer handles one LED.

    I would be glad to help testing.

  • The LedDeviceWS281x uses PWM and has to hit the hardware registers directly bypassing the kernel. This causes 2 problems:
    1) conflict with the analog audio which must be disabled.
    2) DMA Chanel conflict - there didn't seem to be a clean way to claim a free DMA channel and if you happen to use the channel the sd card is using, "bad shit" happens

    The SPI timing is within spec - at least it used to be within tolerances from one version of the data sheet. (There's been a few)

    If you want to try it anyway it should be pretty easy - there are low level rs233 and spi drivers so it should be easy to hack the existing 2812 spi driver and point it to rs232. It would be interesting to see what the CPU load is.

Participate now!

Don’t have an account yet? Register yourself now and be a part of our community!