Fadecandy: 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 and PyUSB. Examples are included.
If you use the included
fcserver daemon, you need not worry about the USB protocol at all.
|Serial||Unique ID string|
|Device Version||See below|
|Endpoint 1||Bulk OUT (Host to Device), 64-byte packets|
The Fadecandy device has one USB Configuration with two Interfaces:
- Interface #0 is a vendor-specific interface with one Bulk OUT endpoint for communicating control data and video keyframes.
- Interface #1 is compatible with the USB Device Firmware Update spec. It's used during firmware upgrade to ask the device to enter bootloader mode. During normal operation, it's safe to ignore this interface.
Some device version codes may be used to indicate experimental or unofficial firmware. Currently, versions in the range 0x0300 through 0x03FF are reserved for unofficial Fadecandy firmware forks.
To use the Fadecandy Controller's USB protocol directly, you'll need to:
- Search for the device you're interested in. You can look for all Fadecandy devices by looking at the Vendor and Product IDs. You can find a specific Fadecandy device by looking at its USB serial number string.
- Open the device, and set its configuration. Depending on the operating system, you may also need to claim interface #0 so your application has exclusive access to it.
- Set up a Color Look-Up Table. There is no default table, the firmware expects you to calculate one based on the gamma and whitepoint you'd like to use.
- Send Video Frames at any time. When you complete a frame, the firmware immediately begins interpolating to it.
There's a minimal example written in Python using PyUSB. It calculates a simple Color LUT and sends random video frames.
To compare with the Color LUT calculation used by
fcserver, see the FCDevice::writeColorCorrection function in the fcserver source code.
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)||0||Set configuration data|
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.
|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|
Color LUT Packets
In a type 1 packet, the USB packet contains up to 31 lookup-table entries. The lookup table is structured as three arrays of 257 entries, starting with the entire red-channel LUT, then the green-channel LUT, then the blue-channel LUT. Each packet is structured as follows:
|2||LUT entry #0, low byte|
|3||LUT entry #0, high byte|
|4||LUT entry #1, low byte|
|5||LUT entry #1, high byte|
|62||LUT entry #30, low byte|
|63||LUT entry #30, high byte|
A type 2 packet sets optional device-wide configuration settings:
|0||7 … 0||Control byte|
|1||7 … 5||(reserved)|
|1||4||0 = Normal mode, 1 = Reserved operation mode|
|1||3||Manual LED control bit|
|1||2||0 = LED shows USB activity, 1 = LED under manual control|
|1||1||Disable keyframe interpolation|
|2 … 63||7 … 0||(reserved)|
The "reserved operation mode" may be used by unofficial Fadecandy firmware that includes experimental or application-specific effects. This reserved bit is guaranteed not to be used during normal operation by future versions of fcserver.
In addition to the OUT endpoint, the device also supports vendor-specific control requests:
|0xC0||0x01||0||0||4||Read rendered frame counter (32-bit, little endian)|
|0xC0||0x01||0||1||4||Read received keyframe counter (32-bit, little endian)|
|0xC0||0x7E||x||4||x||Read Microsoft WCID descriptor|
|0xC0||0x7E||x||5||x||Read Microsoft Extended Properties descriptor|
For reference, this is sample output from the Mac OS X USB Prober diagnostics tool:
Full Speed device @ 15 (0x14200000): Composite device: "Fadecandy" Port Information: 0x101a Not Captive Attached to Root Hub External Device Connected Enabled Connected to External Port Number Of Endpoints (includes EP0): Total Endpoints for Configuration 1 (current): 2 Device Descriptor Descriptor Version Number: 0x0200 Device Class: 0 (Composite) Device Subclass: 0 Device Protocol: 0 Device MaxPacketSize: 64 Device VendorID/ProductID: 0x1D50/0x607A (unknown vendor) Device Version Number: 0x0108 Number of Configurations: 1 Manufacturer String: 1 "scanlime" Product String: 2 "Fadecandy" Serial Number String: 3 "ENICCULVLDQJQDWD" Configuration Descriptor (current config) Length (and contents): 43 Raw Descriptor (hex) 0000: 09 02 2B 00 02 01 00 80 32 09 04 00 00 01 FF 00 Raw Descriptor (hex) 0010: 00 00 07 05 01 02 40 00 00 09 04 01 00 00 FE 01 Raw Descriptor (hex) 0020: 01 04 09 21 0D 10 27 00 04 01 01 Number of Interfaces: 2 Configuration Value: 1 Attributes: 0x80 (bus-powered) MaxPower: 100 mA Interface #0 - Vendor-specific Alternate Setting 0 Number of Endpoints 1 Interface Class: 255 (Vendor-specific) Interface Subclass; 0 (Vendor-specific) Interface Protocol: 0 Endpoint 0x01 - Bulk Output Address: 0x01 (OUT) Attributes: 0x02 (Bulk) Max Packet Size: 64 Polling Interval: 0 ms Interface #1 - Application Specific/Device Firmware Update "Fadecandy Bootloader" Alternate Setting 0 Number of Endpoints 0 Interface Class: 254 (Application Specific) Interface Subclass; 1 (Device Firmware Update) Interface Protocol: 1 DFU Functional Descriptor bmAttributes: 0x0d (Download, No Upload, Manifestation Tolerant, Reserved bits: 0x08) wDetachTimeout: 10000 ms wTransferSize: 1024 bytes