Driver for WS2812

Dependents:   ChrisRGB-Ring

WS2812.cpp

Committer:
chris
Date:
2014-08-02
Revision:
1:c278c3d136bb
Parent:
0:be22a9d4df5f
Child:
3:d56ffdf7beeb

File content as of revision 1:c278c3d136bb:

#include "WS2812.h"

WS2812::WS2812(PinName d, int size) : __spi(d, NC, NC)
{
    __size = size;
    __spi.format(SPIBPF,0);
    __spi.frequency(SPICLK);
    __use_II = 0; // 0=off,1=use global,2=per pixel
    __II = 0xFF; // set global intensity to full
}



WS2812::~WS2812()
{

}

void WS2812::update(int buff[])
{
    // for each of the data points in the buffer
    for (int i = 0; i < __size ; i++) {
        __write(buff[i]);
    }
}


void WS2812::setAll(int colour)
{
    // for each of the data points in the buffer
    for (int i = 0; i < __size ; i++) {
        __write(colour);
    }
}


void WS2812::useII(int d)
{
    if (d > 0) {
        __use_II = d;
    } else {
        __use_II = 0;
    }
}


void WS2812::setII(unsigned char II)
{
    __II = II;
}



void WS2812::__write(int color)
{

    // Outut format : GGRRBB
    // Inout format : IIRRGGBB
    unsigned char agrb[4] = {0x0, 0x0, 0x0, 0x0};

    // extract colour fields from incoming
    // 0 = blue, 1 = red, 2 = green, 3 = brightness
    agrb[0] = color & 0x000000FF;
    agrb[1] = (color & 0x00FF0000) >> 16;
    agrb[2] = (color & 0x0000FF00) >> 8;
    agrb[3] = (color & 0xFF000000) >> 24;

    // apply intensity
    // 1 use global, 2=per pixel
    if (__use_II == 1) {
        for (int clr = 2; clr >= 0; clr--) {
            agrb[clr] = ((agrb[clr] * __II) >> 8);
        }
    } else if (__use_II == 2) {
        for (int clr = 2; clr >= 0; clr--) {
            agrb[clr] = ((agrb[clr] * agrb[3]) >> 8);
        }
    }


    // green=2,red=1,blue=0,
    for (int clr = 2; clr >= 0; clr--) {
        for (int bit = 7 ; bit >= 0 ; bit--) {
            if (agrb[clr] & (0x1 << bit)) {
                __spi.write(WS1);
            } else {
                __spi.write(WS0);
            }
        }
    }
}