driver for WS2812B LED, modified for better compatibility with LPC812 and LPC1549
Fork of wsDrive by
wsDrive.cpp@6:270a9728ee29, 2016-12-10 (annotated)
- Committer:
- JojoS
- Date:
- Sat Dec 10 14:30:38 2016 +0000
- Revision:
- 6:270a9728ee29
- Parent:
- 4:c965e448d96b
support for STM32F4
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
AndyA | 0:b3665f91bedc | 1 | #include "wsDrive.h" |
AndyA | 0:b3665f91bedc | 2 | |
AndyA | 0:b3665f91bedc | 3 | wsDrive::wsDrive(PinName mosi, PinName miso, PinName clk) : BurstSPI(mosi,miso,clk) |
AndyA | 0:b3665f91bedc | 4 | { |
JojoS | 6:270a9728ee29 | 5 | #if defined(TARGET_STM32F4) |
JojoS | 6:270a9728ee29 | 6 | frequency(4000000); |
JojoS | 6:270a9728ee29 | 7 | format(4*4, 1); // one WS bit -> four SPI bits |
JojoS | 6:270a9728ee29 | 8 | #else |
AndyA | 0:b3665f91bedc | 9 | frequency(2400000); |
JojoS | 6:270a9728ee29 | 10 | format(3*4, 1); // one WS bit -> three SPI bits |
JojoS | 6:270a9728ee29 | 11 | #endif |
JojoS | 4:c965e448d96b | 12 | |
AndyA | 0:b3665f91bedc | 13 | pixArray = NULL; |
AndyA | 3:3c48065d20ff | 14 | pixArray16 = NULL; |
AndyA | 0:b3665f91bedc | 15 | pixelLen = 0; |
AndyA | 0:b3665f91bedc | 16 | } |
AndyA | 0:b3665f91bedc | 17 | |
AndyA | 0:b3665f91bedc | 18 | void wsDrive::setData(pixelInfo *dataStart, uint16_t dataLen) |
AndyA | 0:b3665f91bedc | 19 | { |
AndyA | 0:b3665f91bedc | 20 | pixArray = dataStart; |
AndyA | 0:b3665f91bedc | 21 | pixelLen = dataLen; |
AndyA | 3:3c48065d20ff | 22 | pixArray16 = NULL; |
AndyA | 3:3c48065d20ff | 23 | } |
AndyA | 3:3c48065d20ff | 24 | |
AndyA | 3:3c48065d20ff | 25 | void wsDrive::setData(pixelInfo16 *dataStart, uint16_t dataLen) |
AndyA | 3:3c48065d20ff | 26 | { |
AndyA | 3:3c48065d20ff | 27 | pixArray16 = dataStart; |
AndyA | 3:3c48065d20ff | 28 | pixelLen = dataLen; |
AndyA | 3:3c48065d20ff | 29 | pixArray = NULL; |
AndyA | 0:b3665f91bedc | 30 | } |
AndyA | 0:b3665f91bedc | 31 | |
AndyA | 0:b3665f91bedc | 32 | void wsDrive::sendData() |
AndyA | 0:b3665f91bedc | 33 | { |
AndyA | 0:b3665f91bedc | 34 | uint16_t pixIndex = 0; |
AndyA | 3:3c48065d20ff | 35 | if (pixArray) { |
AndyA | 3:3c48065d20ff | 36 | while (pixIndex < pixelLen) { |
AndyA | 3:3c48065d20ff | 37 | sendPixel(pixArray + pixIndex++); |
AndyA | 3:3c48065d20ff | 38 | } |
AndyA | 3:3c48065d20ff | 39 | } else if (pixArray16) { |
AndyA | 3:3c48065d20ff | 40 | while (pixIndex < pixelLen) { |
AndyA | 3:3c48065d20ff | 41 | sendPixel(pixArray16 + pixIndex++); |
AndyA | 3:3c48065d20ff | 42 | } |
AndyA | 3:3c48065d20ff | 43 | } |
AndyA | 0:b3665f91bedc | 44 | } |
AndyA | 0:b3665f91bedc | 45 | |
AndyA | 0:b3665f91bedc | 46 | // each bytes sent as two 12 bit messages (3 bits of data per LED bit). |
AndyA | 0:b3665f91bedc | 47 | void wsDrive::sendByte(unsigned char value) |
AndyA | 0:b3665f91bedc | 48 | { |
JojoS | 6:270a9728ee29 | 49 | uint16_t dataToSend = 0; |
JojoS | 6:270a9728ee29 | 50 | uint8_t mask = 0x80; |
AndyA | 3:3c48065d20ff | 51 | |
JojoS | 6:270a9728ee29 | 52 | #if defined(TARGET_STM32F4) |
JojoS | 6:270a9728ee29 | 53 | while (mask) { |
JojoS | 6:270a9728ee29 | 54 | dataToSend += (value & mask)?0x0C:0x08; // 1000 for a 0 or 1100 for a 1 |
JojoS | 6:270a9728ee29 | 55 | if (mask & 0x11) { // trans |
JojoS | 6:270a9728ee29 | 56 | fastWrite(dataToSend); |
JojoS | 6:270a9728ee29 | 57 | dataToSend = 0; |
JojoS | 6:270a9728ee29 | 58 | } |
JojoS | 6:270a9728ee29 | 59 | dataToSend = dataToSend << 4; |
JojoS | 6:270a9728ee29 | 60 | mask = mask >> 1; |
JojoS | 6:270a9728ee29 | 61 | } |
JojoS | 6:270a9728ee29 | 62 | #else |
AndyA | 0:b3665f91bedc | 63 | while (mask) { |
AndyA | 0:b3665f91bedc | 64 | dataToSend += (value & mask)?0x06:0x4; // 100 for a 0 or 110 for a 1 |
AndyA | 0:b3665f91bedc | 65 | if (mask & 0x11) { // trans |
AndyA | 3:3c48065d20ff | 66 | fastWrite(dataToSend); |
AndyA | 3:3c48065d20ff | 67 | dataToSend = 0; |
AndyA | 0:b3665f91bedc | 68 | } |
AndyA | 0:b3665f91bedc | 69 | dataToSend = dataToSend << 3; |
AndyA | 0:b3665f91bedc | 70 | mask = mask >> 1; |
AndyA | 0:b3665f91bedc | 71 | } |
JojoS | 6:270a9728ee29 | 72 | #endif |
AndyA | 0:b3665f91bedc | 73 | } |
AndyA | 0:b3665f91bedc | 74 | |
AndyA | 0:b3665f91bedc | 75 | void wsDrive::sendPixel(pixelInfo *pixToSend) |
AndyA | 0:b3665f91bedc | 76 | { |
AndyA | 0:b3665f91bedc | 77 | sendByte(pixToSend->G); |
AndyA | 0:b3665f91bedc | 78 | sendByte(pixToSend->R); |
AndyA | 0:b3665f91bedc | 79 | sendByte(pixToSend->B); |
AndyA | 0:b3665f91bedc | 80 | } |
AndyA | 0:b3665f91bedc | 81 | |
AndyA | 3:3c48065d20ff | 82 | void wsDrive::sendPixel(pixelInfo16 *pixToSend) |
AndyA | 3:3c48065d20ff | 83 | { |
AndyA | 3:3c48065d20ff | 84 | if (pixToSend->G > 0xff) |
AndyA | 3:3c48065d20ff | 85 | sendByte(0xff); |
AndyA | 3:3c48065d20ff | 86 | else if (pixToSend->G < 0) |
AndyA | 3:3c48065d20ff | 87 | sendByte(0xff); |
AndyA | 3:3c48065d20ff | 88 | else |
AndyA | 3:3c48065d20ff | 89 | sendByte((unsigned char)pixToSend->G); |
AndyA | 3:3c48065d20ff | 90 | |
AndyA | 3:3c48065d20ff | 91 | if (pixToSend->R > 0xff) |
AndyA | 3:3c48065d20ff | 92 | sendByte(0xff); |
AndyA | 3:3c48065d20ff | 93 | else if (pixToSend->R < 0) |
AndyA | 3:3c48065d20ff | 94 | sendByte(0xff); |
AndyA | 3:3c48065d20ff | 95 | else |
AndyA | 3:3c48065d20ff | 96 | sendByte((unsigned char)pixToSend->R); |
AndyA | 3:3c48065d20ff | 97 | |
AndyA | 3:3c48065d20ff | 98 | if (pixToSend->B > 0xff) |
AndyA | 3:3c48065d20ff | 99 | sendByte(0xff); |
AndyA | 3:3c48065d20ff | 100 | else if (pixToSend->B < 0) |
AndyA | 3:3c48065d20ff | 101 | sendByte(0xff); |
AndyA | 3:3c48065d20ff | 102 | else |
AndyA | 3:3c48065d20ff | 103 | sendByte((unsigned char)pixToSend->B); |
AndyA | 3:3c48065d20ff | 104 | |
AndyA | 3:3c48065d20ff | 105 | } |