DMA-enabled high data rate driver for Heroic Robotics LED strips.

Dependents:   FastPixelDemo

Files at this revision

API Documentation at this revision

Comitter:
heroic
Date:
Sat May 31 18:41:56 2014 +0000
Parent:
9:9038105d14bc
Commit message:
Initial commit of FastPixelLPD8806 open source driver.

Changed in this revision

FastPixelLPD8806.cpp Show annotated file Show diff for this revision Revisions of this file
FastPixelLPD8806.h Show annotated file Show diff for this revision Revisions of this file
LPD8806_fast.cpp Show diff for this revision Revisions of this file
LPD8806_fast.h Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FastPixelLPD8806.cpp	Sat May 31 18:41:56 2014 +0000
@@ -0,0 +1,210 @@
+/***************************************************************************/
+// DMA-enabled high data rate driver for Heroic Robotics FastPixel strips.
+// Written by Jas Strong <jasmine@heroicrobotics.com>
+// Copyright (c) 2013-2014 Heroic Robotics, Inc.
+//
+// FastPixel is a family of high performance LED strips available from
+// Heroic Robotics, Inc.  http://heroicrobotics.com/ - check them out!
+//
+// These strips are capable of supporting 18 Mbit/sec when run on PixelPusher
+// hardware;  your performance on mbed is likely to be somewhat lower due to
+// the lack of high performance driver chips on the SPI lines.
+//
+// Heroic Robotics also sells a family of dedicated LED controllers called
+// PixelPusher-  almost certainly the best LED controller in the world.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+// Some code originally from:
+// Mbed library to control LPD8806-based RGB LED Strips
+// (c) 2011 Jelmer Tiete
+// That library is ported from the Arduino implementation of Adafruit Industries
+// found at: http://github.com/adafruit/LPD8806
+// and their strips: http://www.adafruit.com/products/306
+// Released under the MIT License: http://mbed.org/license/mit
+//
+// Parameterized and modified to use soft SPI.
+// Jas Strong <jasmine@electronpusher.org>
+// Then remonstered to use hardware SPI for blast mode.
+//
+/*****************************************************************************/
+
+#include "LedStrip.h"
+#include "FastPixelLPD8806.h"
+
+#include "MODDMA.h"
+
+#define LATCHNUMBER 32
+#define FAST_PIXEL_MHZ 18
+
+// DMA controller and frequency setting
+extern MODDMA dma;
+extern int current_strip_fill;
+ 
+ // when the transfer is complete, kill the channel.
+void dma_complete_callback() {
+    MODDMA_Config *config = dma.getConfig();
+    dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
+    
+    // clear the IRQ flags
+    if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();    
+    if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();  
+}
+ 
+void dma_err_callback() {
+    MODDMA_Config *config = dma.getConfig();
+    dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
+    
+    // clear the IRQ flags
+    if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();    
+    if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();  
+} 
+
+FastPixelLPD8806::FastPixelLPD8806(PinName dataPin, PinName clockPin, int n) :
+    _spi(dataPin, NC, clockPin)
+ {
+    // Allocate 3 bytes per pixel plus latch bytes
+    numLEDs = n;
+    pixels = (uint8_t *)malloc(numLEDs * 3 + ((numLEDs + LATCHNUMBER-1) / LATCHNUMBER));
+    if (pixels) {
+        memset(pixels, 0x80, numLEDs * 3); // Init to RGB 'off' state
+        memset(pixels+numLEDs*3, 0x0, (numLEDs + LATCHNUMBER-1) / LATCHNUMBER); // latch data
+    }
+        
+    _spi.format(8,0);
+    _spi.frequency(FAST_PIXEL_MHZ*1000000);
+    
+    // remember which strip we are
+    strip_num = current_strip_fill;
+    
+    // make a new DMA config
+    dma_config = new MODDMA_Config;
+}
+ 
+inline void FastPixelLPD8806::write(uint8_t byte) {
+    _spi.write(byte);
+}
+
+
+void FastPixelLPD8806::begin(void) {
+
+    blank();
+    show();
+    show();
+}
+
+uint16_t FastPixelLPD8806::numPixels(void) {
+    return numLEDs;
+}
+
+void FastPixelLPD8806::blank(void) {
+    memset(pixels, 0x80, numLEDs * 3);
+}
+
+// Set up the DMA controller;  we only have two SSP peripherals, so only two strips.
+
+void FastPixelLPD8806::show(void) {
+     if (strip_num == 0) {
+        dma_config  -> channelNum   (MODDMA::Channel_0)
+                    -> srcMemAddr   ( (uint32_t) pixels )
+                    -> dstMemAddr   ( MODDMA::SSP0_Tx )
+                    -> transferSize (numLEDs * 3 + ((numLEDs + LATCHNUMBER-1) / LATCHNUMBER))
+                    -> transferType (MODDMA::m2p)
+                    -> dstConn      (MODDMA::SSP0_Tx)
+                    -> attach_tc    (&dma_complete_callback)
+                    -> attach_err   (&dma_err_callback);
+       LPC_SSP0->DMACR = (1<<1)|(1<<0); // TX,RXDMAE
+    } else {
+        dma_config  -> channelNum   (MODDMA::Channel_1)
+                    -> srcMemAddr   ( (uint32_t) pixels )
+                    -> dstMemAddr   ( MODDMA::SSP1_Tx )
+                    -> transferSize (numLEDs * 3 + ((numLEDs +LATCHNUMBER-1) / LATCHNUMBER))
+                    -> transferType (MODDMA::m2p)
+                    -> dstConn      (MODDMA::SSP1_Tx)
+                    -> attach_tc    (&dma_complete_callback)
+                    -> attach_err   (&dma_err_callback);
+       LPC_SSP1->DMACR = (1<<1)|(1<<0); // TX,RXDMAE
+    }
+    while (dma.Enabled(dma_config->channelNum())) {
+        __nop();
+    }
+    dma.Setup(dma_config);
+    dma.Enable(dma_config);
+}
+
+// LPD8806 is 7-bit, so we shift to normalize to 256 PWM steps.
+uint32_t FastPixelLPD8806::total_luminance(void) {
+    uint32_t running_total;
+    running_total = 0;
+    for (int i=0; i<numLEDs*3; i++)
+        running_total += ((pixels[i] & 0x7f) <<1);
+    return running_total;
+}
+
+// Convert R,G,B to combined 32-bit color
+uint32_t FastPixelLPD8806::Color(uint8_t r, uint8_t g, uint8_t b) {
+    // Take the lowest 7 bits of each value and append them end to end
+    // We have the top bit set high (its a 'parity-like' bit in the protocol
+    // and must be set!)
+    return 0x808080 | ((uint32_t)(g>>1) << 16) | ((uint32_t)(r>>1) << 8) | (uint32_t)(b>>1);
+}
+
+// store the rgb component in our array
+void FastPixelLPD8806::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3  ] = (g>>1) | 0x80;
+    pixels[n*3+1] = (r>>1) | 0x80;
+    pixels[n*3+2] = (b>>1) | 0x80;
+}
+
+void FastPixelLPD8806::setPixelR(uint16_t n, uint8_t r) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3+1] = (r>>1) | 0x80;
+}
+
+void FastPixelLPD8806::setPixelG(uint16_t n, uint8_t g) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3] = (g>>1) | 0x80;
+}
+
+void FastPixelLPD8806::setPixelB(uint16_t n, uint8_t b) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3+2] = (b>>1) | 0x80;
+}
+
+// Set all in one function call, assuming GRB ordering
+void FastPixelLPD8806::setPackedPixels(uint8_t * buffer, uint32_t n) {
+    if (n >= numLEDs) return;
+    for (int i=0; i<n*3; i++)
+        buffer[i] = (buffer[i] >> 1) | 0x80;
+    memcpy(pixels, buffer, (size_t) (n*3));
+}
+
+void FastPixelLPD8806::setPixelColor(uint16_t n, uint32_t c) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3  ] = (c >> 16) | 0x80;
+    pixels[n*3+1] = (c >>  8) | 0x80;
+    pixels[n*3+2] =  c        | 0x80;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FastPixelLPD8806.h	Sat May 31 18:41:56 2014 +0000
@@ -0,0 +1,89 @@
+/***************************************************************************/
+// DMA-enabled high data rate driver for Heroic Robotics FastPixel strips.
+// Written by Jas Strong <jasmine@heroicrobotics.com>
+// Copyright (c) 2013-2014 Heroic Robotics, Inc.
+//
+// FastPixel is a family of high performance LED strips available from
+// Heroic Robotics, Inc.  http://heroicrobotics.com/ - check them out!
+//
+// These strips are capable of supporting 18 Mbit/sec when run on PixelPusher
+// hardware;  your performance on mbed is likely to be somewhat lower due to
+// the lack of high performance driver chips on the SPI lines.
+//
+// Heroic Robotics also sells a family of dedicated LED controllers called
+// PixelPusher-  almost certainly the best LED controller in the world.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+// Some portions originally from:
+//
+// Mbed library to control LPD8806-based RGB LED Strips
+// (c) 2011 Jelmer Tiete
+// This library is ported from the Arduino implementation of Adafruit Industries
+// found at: http://github.com/adafruit/LPD8806
+// and their strips: http://www.adafruit.com/products/306
+// Released under the MIT License: http://mbed.org/license/mit
+//
+// Parameterized and modified to use soft SPI.
+// Jas Strong <jasmine@electronpusher.org>
+// Then remonstered to use hardware SPI for blast mode.
+/*****************************************************************************/
+ 
+// Heavily modified by Jas Strong, 2012-10-04
+// Changed to use a virtual base class and to use software SPI.
+
+#include "mbed.h"
+#include "LedStrip.h"
+#include "MODDMA.h"
+
+#ifndef MBED_FastPixelLPD8806_H
+#define MBED_FastPixelLPD8806_H
+
+class FastPixelLPD8806 : public LedStrip {
+
+ public:
+
+  FastPixelLPD8806(PinName dataPin, PinName clockPin, int n);
+  virtual void begin(void);
+  virtual void show(void);
+  virtual void blank(void);
+  virtual void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
+  virtual void setPackedPixels(uint8_t * buffer, uint32_t n);
+  virtual void setPixelB(uint16_t n, uint8_t b);
+  virtual void setPixelG(uint16_t n, uint8_t g);
+  virtual void setPixelR(uint16_t n, uint8_t r);
+  virtual void setPixelColor(uint16_t n, uint32_t c);
+  virtual uint16_t numPixels(void);
+  virtual uint32_t Color(uint8_t, uint8_t, uint8_t);
+  virtual uint32_t total_luminance(void);
+  
+ private:
+  SPI _spi;
+  void write(uint8_t byte);
+  uint8_t *pixels;     // Holds LED color values
+  uint16_t numLEDs;     // Number of RGB LEDs in strand
+  MODDMA_Config * dma_config;
+  int strip_num;
+  
+
+  uint32_t clock_mask;
+  uint32_t data_mask;
+    
+};
+#endif
\ No newline at end of file
--- a/LPD8806_fast.cpp	Sun Mar 09 22:34:04 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +0,0 @@
-// Mbed library to control LPD8806-based RGB LED Strips
-// (c) 2011 Jelmer Tiete
-// This library is ported from the Arduino implementation of Adafruit Industries
-// found at: http://github.com/adafruit/LPD8806
-// and their strips: http://www.adafruit.com/products/306
-// Released under the MIT License: http://mbed.org/license/mit
-//
-// Parameterized and modified to use soft SPI.
-// Jas Strong <jasmine@electronpusher.org>
-// Then remonstered to use hardware SPI for blast mode.
-//
-/*****************************************************************************/
-
-#include "LedStrip.h"
-#include "LPD8806_fast.h"
-#include "board_variant.h"
-
-#include "MODDMA.h"
-
-#define LATCHNUMBER 32
-
-// DMA controller and frequency setting
-extern MODDMA dma;
-extern int turbo_mode;
-extern int current_strip_fill;
-
-/*
-    PixelPusher 3 pin names:
-
-    STRIP1C = P2_9,
-    STRIP1D = P4_29,
-    STRIP2C = P0_18,
-    STRIP2D = P2_1,
-    STRIP3C = P2_6,
-    STRIP3D = P0_8,
-    STRIP4C = P2_8,
-    STRIP4D = P0_7,
-    STRIP5C = P0_15,
-    STRIP5D = P2_0,
-    STRIP6C = P0_17,
-    STRIP6D = P2_4,
-    STRIP7C = P2_5,
-    STRIP7D = P0_9,
-    STRIP8C = P2_7,
-    STRIP8D = P0_6,
-    
-*/
-
-/*
- *  STRIP7D is P0[9] which is SSP1 MOSI
- *  STRIP4D is P0[7] which is SSP1 SCK
- *
- *  STRIP2C is P0[18] which is SSP0 MOSI
- *  STRIP5C is P0[15] which is SSP0 SCK
- */ 
- 
- // when the transfer is complete, kill the channel.
-void dma_complete_callback() {
-    MODDMA_Config *config = dma.getConfig();
-    dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-    
-    // clear the IRQ flags
-    if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();    
-    if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();  
-}
- 
-void dma_err_callback() {
-    MODDMA_Config *config = dma.getConfig();
-    dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
-    
-    // clear the IRQ flags
-    if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();    
-    if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();  
-} 
-
-LPD8806_fast::LPD8806_fast(PinName dataPin, PinName clockPin, int n) :
-    _spi(dataPin, NC, clockPin)
- {
-    // Allocate 3 bytes per pixel plus latch bytes
-    numLEDs = n;
-    pixels = (uint8_t *)malloc(numLEDs * 3 + ((numLEDs + LATCHNUMBER-1) / LATCHNUMBER));
-    if (pixels) {
-        memset(pixels, 0x80, numLEDs * 3); // Init to RGB 'off' state
-        memset(pixels+numLEDs*3, 0x0, (numLEDs + LATCHNUMBER-1) / LATCHNUMBER); // latch data
-    }
-        
-    _spi.format(8,0);
-    _spi.frequency(turbo_mode*1000000);
-    
-    // remember which strip we are
-    strip_num = current_strip_fill;
-    
-    // make a new DMA config
-    dma_config = new MODDMA_Config;
-}
- 
-inline void LPD8806_fast::write(uint8_t byte) {
-    _spi.write(byte);
-}
-
-/*
-inline void LPD8806_fast::write(uint8_t byte) {
-    for (int i=0; i<8; i++) {
-        clk = 0;
-        dat = (byte & 0x80);
-        clk = 1;
-        byte <<= 1;
-    }
-    clk = 0;
-}*/
-
-void LPD8806_fast::begin(void) {
-
-    blank();
-    show();
-    show();
-}
-
-uint16_t LPD8806_fast::numPixels(void) {
-    return numLEDs;
-}
-
-void LPD8806_fast::blank(void) {
-    memset(pixels, 0x80, numLEDs * 3);
-}
-
-// Set up the DMA controller;  we only have two SSP peripherals, so only two strips.
-
-void LPD8806_fast::show(void) {
-     if (strip_num == 0) {
-        dma_config  -> channelNum   (MODDMA::Channel_0)
-                    -> srcMemAddr   ( (uint32_t) pixels )
-                    -> dstMemAddr   ( MODDMA::SSP0_Tx )
-                    -> transferSize (numLEDs * 3 + ((numLEDs + LATCHNUMBER-1) / LATCHNUMBER))
-                    -> transferType (MODDMA::m2p)
-                    -> dstConn      (MODDMA::SSP0_Tx)
-                    -> attach_tc    (&dma_complete_callback)
-                    -> attach_err   (&dma_err_callback);
-       LPC_SSP0->DMACR = (1<<1)|(1<<0); // TX,RXDMAE
-    } else {
-        dma_config  -> channelNum   (MODDMA::Channel_1)
-                    -> srcMemAddr   ( (uint32_t) pixels )
-                    -> dstMemAddr   ( MODDMA::SSP1_Tx )
-                    -> transferSize (numLEDs * 3 + ((numLEDs +LATCHNUMBER-1) / LATCHNUMBER))
-                    -> transferType (MODDMA::m2p)
-                    -> dstConn      (MODDMA::SSP1_Tx)
-                    -> attach_tc    (&dma_complete_callback)
-                    -> attach_err   (&dma_err_callback);
-       LPC_SSP1->DMACR = (1<<1)|(1<<0); // TX,RXDMAE
-    }
-    while (dma.Enabled(dma_config->channelNum())) {
-        __nop();
-    }
-    dma.Setup(dma_config);
-    dma.Enable(dma_config);
-}
-
-// LPD8806 is 7-bit, so we shift to normalize to 256 PWM steps.
-uint32_t LPD8806_fast::total_luminance(void) {
-    uint32_t running_total;
-    running_total = 0;
-    for (int i=0; i<numLEDs*3; i++)
-        running_total += ((pixels[i] & 0x7f) <<1);
-    return running_total;
-}
-
-// Convert R,G,B to combined 32-bit color
-uint32_t LPD8806_fast::Color(uint8_t r, uint8_t g, uint8_t b) {
-    // Take the lowest 7 bits of each value and append them end to end
-    // We have the top bit set high (its a 'parity-like' bit in the protocol
-    // and must be set!)
-    return 0x808080 | ((uint32_t)(g>>1) << 16) | ((uint32_t)(r>>1) << 8) | (uint32_t)(b>>1);
-}
-
-// store the rgb component in our array
-void LPD8806_fast::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
-    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
-
-    pixels[n*3  ] = (g>>1) | 0x80;
-    pixels[n*3+1] = (r>>1) | 0x80;
-    pixels[n*3+2] = (b>>1) | 0x80;
-}
-
-void LPD8806_fast::setPixelR(uint16_t n, uint8_t r) {
-    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
-
-    pixels[n*3+1] = (r>>1) | 0x80;
-}
-
-void LPD8806_fast::setPixelG(uint16_t n, uint8_t g) {
-    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
-
-    pixels[n*3] = (g>>1) | 0x80;
-}
-
-void LPD8806_fast::setPixelB(uint16_t n, uint8_t b) {
-    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
-
-    pixels[n*3+2] = (b>>1) | 0x80;
-}
-
-// Set all in one function call, assuming GRB ordering
-void LPD8806_fast::setPackedPixels(uint8_t * buffer, uint32_t n) {
-    if (n >= numLEDs) return;
-    for (int i=0; i<n*3; i++)
-        buffer[i] = (buffer[i] >> 1) | 0x80;
-    memcpy(pixels, buffer, (size_t) (n*3));
-}
-
-void LPD8806_fast::setPixelColor(uint16_t n, uint32_t c) {
-    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
-
-    pixels[n*3  ] = (c >> 16) | 0x80;
-    pixels[n*3+1] = (c >>  8) | 0x80;
-    pixels[n*3+2] =  c        | 0x80;
-}
--- a/LPD8806_fast.h	Sun Mar 09 22:34:04 2014 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +0,0 @@
-// Mbed library to control LPD8806-based RGB LED Strips
-// (c) 2011 Jelmer Tiete
-// This library is ported from the Arduino implementation of Adafruit Industries
-// found at: http://github.com/adafruit/LPD8806
-// and their strips: http://www.adafruit.com/products/306
-// Released under the MIT License: http://mbed.org/license/mit
-//
-// Parameterized and modified to use soft SPI.
-// Jas Strong <jasmine@electronpusher.org>
-// Then remonstered to use hardware SPI for blast mode.
-/*****************************************************************************/
- 
-// Heavily modified by Jas Strong, 2012-10-04
-// Changed to use a virtual base class and to use software SPI.
-
-#include "mbed.h"
-#include "LedStrip.h"
-#include "MODDMA.h"
-
-#ifndef MBED_LPD8806_fast_H
-#define MBED_LPD8806_fast_H
-
-class LPD8806_fast : public LedStrip {
-
- public:
-
-  LPD8806_fast(PinName dataPin, PinName clockPin, int n);
-  virtual void begin(void);
-  virtual void show(void);
-  virtual void blank(void);
-  virtual void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b);
-  virtual void setPackedPixels(uint8_t * buffer, uint32_t n);
-  virtual void setPixelB(uint16_t n, uint8_t b);
-  virtual void setPixelG(uint16_t n, uint8_t g);
-  virtual void setPixelR(uint16_t n, uint8_t r);
-  virtual void setPixelColor(uint16_t n, uint32_t c);
-  virtual uint16_t numPixels(void);
-  virtual uint32_t Color(uint8_t, uint8_t, uint8_t);
-  virtual uint32_t total_luminance(void);
-  
- private:
-  SPI _spi;
-  void write(uint8_t byte);
-  uint8_t *pixels;     // Holds LED color values
-  uint16_t numLEDs;     // Number of RGB LEDs in strand
-  MODDMA_Config * dma_config;
-  int strip_num;
-  
-
-  uint32_t clock_mask;
-  uint32_t data_mask;
-    
-};
-#endif
\ No newline at end of file