Typically bit-banging an I/O line is the common method of driving the WS2812B (WS2811) RGB LEDs. However, this ties up precious microcontroller cycles while it waits around to flip a bit. A less processor intensive method is to use one of the built-in Serial Peripheral Interface (SPI) modules. This is done using specially crafted data and baud rate settings, that when shifted out over the Serial Data Out (SDO) pin, recreate the needed WS2812B signal timing. Even when running in SPI mode, your hardware TX buffer size will limit how many pixels you can update without CPU intervention.
[Henrik] gets around this limitation by using peripheral DMA (Direct Memory Access) to the SPI module in the Microchip PIC32MX250F128B microcontroller. Once properly configured, the DMA controller will auto increment through the defined section of DMA RAM, sending the pixel data over to the SPI module. Since the DMA controller takes care of the transfer, the micro is free to do other things. This makes all of DMA memory your display buffer. And leaves plenty of precious microcontroller cycles available to calculate what patterns you want the RGB LEDs to display.
Source code is available at the above link for those who would like to peruse, or try it out. This is part of [Henrik’s] Pixel Art Project. Video of DMA based SPI pixels after the break:
[Paul Stoffregen], known as father of the Teensy, has leveraged the Teensy 3.1’s hardware to obtain some serious speed gains with SPI driven TFT LCDs. Low cost serial TFT LCDs have become commonplace these days. Many of us have used Adafruit’s TFT LCD library to drive these displays on an Arduino. The Adafruit library gives us a simple API to work with these LCDs, and saves us from having to learn the intricacies of various driver chips.
[Paul] has turbocharged the library by using hardware available on Teensy 3.1’s 32 Freescale Kinetis K20 microcontroller. The first bump is raw speed. The Arduino’s ATmega328 can drive the SPI bus at 8MHz, while the Teensy’s Kinetis can ramp things up to 24MHz.
Speed isn’t everything though. [Paul] also used the Freescale’s 4 level FIFO to buffer transfers. By using a “Write first, then block until the FIFO isn’t full” algorithm, [Paul] ensured that new data always gets to the LCD as fast as possible.
Another huge bump was SPI chip select. The Kinetis can drive up to 5 SPI chip select pins from hardware. The ATmega328 doesn’t support chip selects. so they must be implemented with GPIO pins, which takes even more time.
The final result is rather impressive. Click past the break to see the ATmega based Arduno race against the Kinetis K20 powered Teensy 3.1.
To prevent data corruption when using multiple SPI devices on the same bus, care must be taken to ensure that they are only accessed from within the main loop, or from the interrupt routine, never both. Data corruption can happen when one device is chip selected in the main loop, and then during that transfer an interrupt occurs, chip selecting another device. The original device now gets incorrect data.
For the last several weeks, [Paul] has been working on a new Arduino SPI library, to solve these types of conflicts. In the above scenario, the new library will generate a blocking SPI transaction, thus allowing the first main loop SPI transfer to complete, before attempting the second transfer. This is illustrated in the picture above, the blue trace rising edge is when the interrupt occurred, during the green trace chip select. The best part, it only affects SPI, your other interrupts will still happen on time. No servo jitter!
This is just one of the new library features, check out the link above for the rest. [Paul] sums it up best: “protects your SPI access from other interrupt-based libraries, and guarantees correct setting while you use the SPI bus”.
Most of [Necromancer]’s work involves flashing routers and the like, and he found the Bus Pirate was far too slow for his liking – he was spending the better part of four minutes to write a 2 MiB SPI Flash. Figuring he couldn’t do much worse, he wrote two firmwares for the uISP to put some data on a Flash chip, one a serial programmer, the other a much more optimized version.
Although the ATMega in the uISP is running at about half the speed as the PIC in the Bus Pirate, [Necromancer] found the optimized firmware takes nearly half the time to write to an 8 MiB Flash chip than the Bus Pirate.
It’s an impressive accomplishment, considering the Bus Pirate has a dedicated USB to serial chip, the uISP is bitbanging its USB connection, and the BP is running with a much faster clock. [Necro] thinks the problem with the Bus Pirate is the fact the bandwidth is capped to 115200 bps, or a maximum throughput of 14 kiB/s. Getting rid of this handicap and optimizing the delay loop makes the cheaper device faster.
When a Lexmark inkjet printer stopped working, [Mojobobo] was able to claim it as his own. He quickly realized that the machine was flooded with ink and not worth repairing, but that didn’t mean he couldn’t still find a use for it. When he learned that the printer’s firmware was not only upgradable but also unprotected, he knew he should be able to get the printer to do his own bidding.
[Mojobobo] started his journey with the motherboard. The unit still powered up, but it was asking to insert a “duplex module” before it would boot any further. [Mojobobo] first tried to find a way to trick the duplex module sensor, but was unsuccessful. His next step was to search for some kind of serial communications port. He didn’t have an oscilloscope, so instead he used a speaker with a wire probe. In theory, if the wire was pressed against an active serial port, he would be able to hear varying tones through the speaker. Sure enough, he found some interesting tones after probing around some ports next to a “JTAG” label. He looked up some information about the nearby chip and found that it included an SPI bus.
After some internet research, [Mojobobo] learned enough about SPI to have a rough idea of how to use it. Having limited tools available to him, he decided to use his Arduino to try to communicate with the motherboard. After wiring up a simple circuit, (and then re-wiring it) he was able to dump the first 4096 bytes of the motherboard’s boot loader to the Arduino via the SPI interface.
[Mojobobo’s] next steps will be to find a faster way to dump the boot loader. At 9600 baud, he grew tired of waiting after three hours. Once he has the full boot loader he intends to search for a way to bypass the duplex sensor and get the board to finish booting. Then he may just use the printer for its scanning functions, or he might find other interesting uses for it.
The WS28xx offerings place a microcontroller inside an RGB LED, allowing them to be individually addressed in very long chains or large matrices (still a chain but different layout). But the timing scheme used to address them doesn’t play well with traditionally available microcontroller peripherals. [Brett] had been intrigued by some of the attempts to bend hardware SPI to the will of the WS2811 — notably [Cunning_Fellow’s] work featured in this post. He took it a great step forward by simplifying the driver to just one transistor, three resistors, and a capacitor.
Click through the link above for his step-by-step description of how the circuit works (it’s not worth re-explaining here as he does a very concise job himself). The oscilloscope above shows the SPI signal on top and the resulting timing signal below. You will notice the edges aren’t very clean, which requires the first pixel to be very close to the driver or risk further degradation. But, since the WS28xx drivers feature a repeater which cleans up signals like this, it’s smooth sailing after the first pixel.
Although it’s still a prototype, [Russell] tipped us off to his battery-powered device for storing your contacts list: ContactKey. (Warning: Loud sound @ beginning). Sure, paper can back up your contact information, but paper isn’t nearly as cool to show off, nor can it receive updates directly from your Android. The ContactKey displays a contact’s information on an OLED screen, which you can pluck through by pressing a few buttons: either ‘Up,’ ‘Down,’ or ‘Reset’. Although the up/down button can advance one contact at a time, holding one down will fly through the list at lightning speed. A few seconds of inactivity causes a timeout and puts the ContactKey to sleep to conserve battery life.
This build uses an ATMega328 microcontroller and an external EEPROM to store the actual list. [Russell] wrote an Android app that will sync your contact list to the ContactKey over USB via an FTDI chip. The microcontroller uses I2C to talk to the EEPROM, while an OLED display interfaces to the ATMega through SPI. We’re looking forward to seeing how compact [Russell] can make the ContactKey once it’s off the breadboard; the battery life for most smartphones isn’t particularly stellar. Phones of the future will eventually live longer, but we bet it won’t be this one.