xLAB - acutators / led-mrf-osc-legacy-code

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LPD8806.cpp Source File

LPD8806.cpp

00001 // Mbed library to control LPD8806-based RGB LED Strips
00002 // (c) 2011 Jelmer Tiete
00003 // This library is ported from the Arduino implementation of Adafruit Industries
00004 // found at: http://github.com/adafruit/LPD8806
00005 // and their strips: http://www.adafruit.com/products/306
00006 // Released under the MIT License: http://mbed.org/license/mit
00007 //
00008 // standard connected to 1st hardware SPI
00009 // LPD8806  <> MBED
00010 // DATA     -> P5
00011 // CLOCK    -> p7
00012 /*****************************************************************************/
00013 
00014 #include "LPD8806.h"
00015 
00016 //Define SPI pins
00017 //Connected to first SPI module
00018 SPI spi(p5, p6, p7); // mosi, miso, sclk
00019 //SPI spi(p11, p12, p13); // mosi, miso, sclk
00020 
00021 LPD8806::LPD8806(uint16_t n) {
00022     // Allocate 3 bytes per pixel:
00023     if (NULL != (pixels = (uint8_t *)malloc(numLEDs * 3))) {
00024         memset(pixels, 0x80, numLEDs * 3); // Init to RGB 'off' state
00025         numLEDs     = n;
00026     }
00027 }
00028 
00029 void LPD8806::begin(void) {
00030 
00031     // Setup the spi for 8 bit data, low steady state clock,
00032     // first edge capture, with a 2MHz clock rate
00033     spi.format(8,0);
00034     spi.frequency(2000000);
00035 
00036     // Issue initial latch to 'wake up' strip (latch length varies w/numLEDs)
00037     writezeros(3 * ((numLEDs + 63) / 64));
00038 }
00039 
00040 uint16_t LPD8806::numPixels(void) {
00041     return numLEDs;
00042 }
00043 
00044 void LPD8806::writezeros(uint16_t n) {
00045     while (n--) spi.write(0x00);
00046 }
00047 
00048 // This is how data is pushed to the strip.  Unfortunately, the company
00049 // that makes the chip didnt release the  protocol document or you need
00050 // to sign an NDA or something stupid like that, but we reverse engineered
00051 // this from a strip controller and it seems to work very nicely!
00052 void LPD8806::show(void) {
00053     uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
00054 
00055     for (i=0; i<nl3; i++ ) {
00056         spi.write(pixels[i]);
00057     }
00058 
00059     // Write latch at end of data; latch length varies with number of LEDs
00060     writezeros(3 * ((numLEDs + 63) / 64));
00061 
00062     // We need to have a delay here, a few ms seems to do the job
00063     // shorter may be OK as well - need to experiment :(
00064 // wait_ms(3);
00065 }
00066 
00067 // Convert R,G,B to combined 32-bit color
00068 uint32_t LPD8806::Color(uint8_t r, uint8_t g, uint8_t b) {
00069     // Take the lowest 7 bits of each value and append them end to end
00070     // We have the top bit set high (its a 'parity-like' bit in the protocol
00071     // and must be set!)
00072     return 0x808080 | ((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b;
00073 }
00074 
00075 // store the rgb component in our array
00076 void LPD8806::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
00077     if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
00078 
00079     pixels[n*3  ] = g | 0x80;
00080     pixels[n*3+1] = r | 0x80;
00081     pixels[n*3+2] = b | 0x80;
00082 }
00083 
00084 void LPD8806::setPixelColor(uint16_t n, uint32_t c) {
00085     if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
00086 
00087     pixels[n*3  ] = (c >> 16) | 0x80;
00088     pixels[n*3+1] = (c >>  8) | 0x80;
00089     pixels[n*3+2] =  c        | 0x80;
00090 }