It is often written that Neopixels are not directly controllable by manipulating GPIO pins on SBCs because the precise timings cannot be met, especially when from user space. I need somehow to drive the TLC5947 that is a full color RGB LED driver taking the following signals:
- Data (SIN), a bit to read.
- Clock (SCLK), read a bit to display as currently represented by SIN.
- Move from shift register to display register (XLAT).
From the description looks like it only matters how do these signals relate to each other. Hence I could set the SIN bit first, wait for a short time, then set the SCLK clock, wait, remove the SCLK clock, repeat. Even if my delay times vary slightly, should not actually matter as long as I keep the order which signal goes after what. Hence if my C++ program controls all 3 bits as separate GPIO lines (for instance, by writing into /sys/class/gpio/ as described here) I hopefully could get without adding a separate Arduino board and the solving another complex problem how the board should communicate. Is it reasonable to expect this to work? 24 channels is not so many, it it would manage in a couple of seconds, should be ok.
From my search over web it looks there may be other (and likely “cleaner”) ways to solve this problem but after two days of googling I have lost myself completely between all kinds of Python, Arduino, Neopixels and RPi. My device is Jetson Nano, my programming language is C++ and I need to drive my specific device. If anybody knows the alternative and better way to solve my problem, this would also be a great answer.
Another question about tlc5947 is here. It is not closely relevant.
Yes, you could do this.
The LED driver you describe has a synchronous serial configuration/data interface where timing requirements are mostly relative and minimum – typically with such a thing you can operate essentially as slowly as you like. And this interface is quite decoupled from the actual PWM operation of the LEDs.
This is in contrast to single-wire “Neopixel” type interfaces where timing is critical to transmitting the data at all. (Though there also exist other LED-string solutions which have both a clock and data line).
What you’ll have to more deeply study the hardware and peripheral driver documentation to determine, is if there’s any functional block in the Jetson’s SoC which you could use to help transmit the data, for example an SPI engine, or perhaps a re-purposed I2S audio one, or some more generic synchronous serial engine. Some SoC’s also have MCU-like auxiliary processors which could handle tasks like this (potentially even driving Neopixels). If you can feed the GPIO block with DMA, it may also be possible to setup a bitmapped “waveform” for the clock and data signals in memory and have that clocked out at a steady rate by the DMA engine (you’d probably have to represent at least a byte worth of channels, even though you’d only be using two pins, but on a board like this you have a lot of memory)
Particularly if you end up “bit-banging” this from software, your real concern may be not so much sending the data, but ensuring that the colors change at the times you want them to – especially if you are doing any audio/video type synchronization. If you do end up bit-banging, you’ll probably want to do the actual I/O twiddling in a kernel driver, not userspace.
At a practical level Adafruit sells a board with this chip, and they have a python-ish solution for driving it from a Raspberry Pi as part of a larger collection of gadget interface functionality. It would appear that software collection has at least partial support for some Jetson boards, though you’ll have to see for yourself if that includes your board, and if it includes the particular SPI functionality you’d need to operate this board in the way they operate it on a pi: