driver for WS2812B LED, modified for better compatibility with LPC812 and LPC1549

Dependencies:   BurstSPI

Dependents:   RGB-balls cylon

Fork of wsDrive by Andy A

wsDrive.cpp

Committer:
JojoS
Date:
2016-12-10
Revision:
6:270a9728ee29
Parent:
4:c965e448d96b

File content as of revision 6:270a9728ee29:

#include "wsDrive.h"

wsDrive::wsDrive(PinName mosi, PinName miso, PinName clk) : BurstSPI(mosi,miso,clk)
{
#if defined(TARGET_STM32F4)    
    frequency(4000000);
    format(4*4, 1);          // one WS bit -> four SPI bits
#else
    frequency(2400000);
    format(3*4, 1);          // one WS bit -> three SPI bits
#endif

    pixArray = NULL;
    pixArray16 = NULL;
    pixelLen = 0;
}

void wsDrive::setData(pixelInfo *dataStart, uint16_t dataLen)
{
    pixArray = dataStart;
    pixelLen = dataLen;
    pixArray16 = NULL;
}

void wsDrive::setData(pixelInfo16 *dataStart, uint16_t dataLen)
{
    pixArray16 = dataStart;
    pixelLen = dataLen;
    pixArray = NULL;
}

void wsDrive::sendData()
{
    uint16_t pixIndex = 0;
    if (pixArray) {
        while (pixIndex < pixelLen) {
            sendPixel(pixArray + pixIndex++);
        }
    } else if (pixArray16) {
        while (pixIndex < pixelLen) {
            sendPixel(pixArray16 + pixIndex++);
        }
    }
}

// each bytes sent as two 12 bit messages (3 bits of data per LED bit).
void wsDrive::sendByte(unsigned char value)
{
    uint16_t dataToSend = 0;
    uint8_t mask = 0x80;

#if defined(TARGET_STM32F4)    
    while (mask) {
        dataToSend += (value & mask)?0x0C:0x08; // 1000 for a 0 or  1100 for a 1
        if (mask & 0x11) {                     // trans
            fastWrite(dataToSend);
            dataToSend = 0;
        }
        dataToSend = dataToSend << 4;
        mask = mask >> 1;
    }
#else
    while (mask) {
        dataToSend += (value & mask)?0x06:0x4; // 100 for a 0 or  110 for a 1
        if (mask & 0x11) {                     // trans
            fastWrite(dataToSend);
            dataToSend = 0;
        }
        dataToSend = dataToSend << 3;
        mask = mask >> 1;
    }
#endif
}

void wsDrive::sendPixel(pixelInfo *pixToSend)
{
    sendByte(pixToSend->G);
    sendByte(pixToSend->R);
    sendByte(pixToSend->B);
}

void wsDrive::sendPixel(pixelInfo16 *pixToSend)
{
    if (pixToSend->G > 0xff)
        sendByte(0xff);
    else if (pixToSend->G < 0)
        sendByte(0xff);
    else
        sendByte((unsigned char)pixToSend->G);

    if (pixToSend->R > 0xff)
        sendByte(0xff);
    else if (pixToSend->R < 0)
        sendByte(0xff);
    else
        sendByte((unsigned char)pixToSend->R);

    if (pixToSend->B > 0xff)
        sendByte(0xff);
    else if (pixToSend->B < 0)
        sendByte(0xff);
    else
        sendByte((unsigned char)pixToSend->B);

}