Library for the WS2812 LED Driver. Uses bit banging and nops for precise timing. Number of nops executed are configurable at run time.
Diff: WS2812.cpp
- Revision:
- 1:aadbf08c62a2
- Parent:
- 0:0b79cafcb387
- Child:
- 3:d09a1ee509cc
diff -r 0b79cafcb387 -r aadbf08c62a2 WS2812.cpp --- a/WS2812.cpp Thu Feb 12 19:17:10 2015 +0000 +++ b/WS2812.cpp Thu Feb 12 20:20:10 2015 +0000 @@ -1,15 +1,15 @@ #include "WS2812.h" -WS2812::WS2812(PinName d, int size) : __gpo(d) +WS2812::WS2812(PinName pin, int size, int zeroHigh, int zeroLow, int oneHigh, int oneLow) : __gpo(pin) { __size = size; __transmitBuf = new bool[size * FRAME_SIZE]; - __use_II = 0; // 0=off,1=use global,2=per pixel + __use_II = OFF; __II = 0xFF; // set global intensity to full - __outPin = d; + __outPin = pin; // Default values designed for K64f. Assumes GPIO toggle takes ~0.4us - setDelays(0, 5, 5, 0); + setDelays(zeroHigh, zeroLow, oneHigh, oneLow); } @@ -47,10 +47,10 @@ agrb[2] = color & 0x000000FF; agrb[3] = (color & 0xFF000000) >> 24; - // set and intensity scaling factor (global, per pixel, none) - if (__use_II == 1) { + // set the intensity scaling factor (global, per pixel, none) + if (__use_II == GLOBAL) { sf = __II; - } else if (__use_II == 2) { + } else if (__use_II == PER_PIXEL) { sf = agrb[3]; } else { sf = 0xFF; @@ -80,8 +80,13 @@ void WS2812::write_offsets (int buf[],int r_offset, int g_offset, int b_offset) { int i, j; + // Load the transmit buffer __loadBuf(buf, r_offset, g_offset, b_offset); + // Entering timing critical section, so disabling interrupts + __disable_irq(); + + // Begin bit-banging for (i = 0; i < FRAME_SIZE * __size; i++) { j = 0; if (__transmitBuf[i]){ @@ -104,15 +109,18 @@ } } } + + // Exiting timing critical section, so enabling interrutps + __enable_irq(); } -void WS2812::useII(int d) +void WS2812::useII(BrightnessControl bc) { - if (d > 0) { - __use_II = d; + if (bc > OFF) { + __use_II = bc; } else { - __use_II = 0; + __use_II = OFF; } }