Cogless Pixel Drivers for P2
JonnyMac
Posts: 9,105
There are many applications that use just a few smart pixels, and in those cases we can save a cog when using the P2. Attached are drivers for 1-wire (WS2812b, et al.) and 2-wire (APA102c) pixels. Both use inline PASM, and the 2-wire driver uses Smart Pin SPI to generate the output.
These drivers work like Schmarschmino drivers: you change the pixels (with object methods or directly in the app), then call the show() method to refresh the pixel string. Some 1-wire pixels swap the red and green bytes in a color, so there is a swap flag as part of the show() method in that driver.
These are minimalist drivers -- not fancy, but they work well and don't need a cog. I'm using them in a couple of work projects.
Updated: 04 MAY 2024
Comments
I didn't like that I was passing the swap flag in the show() method of the single-wire driver. After a great dinner with my friend, Rick Galinson (Mandalorian, Book of Boba Fett, Ahsoka, lots of movies and commercials) last night, and some much needed rest, I found a way to fix that. Of course, it seems obvious now.
If you downloaded these drivers before I put the "Updated" notice in post #1, please replace them with what's posted now. The swap flag is passed in the startx() method and, so the show() method doesn't need that parameter. I did some formatting clean-ups, and did my best to make both drivers very consistent with each other. Code written for one driver is easier to migrate to the other now (just start() or startx() method change).
This is very useful for me, thanks.
I dumbed this down a lot for a certain application....
Neat idea to have a simpler driver for single pixels.
Was there a previous single-pixel version for P1; thinking about driving the Parallax #28085 WS2812B module without a cog ?
Ha! Just realised that APA102c you're using @JonnyMac uses the host clock, so you can deploy a much simpler driver than is possible with the WS2812B timing.
I'm often using something suspiciously similar, probably for the same reasons where only a couple indicators are needed and cogs are at a premium. I'll post the "shift out" style driver to OBEX later if I don't find one from you there.
Anyway- figured I'd share the datasheet, especially for anyone in Europe who might struggle to get the APA device. These clocked serial RGB's are super handy!
@VonSzarvas Yes, was testing with that Parallax module. Also testing with a new SMT version of neopixel...
The first device I ever worked with (2009-ish) was called the WS2801 which was a 2-wire device. This was long before pixels were commonplace at Adafruit or other suppliers. I got them from a friend who imports containers full of LEDs. Believe it or not, I tested the original device using a BASIC Stamp 2. Things have come a long way since, but the Px processors have certainly made the single wire devices easier to deal with.
There are a lot of single-wire pixels, but I mostly use the WS2812b at work, so I also broke out that variant as its own object. I'll attach it to the first post.
Neat - not much overhead there.
Is there anything in the PASM2 part that wouldn't compile under PASM for P1 ? (like, any P2 specific instructions that this solution relies on?)
(yeah I know, I should wait to try it before asking
Edit: looking at the code, the inline PASM would need adjustment, but that doesn't seem like an issue for conversion. Just if the PASM2 in the show method relies on anything P2 specific. Apart from setregs maybe (which I don't recognise yet), nothing else jumps out as being irreplicable... Doesn't seem to be using smartpins...
Yes. In the P1 we need to create a bitmask for the pin, and deal with the OUT and DIR registers -- that's all one instruction in the P2. The biggest change, though, is reversing the positions of the red and green bytes before the data is transmitted.
P1 (from jm_rgbx_pixel.spin):
P2:
The movbyts instruction is magic.
Note that I include the option to test for R/G swapping in my WS2812b P2 driver so that I can use it with other pixels. There is a version called the APA106A that is a pixel in a standard 5mm LED body (with 4 wires), and that doesn't require RG swapping.
The P2 rep and waitx instructions make the mane shift_out loop more efficient, too.
P1
P2:
My 1-wire pixel drivers for the P2 don't use smart pins, but my 2-wire driver does. It may be possible to use a smart pin for 1-wire pixels (using pulse mode), but I don't think there'd be any benefit given the overhead required by smart pins.