for SoundWS2812B-FFT
Fork of PixelArray by
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Sun Jul 17 2022 22:46:21 by 1.7.2