Only update of BurstSPI-Library

Dependencies:   BurstSPI

Dependents:   WordClock TI_NEOPIXEL_SPI

Fork of PixelArray by Jacob Bramley

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers neopixel.cpp Source File

neopixel.cpp

00001 #include <stdint.h>
00002 #include "mbed.h"
00003 #include "neopixel.h"
00004 
00005 namespace neopixel
00006 {
00007 
00008 PixelArray::PixelArray(PinName out, ByteOrder byte_order, Protocol protocol)
00009     : spi_(out, NC, NC), byte_order_(byte_order), protocol_(protocol)
00010 {
00011     if (protocol_ == PROTOCOL_800KHZ) {
00012         // 800kHz bit encodings:
00013         //  '0': ----________
00014         //  '1': --------____
00015         // The period is 1.25us, giving a basic frequency of 800kHz.
00016         // Getting the mark-space ratio right is trickier, though. There are a number
00017         // of different timings, and the correct (documented) values depend on the
00018         // controller chip.
00019         //
00020         // The _real_ timing restrictions are much simpler though, and someone has
00021         // published a lovely analysis here:
00022         //   http://cpldcpu.wordpress.com/2014/01/14/light_ws2812-library-v2-0-part-i-understanding-the-ws2812/
00023         //
00024         // In summary:
00025         // - The period should be at least 1.25us.
00026         // - The '0' high time can be anywhere from 0.0625us to 0.5us.
00027         // - The '1' high time should be longer than 0.625us.
00028         //
00029         // These constraints are easy to meet by splitting each bit into three and packing them into SPI packets.
00030         //  '0': 100             mark: 0.42us, space: 0.83us
00031         //  '1': 110             mark: 0.83us, space: 0.42us
00032         spi_.frequency(2400000);  // 800kHz * 3
00033         spi_.format(12);          // Send four NeoPixel bits in each packet.
00034     } else {
00035         // 400kHz bit encodings:
00036         //  '0': --________
00037         //  '1': -----_____
00038         //
00039         // Timing requirements are derived from this document:
00040         //   http://www.adafruit.com/datasheets/WS2811.pdf
00041         //
00042         // The period is 2.5us, and we use a 10-bit packet for this encoding:
00043         //  '0': 1100000000      mark: 0.5us, space: 2us
00044         //  '1': 1111100000      mark: 1.25us, space: 1.25us    
00045         spi_.frequency(4000000);  // 400kHz * 10
00046         spi_.format(10);          // Send one NeoPixel bit in each packet.
00047     }
00048 }
00049 
00050 static void SendFourBits(BurstSPI& spi, uint32_t bits)
00051 {
00052     // Encode '0' bits as 100 and '1' bits as 110.
00053     // We have this bit pattern: 00000000abcd
00054     // We want this bit pattern: 1a01b01c01d0
00055     uint32_t ac = (bits * 0x088) &        // 0abcdabcd000
00056                   0x410; // 0a00000c0000
00057 
00058     uint32_t bd = (bits * 0x022) &        // 000abcdabcd0
00059                   0x082; // 0000b00000d0
00060 
00061     static uint32_t const base = 04444;   // 100100100100
00062 
00063     spi.fastWrite(base | ac | bd);        // 1a01b01c01d0
00064 }
00065 
00066 static void SendEightBits(BurstSPI& spi, uint8_t bits)
00067 {
00068     int zero = 0x300;  // Encode zero as 0b1100000000
00069     int one = 0x3e0;   // Encode one as 0b1111100000
00070     for (int i = 128; i >= 1; i >>= 1) {
00071         spi.fastWrite((bits & i) ? one : zero);
00072     }
00073 }
00074 
00075 void PixelArray::send_pixel(Pixel& pixel)
00076 {
00077     // Pixels are sent as follows:
00078     // - The first transmitted pixel is the pixel closest to the transmitter.
00079     // - The most significant bit is always sent first.
00080     //
00081     // g7,g6,g5,g4,g3,g2,g1,g0,r7,r6,r5,r4,r3,r2,r1,r0,b7,b6,b5,b4,b3,b2,b1,b0
00082     // \_____________________________________________________________________/
00083     //                           |      _________________...
00084     //                           |     /   __________________...
00085     //                           |    /   /   ___________________...
00086     //                           |   /   /   /
00087     //                          GRB,GRB,GRB,GRB,...
00088     //
00089     // For BYTE_ORDER_RGB, the order of the first two bytes are reversed.
00090 
00091     uint8_t byte0 = (byte_order_ == BYTE_ORDER_RGB) ? pixel.red : pixel.green;
00092     uint8_t byte1 = (byte_order_ == BYTE_ORDER_RGB) ? pixel.green : pixel.red;
00093 
00094     if (protocol_ == PROTOCOL_800KHZ) {
00095         SendFourBits(spi_, (byte0 >> 4) & 0xf);
00096         SendFourBits(spi_, (byte0 >> 0) & 0xf);
00097         SendFourBits(spi_, (byte1 >> 4) & 0xf);
00098         SendFourBits(spi_, (byte1 >> 0) & 0xf);
00099         SendFourBits(spi_, (pixel.blue >> 4) & 0xf);
00100         SendFourBits(spi_, (pixel.blue >> 0) & 0xf);
00101     } else {
00102         SendEightBits(spi_, byte0);
00103         SendEightBits(spi_, byte1);
00104         SendEightBits(spi_, pixel.blue);
00105     }
00106 }
00107 
00108 void PixelArray::update(Pixel buffer[], uint32_t length)
00109 {
00110     for (size_t i = 0; i < length; i++) {
00111         send_pixel(buffer[i]);
00112     }
00113 
00114     wait_us(latch_time_us_);
00115 }
00116 
00117 void PixelArray::update(PixelGenerator generator, uint32_t length, uintptr_t extra)
00118 {
00119     for (size_t i = 0; i < length; i++) {
00120         Pixel out;
00121         generator(&out, i, extra);
00122         send_pixel(out);
00123     }
00124 
00125     wait_us(latch_time_us_);
00126 }
00127 
00128 }