Driver for WS2812

Dependents:   ChrisRGB-Ring

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WS2812.cpp Source File

WS2812.cpp

00001 #include "WS2812.h"
00002 
00003 WS2812::WS2812(PinName d, int size) : __spi(d, NC, NC)
00004 {
00005     __size = size;
00006     __spi.format(SPIBPF,0);
00007     __spi.frequency(SPICLK);
00008     __use_II = 0; // 0=off,1=use global,2=per pixel
00009     __II = 0xFF; // set global intensity to full
00010 }
00011 
00012 
00013 WS2812::~WS2812 ()
00014 {
00015 
00016 }
00017 
00018 
00019 void WS2812::write(int buf[])
00020 {
00021     // for each of the data points in the buffer
00022     for (int i = 0; i < __size ; i++) {
00023         __write(buf[i]);
00024     }
00025 }
00026 
00027 
00028 void WS2812::write_offsets(int buf[], int r_offset, int g_offset, int b_offset)
00029 {
00030     // for each of the data points in the buffer
00031     for (int i = 0; i < __size ; i++) {
00032 
00033         unsigned int argb = 0x0;
00034         // index and extract colour fields from IIRRGGBB buf[]
00035         // 0 = blue, 1 = green, 2 = red, 3 = brightness
00036         argb |=  (buf[(i+b_offset)%__size] & 0x000000FF);
00037         argb |= ((buf[(i+g_offset)%__size] & 0x0000FF00));
00038         argb |= ((buf[(i+r_offset)%__size] & 0x00FF0000));
00039         argb |= (buf[i] & 0xFF000000);
00040         __write(argb);
00041     }
00042 }
00043 
00044 
00045 
00046 
00047 void WS2812::setAll(int colour)
00048 {
00049     // for each of the data points in the buffer
00050     for (int i = 0; i < __size ; i++) {
00051         __write(colour);
00052     }
00053 }
00054 
00055 
00056 void WS2812::useII(int d)
00057 {
00058     if (d > 0) {
00059         __use_II = d;
00060     } else {
00061         __use_II = 0;
00062     }
00063 }
00064 
00065 
00066 void WS2812::setII(unsigned char II)
00067 {
00068     __II = II;
00069 }
00070 
00071 
00072 
00073 void WS2812::__write(int color)
00074 {
00075 
00076     // Outut format : GGRRBB
00077     // Inout format : IIRRGGBB
00078     unsigned char agrb[4] = {0x0, 0x0, 0x0, 0x0};
00079 
00080     unsigned char sf; // scaling factor for  II
00081 
00082     // extract colour fields from incoming
00083     // 0 = blue, 1 = red, 2 = green, 3 = brightness
00084     agrb[0] = color & 0x000000FF;
00085     agrb[1] = (color & 0x00FF0000) >> 16;
00086     agrb[2] = (color & 0x0000FF00) >> 8;
00087     agrb[3] = (color & 0xFF000000) >> 24;
00088 
00089     // set and intensity scaling factor (global, per pixel, none)
00090     if (__use_II == 1) {
00091         sf = __II;
00092     } else if (__use_II == 2) {
00093         sf = agrb[3];
00094     } else {
00095         sf = 0xFF;
00096     }
00097 
00098     // Apply the scaling factor to each othe colour components
00099     for (int clr = 2; clr >= 0; clr--) {
00100         agrb[clr] = ((agrb[clr] * sf) >> 8);
00101     }
00102 
00103     // For each colour component G,R,B
00104     // shift out the data 7..0, writing a SPI frame per bit
00105     // green=2,red=1,blue=0,
00106     for (int clr = 2; clr >= 0; clr--) {
00107         for (int bit = 7 ; bit >= 0 ; bit--) {
00108             if (agrb[clr] & (0x1 << bit)) {
00109                 __spi.write(WS1);
00110             } else {
00111                 __spi.write(WS0);
00112             }
00113         }
00114     }
00115 }
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123