Simple 8x8 LED Matrix controller which interfaces with a Processing GUI over serial to display sketches

Dependencies:   Multi_WS2811 mbed

Fork of Multi_WS2811_test by Ned Konz

Files at this revision

API Documentation at this revision

Comitter:
heroic
Date:
Thu Oct 11 08:34:21 2012 +0000
Parent:
5:70ded6500cd3
Child:
7:3025f0e0d70a
Commit message:
Initial commit of WS2801 driver library.

Changed in this revision

LPD8806.cpp Show diff for this revision Revisions of this file
LPD8806.h Show diff for this revision Revisions of this file
WS2801.cpp Show annotated file Show diff for this revision Revisions of this file
WS2801.h Show annotated file Show diff for this revision Revisions of this file
--- a/LPD8806.cpp	Wed Oct 10 05:43:58 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +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>
-/*****************************************************************************/
-
-#include "LedStrip.h"
-#include "LPD8806.h"
-
-LPD8806::LPD8806(PinName dataPin, PinName clockPin, int n) :
-    dat(dataPin),
-    clk(clockPin) {
-    // Allocate 3 bytes per pixel:
-    numLEDs = n;
-    if ((pixels = (uint8_t *)malloc(numLEDs * 3))) {
-        memset(pixels, 0x80, numLEDs * 3); // Init to RGB 'off' state
-    }
-}
-
-/*
- *  Soft SPI clock-out implementation (CPOL = 0, CPHA = 0).
- *  Certainly not the fastest in the world but it'll do.
- *  Gets about 3.6 MHz;  could get several times as much
- *  using the bitbands directly  - jas.
- */
- 
-void LPD8806::write(uint8_t byte) {
-    for (int i=0; i<8; i++) {
-        clk = 0;
-        dat = (byte & 0x80);
-        clk = 1;
-        byte <<= 1;
-    }
-    clk = 0;
-}
-
-void LPD8806::begin(void) {
-
-    // Issue initial latch to 'wake up' strip (latch length varies w/numLEDs)
-    writezeros(3 * ((numLEDs + 63) / 64));
-    blank();
-    show();
-}
-
-uint16_t LPD8806::numPixels(void) {
-    return numLEDs;
-}
-
-void LPD8806::writezeros(uint16_t n) {
-    while (n--) write(0x00);
-}
-
-void LPD8806::blank(void) {
-    memset(pixels, 0x80, numLEDs * 3);
-}
-
-// This is how data is pushed to the strip.  Unfortunately, the company
-// that makes the chip didnt release the  protocol document or you need
-// to sign an NDA or something stupid like that, but we reverse engineered
-// this from a strip controller and it seems to work very nicely!
-void LPD8806::show(void) {
-    uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
-
-    for (i=0; i<nl3; i++ ) {
-        write(pixels[i]);
-    }
-
-    // Write latch at end of data; latch length varies with number of LEDs
-    writezeros(3 * ((numLEDs + 63) / 64));
-}
-
-// Convert R,G,B to combined 32-bit color
-uint32_t LPD8806::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 << 16) | ((uint32_t)r << 8) | (uint32_t)b;
-}
-
-// store the rgb component in our array
-void LPD8806::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 | 0x80;
-    pixels[n*3+1] = r | 0x80;
-    pixels[n*3+2] = b | 0x80;
-}
-
-void LPD8806::setPixelR(uint16_t n, uint8_t r) {
-    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
-
-    pixels[n*3+1] = r | 0x80;
-}
-
-void LPD8806::setPixelG(uint16_t n, uint8_t g) {
-    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
-
-    pixels[n*3] = g | 0x80;
-}
-
-void LPD8806::setPixelB(uint16_t n, uint8_t b) {
-    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
-
-    pixels[n*3+2] = b | 0x80;
-}
-
-void LPD8806::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.h	Wed Oct 10 05:43:58 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +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
-//
-/*****************************************************************************/
-
-// 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"
-#ifndef MBED_LPD8806_H
-#define MBED_LPD8806_H
-
-class LPD8806 : public LedStrip {
-
- public:
-
-  LPD8806(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 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);
-
- private:
-  DigitalOut dat;
-  DigitalOut clk;
-  void write(uint8_t byte);
-  uint8_t *pixels;     // Holds LED color values
-  uint16_t numLEDs;     // Number of RGB LEDs in strand
-    
-  void
-    writezeros(uint16_t n);
-};
-#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WS2801.cpp	Thu Oct 11 08:34:21 2012 +0000
@@ -0,0 +1,114 @@
+// 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>
+/*****************************************************************************/
+
+#include "LedStrip.h"
+#include "WS2801.h"
+
+WS2801::WS2801(PinName dataPin, PinName clockPin, int n) :
+    dat(dataPin),
+    clk(clockPin) {
+    // Allocate 3 bytes per pixel:
+    numLEDs = n;
+    if ((pixels = (uint8_t *)malloc(numLEDs * 3))) {
+        memset(pixels, 0x00, numLEDs * 3); // Init to RGB 'off' state
+    }
+    guardtime.start();
+}
+
+/*
+ *  Soft SPI clock-out implementation (CPOL = 0, CPHA = 0).
+ *  Certainly not the fastest in the world but it'll do.
+ *  Gets about 3.6 MHz;  could get several times as much
+ *  using the bitbands directly  - jas.
+ */
+ 
+void WS2801::write(uint8_t byte) {
+    for (int i=0; i<8; i++) {
+        clk = 0;
+        wait_us(WS2801_DELAY);
+        dat = (byte & 0x80);
+        clk = 1;
+        wait_us(WS2801_DELAY);
+        byte <<= 1;
+    }
+    clk = 0;
+}
+
+void WS2801::begin(void) {
+    blank();
+    show();
+}
+
+uint16_t WS2801::numPixels(void) {
+    return numLEDs;
+}
+
+void WS2801::blank(void) {
+    memset(pixels, 0x00, numLEDs * 3);
+}
+
+// This is how data is pushed to the strip.  Unfortunately, the company
+// that makes the chip didnt release the  protocol document or you need
+// to sign an NDA or something stupid like that, but we reverse engineered
+// this from a strip controller and it seems to work very nicely!
+void WS2801::show(void) {
+    uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
+    while (guardtime.read_us() < 500)
+        /* spin */;
+    for (i=0; i<nl3; i++ ) {
+        write(pixels[i]);
+    }
+
+    guardtime.reset();
+}
+
+// Convert R,G,B to combined 32-bit color
+uint32_t WS2801::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 ((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b;
+}
+
+// store the rgb component in our array
+void WS2801::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;
+    pixels[n*3+1] = r;
+    pixels[n*3+2] = b;
+}
+
+void WS2801::setPixelR(uint16_t n, uint8_t r) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3+1] = r;
+}
+
+void WS2801::setPixelG(uint16_t n, uint8_t g) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3] = g;
+}
+
+void WS2801::setPixelB(uint16_t n, uint8_t b) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3+2] = b;
+}
+
+void WS2801::setPixelColor(uint16_t n, uint32_t c) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3  ] = (c >> 16);
+    pixels[n*3+1] = (c >>  8);
+    pixels[n*3+2] =  c;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WS2801.h	Thu Oct 11 08:34:21 2012 +0000
@@ -0,0 +1,45 @@
+// Mbed library to control WS2801-based RGB LED Strips
+// some portions (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
+//
+/*****************************************************************************/
+
+// 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"
+#ifndef MBED_WS2801_H
+#define MBED_WS2801_H
+
+#define WS2801_DELAY 1
+
+class WS2801 : public LedStrip {
+
+ public:
+
+  WS2801(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 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);
+
+ private:
+  DigitalOut dat;
+  DigitalOut clk;
+  void write(uint8_t byte);
+  uint8_t *pixels;     // Holds LED color values
+  uint16_t numLEDs;     // Number of RGB LEDs in strand
+  Timer guardtime;
+    
+};
+#endif
\ No newline at end of file