Fadecandy is firmware for the [Teensy 3.0](http://www.pjrc.com/store/teensy3.html), a tiny and inexpensive ARM microcontroller board.
...
...
@@ -8,9 +8,9 @@ Fadecandy drives addressable LED strips with the WS2811 and WS2812 controllers.
This firmware is based on Stoffregen's excellent [OctoWS2811](http://www.pjrc.com/teensy/td_libs_OctoWS2811.html) library, which pumps out serial data for these LED strips entirely using DMA. This firmware builds on Paul's work by adding:
* A high performance USB protocol
* Zero-copy architecture
* Zerocopy architecture with triple-buffering
* Interpolation between keyframes
* Gamma correction
* Gamma and color correction with per-channel 256-entry lookup tables
* Temporal dithering
These features add up to give *very smooth* fades and high dynamic range. Ever notice that annoying stair-stepping effect when fading LEDs from off to dim? Fadecandy avoids that using a form of [delta-sigma modulation](http://en.wikipedia.org/wiki/Delta-sigma_modulation). It rapidly wiggles each pixel's value up or down by one 8-bit step, in order to achieve 16-bit resolution for fades.
...
...
@@ -27,3 +27,94 @@ Prerequisites
* The recommended ARM toolchain, from <https://code.launchpad.net/gcc-arm-embedded>
* The Teensy Loader: <http://www.pjrc.com/teensy/loader.html>
Color Processing
----------------
The Fadecandy firmware maintains a color lookup table with 256 8-bit entries for each of the three color channels. The input values to this LUT are the 8-bit colorspace as used in the framebuffer's 24-bit pixel values. The outputs are a 48-bit color which acts as the input for Fadecandy's dithering algorithm.
Why 48-bit color? In combination with our dithering algorithm, this gives a lot more color resolution, especially near the low end of the brightness range where stair-stepping and color shift can be most apparent.
Each pixel goes through the following processing steps in Fadecandy:
* 8 bit per channel framebuffer values are expanded to 16 bits per channel
* We interpolate smoothly from the old framebuffer values to the new framebuffer values
* This interpolated 16-bit value goes through the color LUT, which itself is linearly interpolated
* The final 16-bit value is fed into our temporal dithering algorithm, which results in an 8-bit color
* These 8-bit colors are converted to the format needed by OctoWS2811's DMA engine
* In hardware, the converted colors are streamed out to eight LED strings in parallel
USB Protocol
------------
To achieve the best CPU efficiency, Fadecandy uses a custom packet-oriented USB protocol rather than emulating a USB serial device. This simple USB protocol is easy to speak using cross-platform libraries like [libusb](http://www.libusb.org) and [PyUSB](http://pyusb.sourceforge.net/). Examples are included. If you use the included [Open Pixel Control](http://openpixelcontrol.org/) bridge, you need not worry about the USB protocol at all.
Attribute | Value
--------------- | -----
Vendor ID | 0x1d50
Product ID | 0x607a
Manufacturer | "scanlime"
Product | "Fadecandy"
Serial | Unique for each Teensy 3.0 board
Device Class | Vendor-specific
Configurations | 1
Endpoints | 1
Endpoint 1 | Bulk OUT (Host to Device), 64-byte packets
The device has a single Bulk OUT endpoint which expects packets of up to 64 bytes. Multiple packets may be transmitted in one LibUSB "write" operation, as long as the buffer you provide is a multiple of 64 bytes in length.
Each packet begins with an 8-bit control byte, which is divided into three bit-fields:
Bits 7..6 | Bit 5 | Bits 4..0
---------- | ----------- | ------------
Type code | 'Final' bit | Packet index
* The 'type' code indicates what kind of packet this is.
* The 'final' bit, if set, causes the most recent group of packets to take effect
* The packet index is used to sequence packets within a particular type code
The following packet types are recognized:
Type code | Meaning of 'final' bit | Index range | Packet contents
0 | Interpolate to new video frame | 0 … 24 | Up to 21 pixels, 24-bit RGB
1 | Instantly apply new color LUT | 0 … 24 | Up to 31 16-bit lookup table entries
2 | | | (reserved)
3 | | | (reserved)
In a type 0 packet, the USB packet contains up to 21 pixels of 24-bit RGB color data. The last packet (index 24) only needs to contain 8 valid pixels. Pixels 9-20 in these packets are ignored.
Byte Offset | Description
------------- | ------------
0 | Control byte
1 | Pixel 0, Red
2 | Pixel 0, Green
3 | Pixel 0, Blue
4 | Pixel 1, Red
5 | Pixel 1, Green
6 | Pixel 1, Blue
… | …
61 | Pixel 20, Red
62 | Pixel 20, Green
63 | Pixel 20, Blue
In a type 1 packet, the USB packet contains up to 31 lookup-table entries. The lookup table is structured as three arrays of 256 entries, starting with the entire red-channel LUT, then the green-channel LUT, then the blue-channel LUT. Each packet is structured as follows: