I’ve got a pretty cool new library just about ready to publish on github. I’ve been playing around with WS2812b LEDs lately, and have been using my trusty TI Tiva C Series and Stellarisware launchpads.
The first thing I did with these was to hijack the SPI peripheral to drive the data lines on the LED strip. I thought myself rather clever for realizing that the proprietary one wire protocol the 2812s use could be functionally implemented using the SSI protocol given the right combination of bit packing and frequency setting, but a bit of googling showed me that this is pretty normal nowadays, especially on the Arduino platform. Ah well… If you haven’t seen it, it’s novel to you? Still feel accomplished for that, but nothing groundbreaking enough to post about (hence why I haven’t mentioned it here, despite having it working since last April).
What to do next then? Well, my library for the 2812s relied on waiting for the SSI interrupt to signal another byte was ready for the bus, filling the byte, and waiting for the next TX done signal to come in. It was ok for parallel processing in the sense that it at least didn’t just sit in a spinloop while the data was transferring, but I still felt my solution was rather inefficient. Enter the uDMA engine. My sample code is now to the point that the uDMA engine is set up to be constantly running on the transmit array. This means you can update the output color array at any point in software, and the uDMA engine will cause the change to “automatically” propagate onto the LED strip, with an extremely minimal amount of software overhead. The only processor overhead for this method is an interrupt subroutine executing each time the LED strip is ready to be refreshed, which consists of about eight lines of code.
My next step is going to be integrating my uDMA sample code into a proper uDMA library. I really like the writeup ADAfruit has on interrupts, and I think it would be cool to do a similar writeup on what DMA is and how it works. So step one will be getting a proper uDMA based library up on github. Step two, use that library as the basis for a post on what DMA is, how it works, and how to set up the uDMA engine on a Stellaris/Tiva C microcontroller.
On a more personal note, I’ve gotta say it was unspeakably enjoyable getting this up and running. From starting to look at datasheets to having a constantly changing rainbow pattern sent out to the LED strip via uDMA, it took about two hours to get everything up and running. Two hours, start to finish, to implement something pretty damn cool. I’m still working on finding my footing in the post-silicon validation job I took back in March for an ARM based server chip, and it was so, so nice to just open up a well written datasheet, grab some documentation for a software library written by folks who specialize in customer facing software libraries, and knock out some application code. I miss that