Driver for WS2812

Dependents:   ChrisRGB-Ring

Committer:
chris
Date:
Mon Aug 18 13:25:57 2014 +0000
Revision:
5:a07522fe36d4
Parent:
4:b230e85fc5e7
Added the ability to write with offsets

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chris 0:be22a9d4df5f 1 #include "WS2812.h"
chris 0:be22a9d4df5f 2
chris 0:be22a9d4df5f 3 WS2812::WS2812(PinName d, int size) : __spi(d, NC, NC)
chris 0:be22a9d4df5f 4 {
chris 0:be22a9d4df5f 5 __size = size;
chris 0:be22a9d4df5f 6 __spi.format(SPIBPF,0);
chris 0:be22a9d4df5f 7 __spi.frequency(SPICLK);
chris 0:be22a9d4df5f 8 __use_II = 0; // 0=off,1=use global,2=per pixel
chris 0:be22a9d4df5f 9 __II = 0xFF; // set global intensity to full
chris 0:be22a9d4df5f 10 }
chris 0:be22a9d4df5f 11
chris 0:be22a9d4df5f 12
chris 0:be22a9d4df5f 13 WS2812::~WS2812()
chris 0:be22a9d4df5f 14 {
chris 0:be22a9d4df5f 15
chris 0:be22a9d4df5f 16 }
chris 0:be22a9d4df5f 17
chris 4:b230e85fc5e7 18
chris 4:b230e85fc5e7 19 void WS2812::write(int buf[])
chris 0:be22a9d4df5f 20 {
chris 0:be22a9d4df5f 21 // for each of the data points in the buffer
chris 0:be22a9d4df5f 22 for (int i = 0; i < __size ; i++) {
chris 4:b230e85fc5e7 23 __write(buf[i]);
chris 0:be22a9d4df5f 24 }
chris 0:be22a9d4df5f 25 }
chris 0:be22a9d4df5f 26
chris 0:be22a9d4df5f 27
chris 5:a07522fe36d4 28 void WS2812::write_offsets(int buf[], int r_offset, int g_offset, int b_offset)
chris 5:a07522fe36d4 29 {
chris 5:a07522fe36d4 30 // for each of the data points in the buffer
chris 5:a07522fe36d4 31 for (int i = 0; i < __size ; i++) {
chris 5:a07522fe36d4 32
chris 5:a07522fe36d4 33 unsigned int argb = 0x0;
chris 5:a07522fe36d4 34 // index and extract colour fields from IIRRGGBB buf[]
chris 5:a07522fe36d4 35 // 0 = blue, 1 = green, 2 = red, 3 = brightness
chris 5:a07522fe36d4 36 argb |= (buf[(i+b_offset)%__size] & 0x000000FF);
chris 5:a07522fe36d4 37 argb |= ((buf[(i+g_offset)%__size] & 0x0000FF00));
chris 5:a07522fe36d4 38 argb |= ((buf[(i+r_offset)%__size] & 0x00FF0000));
chris 5:a07522fe36d4 39 argb |= (buf[i] & 0xFF000000);
chris 5:a07522fe36d4 40 __write(argb);
chris 5:a07522fe36d4 41 }
chris 5:a07522fe36d4 42 }
chris 5:a07522fe36d4 43
chris 5:a07522fe36d4 44
chris 5:a07522fe36d4 45
chris 5:a07522fe36d4 46
chris 0:be22a9d4df5f 47 void WS2812::setAll(int colour)
chris 0:be22a9d4df5f 48 {
chris 0:be22a9d4df5f 49 // for each of the data points in the buffer
chris 0:be22a9d4df5f 50 for (int i = 0; i < __size ; i++) {
chris 0:be22a9d4df5f 51 __write(colour);
chris 0:be22a9d4df5f 52 }
chris 0:be22a9d4df5f 53 }
chris 0:be22a9d4df5f 54
chris 0:be22a9d4df5f 55
chris 0:be22a9d4df5f 56 void WS2812::useII(int d)
chris 0:be22a9d4df5f 57 {
chris 0:be22a9d4df5f 58 if (d > 0) {
chris 0:be22a9d4df5f 59 __use_II = d;
chris 0:be22a9d4df5f 60 } else {
chris 0:be22a9d4df5f 61 __use_II = 0;
chris 0:be22a9d4df5f 62 }
chris 0:be22a9d4df5f 63 }
chris 0:be22a9d4df5f 64
chris 0:be22a9d4df5f 65
chris 0:be22a9d4df5f 66 void WS2812::setII(unsigned char II)
chris 0:be22a9d4df5f 67 {
chris 0:be22a9d4df5f 68 __II = II;
chris 0:be22a9d4df5f 69 }
chris 0:be22a9d4df5f 70
chris 0:be22a9d4df5f 71
chris 0:be22a9d4df5f 72
chris 0:be22a9d4df5f 73 void WS2812::__write(int color)
chris 0:be22a9d4df5f 74 {
chris 0:be22a9d4df5f 75
chris 0:be22a9d4df5f 76 // Outut format : GGRRBB
chris 0:be22a9d4df5f 77 // Inout format : IIRRGGBB
chris 0:be22a9d4df5f 78 unsigned char agrb[4] = {0x0, 0x0, 0x0, 0x0};
chris 0:be22a9d4df5f 79
chris 4:b230e85fc5e7 80 unsigned char sf; // scaling factor for II
chris 4:b230e85fc5e7 81
chris 0:be22a9d4df5f 82 // extract colour fields from incoming
chris 0:be22a9d4df5f 83 // 0 = blue, 1 = red, 2 = green, 3 = brightness
chris 0:be22a9d4df5f 84 agrb[0] = color & 0x000000FF;
chris 0:be22a9d4df5f 85 agrb[1] = (color & 0x00FF0000) >> 16;
chris 0:be22a9d4df5f 86 agrb[2] = (color & 0x0000FF00) >> 8;
chris 0:be22a9d4df5f 87 agrb[3] = (color & 0xFF000000) >> 24;
chris 0:be22a9d4df5f 88
chris 4:b230e85fc5e7 89 // set and intensity scaling factor (global, per pixel, none)
chris 0:be22a9d4df5f 90 if (__use_II == 1) {
chris 4:b230e85fc5e7 91 sf = __II;
chris 0:be22a9d4df5f 92 } else if (__use_II == 2) {
chris 4:b230e85fc5e7 93 sf = agrb[3];
chris 4:b230e85fc5e7 94 } else {
chris 4:b230e85fc5e7 95 sf = 0xFF;
chris 0:be22a9d4df5f 96 }
chris 0:be22a9d4df5f 97
chris 4:b230e85fc5e7 98 // Apply the scaling factor to each othe colour components
chris 4:b230e85fc5e7 99 for (int clr = 2; clr >= 0; clr--) {
chris 4:b230e85fc5e7 100 agrb[clr] = ((agrb[clr] * sf) >> 8);
chris 4:b230e85fc5e7 101 }
chris 0:be22a9d4df5f 102
chris 4:b230e85fc5e7 103 // For each colour component G,R,B
chris 4:b230e85fc5e7 104 // shift out the data 7..0, writing a SPI frame per bit
chris 0:be22a9d4df5f 105 // green=2,red=1,blue=0,
chris 0:be22a9d4df5f 106 for (int clr = 2; clr >= 0; clr--) {
chris 0:be22a9d4df5f 107 for (int bit = 7 ; bit >= 0 ; bit--) {
chris 0:be22a9d4df5f 108 if (agrb[clr] & (0x1 << bit)) {
chris 0:be22a9d4df5f 109 __spi.write(WS1);
chris 0:be22a9d4df5f 110 } else {
chris 0:be22a9d4df5f 111 __spi.write(WS0);
chris 0:be22a9d4df5f 112 }
chris 0:be22a9d4df5f 113 }
chris 0:be22a9d4df5f 114 }
chris 0:be22a9d4df5f 115 }
chris 0:be22a9d4df5f 116
chris 0:be22a9d4df5f 117
chris 0:be22a9d4df5f 118
chris 0:be22a9d4df5f 119
chris 0:be22a9d4df5f 120
chris 0:be22a9d4df5f 121
chris 0:be22a9d4df5f 122
chris 0:be22a9d4df5f 123