This project is related to the Hexagone Table because it's cool to have a Linux powered coffee table !
Before we start, this project began in December 2021, the objective was to take a re-dive by myself in TI PRU with the BeagleBone Black. I had done some code in assembly and it was a pain in the ass but a good exercises back in 2013. Since then I saw other projects, like FPP, I didn't look back then because the objective was to do it on my own and master it.
The 427 LEDs in the table could have been driven by WLED, which I discover only in October 2023, but at the time I was a fan of Espruino for quick development with ESP8266 and ESP32. I used Espruino in many DIY IoT projects, temperature sensor and Alexa compatible relays. The counter part of the "plug and play" of Espruino is performance when playing with numerous Neopixels.
As an embedded Linux engineer, I return to my circle of trust, use a Linux environment witch help for debugging on PC and can run on embedded devices like the BeagleBone Black with has 2 PRUs in order to create a "Neopixel driver".
I started with the PRU Software Support Package and the gpioToggle example and follow this steps:
- Create the configuration
- Start counter, PRU will send data while counter is positive and decrement at each loop
- number of LED, is the same all outputs
- Memory offset for each outputs
- GPIO mask for the 8 outputs
- Initialize the memory with a pattern
- Drive 8 GPIOs
- Correct the timing to match ws2811 specs
- At 800Khz and 8 bit to fetch at different memory offset there is no time to spare
- The bit time is 1.25us and there is 3 phases for each bit, all the bit banging time is used
- time High : Fetch 3bit
- time between : Fetch 3bit
- time Low : Fetch next 2bit
The memory used is the shared memory of the PRU, in the am335x there is 12KB that are accessible both to PRU and Linux, witch mean 4096 RGB LEDs can be driven with this space.
During testing I found that GPIO shared with the Linux introduce some latency in the bit banging and disrupt the sending, I then switched to PRU GPIO with are directly mapped to the register R30. After a long period of testing, and nearly giving up, there was this variable that souldn't have been declared as volatile.
There it was, the "Neopixel driver", some memory mapping on Linux, configure the size and increment the start counter and there is goes bit banging Neopixel data like crazy.
In September 2023, I joined the carnival of Cholet. I got in touch with a team, System'D, that was using WS2811 for some time but the driver T300K they were using with LedEdit 2014 was out of order with few alternative. The characteristic of the T300K are:
- 8 outputs up to 1024 RGB LEDs with industrial connectors
- 100Mbit/s ethernet
- dip siwtch for driver ID
- Screen for ID display
- Embedded power supply
I wanted to go big with LEDs number, I was served, I never tough that 4096 could be a limitation but challenge accepted. The protocol used by LedEdit 2014 was also a mystery to be solved to make this work, this will be detailed in an other project.
Finding 24KB of shared memory keep spinning in my head until I look on the PRU datasheet and realized that there was 8KB for each PRU, aka 16KB of ram and the 12KB already used before, but I had to let go what wasn't necessary, memory did not need to be contiguous. The other loss was the second PRU couldn't be used any more, I couldn't care less.
More information on software are detail in this project.
Some extra requirement came along, the will to drive WS2801 which need a clock for reference. In the PRU code there was some time left to drive other 2 GPIO as clock over the same code. Witch mean that WS2812 and WS2801 could be driven without any differences.
And there we go back to some hardware to drive those LEDs, after the prototype, PCB were made with
- SN74AHCT245N buffer
- DS01C-254-L-06BE dip switch
- TBP01R1-508-03BE connectors

With version 2 of the board, we added an OLED display...
Read more »