Heroic Robotics / SD600A

Fork of SD600A by Heroic Robotics

Revision:
6:aacceefab2ea
Parent:
5:c2579d6415e1
Child:
7:cda3ca93e5a1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SD600A.cpp	Mon Oct 08 23:35:39 2012 +0000
@@ -0,0 +1,142 @@
+// Mbed library to control SD600A-based RGB LED Strips
+// Partially based on work (c) 2011 Jelmer Tiete
+//
+// Ported from Arduino by
+// Jas Strong <jasmine@electronpusher.org>
+/*****************************************************************************/
+
+#include "rtos.h"
+#include "LedStrip.h"
+#include "SD600A.h"
+
+void idle_function(void const *argument) {
+    while (1) {
+        ((SD600A *)argument)->threadlock.lock();
+        ((SD600A *)argument)->dat = 0;
+        ((SD600A *)argument)->clk = 1;
+        ((SD600A *)argument)->clk = 0;
+        ((SD600A *)argument)->clk = 1;
+        ((SD600A *)argument)->clk = 0;
+        ((SD600A *)argument)->threadlock.unlock();
+        Thread::yield();
+    }
+}
+
+SD600A::SD600A(PinName dataPin, PinName clockPin, int n) :
+    dat(dataPin),
+    clk(clockPin),
+    idlethread(idle_function,this) {
+    // Allocate 3 bytes per pixel:
+    numLEDs = n;
+    if ((pixels = (uint8_t *)malloc(numLEDs * 3))) {
+        memset(pixels, 0, numLEDs * 3); // Init to RGB 'off' state
+    }
+    threadlock.unlock();
+}
+
+/*
+ *  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 SD600A::write(uint8_t byte) {
+    for (int i=0; i<8; i++) {
+        clk = 0;
+        dat = (byte & 0x80);
+        clk = 1;
+        byte <<= 1;
+    }
+    clk = 0;
+}
+
+void SD600A::begin(void) {
+
+    // Issue initial latch to 'wake up' strip (latch length varies w/numLEDs)
+    threadlock.lock();
+    for (int i=0; i<numLEDs; i++) {
+        write(0);
+        write(0);
+        write(0);
+    }
+    writeguard();
+    threadlock.unlock();
+}
+
+uint16_t SD600A::numPixels(void) {
+    return numLEDs;
+}
+
+void SD600A::writeguard(void) {
+    // generate a 25-bit word of zeros
+    clk = 1;
+    dat = 0;
+    clk = 0;
+    write(0x00);
+    write(0x00);
+    write(0x00);
+}
+
+void SD600A::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 SD600A::show(void) {
+    uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
+    threadlock.lock();
+
+    for (i=0; i<nl3; i++ ) {
+        write(pixels[i]);
+    }
+
+    // Write guard word
+    writeguard();
+    threadlock.unlock();
+}
+
+// Convert R,G,B to combined 32-bit color
+uint32_t SD600A::Color(uint8_t r, uint8_t g, uint8_t b) {
+    // Take 23 bits of the value and append them end to end
+    // We cannot drive all ones or it will make the part latch if the previous word ended in zero!
+    return 0xfffffe & ((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b;
+}
+
+// store the rgb component in our array
+void SD600A::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 & 0xff;
+    pixels[n*3+1] = r & 0xff;
+    pixels[n*3+2] = b & 0xfe;
+}
+
+void SD600A::setPixelR(uint16_t n, uint8_t r) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3+1] = r & 0xff;
+}
+
+void SD600A::setPixelG(uint16_t n, uint8_t g) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3] = g & 0xff;
+}
+
+void SD600A::setPixelB(uint16_t n, uint8_t b) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3+2] = b & 0xfe;
+}
+
+void SD600A::setPixelColor(uint16_t n, uint32_t c) {
+    if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
+
+    pixels[n*3  ] = (c >> 16) & 0xff;
+    pixels[n*3+1] = (c >>  8) & 0xff;
+    pixels[n*3+2] =  c        & 0xfe;
+}