Library for LPD8806 (and probably LPD8803/LPD8809) PWM LED driver chips, strips and pixels. Standard connected to 1st hardware SPI module. Data -> p5 and Clock -> p7

Dependents:   LPD8806_Test net-o-meter PennGradCap

Files at this revision

API Documentation at this revision

Comitter:
ehbmbed2
Date:
Fri Dec 16 03:16:50 2011 +0000
Child:
1:6ebd3ac910b6
Commit message:
first revision, works, needs to be tested on long strands

Changed in this revision

LPD8806.cpp Show annotated file Show diff for this revision Revisions of this file
LPD8806.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LPD8806.cpp	Fri Dec 16 03:16:50 2011 +0000
@@ -0,0 +1,85 @@
+// 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
+
+/*****************************************************************************/
+
+#include "LPD8806.h"
+
+//Define SPI pins
+SPI spi(p5, p6, p7); // mosi, miso, sclk
+//SPI spi(p11, p12, p13); // mosi, miso, sclk
+
+LPD8806::LPD8806(uint16_t n) {
+    // Allocate 3 bytes per pixel:
+    if (NULL != (pixels = (uint8_t *)malloc(numLEDs * 3))) {
+        memset(pixels, 0x80, numLEDs * 3); // Init to RGB 'off' state
+        numLEDs     = n;
+    }
+}
+
+void LPD8806::begin(void) {
+
+    // Setup the spi for 8 bit data, low steady state clock,
+    // first edge capture, with a 2MHz clock rate
+    spi.format(8,0);
+    spi.frequency(2000000);
+
+    // Issue initial latch to 'wake up' strip (latch length varies w/numLEDs)
+    writezeros(3 * ((numLEDs + 63) / 64));
+}
+
+uint16_t LPD8806::numPixels(void) {
+    return numLEDs;
+}
+
+void LPD8806::writezeros(uint16_t n) {
+    while (n--) spi.write(0x00);
+}
+
+// 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++ ) {
+        spi.write(pixels[i]);
+    }
+
+    // Write latch at end of data; latch length varies with number of LEDs
+    writezeros(3 * ((numLEDs + 63) / 64));
+
+    // We need to have a delay here, a few ms seems to do the job
+    // shorter may be OK as well - need to experiment :(
+// wait_ms(3);
+}
+
+// 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::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/LPD8806.h	Fri Dec 16 03:16:50 2011 +0000
@@ -0,0 +1,39 @@
+// 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
+
+/*****************************************************************************/
+
+#include "mbed.h"
+#ifndef MBED_LPD8806_H
+#define MBED_LPD8806_H
+
+class LPD8806 {
+
+ public:
+
+  LPD8806(uint16_t n);
+  void
+    begin(void),
+    show(void),
+    setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
+    setPixelColor(uint16_t n, uint32_t c);
+  uint16_t
+    numPixels(void);
+  uint32_t
+    Color(uint8_t, uint8_t, uint8_t);
+
+ private:
+
+  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