Library for the WS2812 LED Driver. Uses bit banging and nops for precise timing. Number of nops executed are configurable at run time.

Dependents:   MIP

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;
     }
 }