For those that may remember the old LEDScape library, I’ve been working on an updated version of that library, which focuses on strips instead of matrices, uses rproc instead of UIO PRUSS, and updates the PRU assembly to clpru from pasm.
Link: https://github.com/iontank/ThrowingBagels
The key thing you need to know is that we hook up 32 addressable LED strips and then use the PRU to bitbang out RGB(W) data. We use the PRU because our timings need to be pretty precise- a few hundred nanoseconds for each key phase of the operation.
Here’s the important issue: we need to address all 32 GPIO pins from the PRU, but not all of them are bound to the r30 register. So we need to go through the OCP port. This is exactly how LEDScape worked, and continues to work, just fine. We’ve never been able to get LEDScape working under 4.x kernels, mostly because of UIO problems (which is what kicked off this whole “move to rproc” thing).
My upgrade, ThrowingBagels, uses basically the same core logic on the PRU, just ported to clpru assembly and running on a 4.19 kernel. And seemingly randomly, the timings hitch which causes the LEDs to flicker to the wrong color. Phases of our bitbang operation will sometimes take almost twice as long as they should- a sleep that should have been 600ns ends up taking 1100ns. The only operation happening that doesn’t have guaranteed timings is writing to the GPIO pins via OCP, everything else we do happens entirely in PRU DRAM. Since this appears to happen randomly, the hitch must be coming from that OCP step, I assume.
In support of that hypothesis, if I upgrade from the kernel that ships with the “AM3358 Debian 10.3 2020-04-06 4GB eMMC IoT Flasher” image to the most recent 4.19 kernel, the problem becomes a lot more infrequent. We’re blasting this data out at 30fps, like video, and when cut down on the number of services running and update the kernel, I can get the glitches down from happening every few seconds, to happening every few tens of seconds.
My suspicion, and I can’t quite prove anything, is that on 4.19 there’s something about the kernel or configuration that sometimes adds latency to OCP writes, which wasn’t there on 3.16. So my key question is: how do I improve the timing consistency when the PRU uses OCP to write to DDR RAM? I understand that it will never have guaranteed timing, but sometimes it’s hitting me with latencies of up to 500ns. Anything I can do to minimize that latency would be a huge help.
TL;DR: how can I make PRU->OCP->GPIO more consistent in its timing under a 4.19 kernel?