Library for LPD8806 (and probably LPD8803/LPD8809) PWM LED driver chips, strips and pixels. For FRDM K64F

Dependents:   RadarLEDStrip

Fork of LPD8806 by Jelmer Tiete

Committer:
awatt196
Date:
Wed Jul 13 16:34:00 2016 +0000
Revision:
2:7478c1ea3fe4
Parent:
1:6ebd3ac910b6
just changed the pins

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ehbmbed2 0:12e734116fea 1 // Mbed library to control LPD8806-based RGB LED Strips
ehbmbed2 0:12e734116fea 2 // (c) 2011 Jelmer Tiete
ehbmbed2 0:12e734116fea 3 // This library is ported from the Arduino implementation of Adafruit Industries
ehbmbed2 0:12e734116fea 4 // found at: http://github.com/adafruit/LPD8806
ehbmbed2 0:12e734116fea 5 // and their strips: http://www.adafruit.com/products/306
ehbmbed2 0:12e734116fea 6 // Released under the MIT License: http://mbed.org/license/mit
ehbmbed2 1:6ebd3ac910b6 7 //
ehbmbed2 1:6ebd3ac910b6 8 // standard connected to 1st hardware SPI
ehbmbed2 1:6ebd3ac910b6 9 // LPD8806 <> MBED
ehbmbed2 1:6ebd3ac910b6 10 // DATA -> P5
ehbmbed2 1:6ebd3ac910b6 11 // CLOCK -> p7
ehbmbed2 0:12e734116fea 12 /*****************************************************************************/
ehbmbed2 0:12e734116fea 13
ehbmbed2 0:12e734116fea 14 #include "LPD8806.h"
ehbmbed2 0:12e734116fea 15
ehbmbed2 0:12e734116fea 16 //Define SPI pins
ehbmbed2 1:6ebd3ac910b6 17 //Connected to first SPI module
awatt196 2:7478c1ea3fe4 18 SPI spi(D11, D12, D13); // mosi, miso, sclk
ehbmbed2 0:12e734116fea 19 //SPI spi(p11, p12, p13); // mosi, miso, sclk
ehbmbed2 0:12e734116fea 20
ehbmbed2 0:12e734116fea 21 LPD8806::LPD8806(uint16_t n) {
ehbmbed2 0:12e734116fea 22 // Allocate 3 bytes per pixel:
ehbmbed2 0:12e734116fea 23 if (NULL != (pixels = (uint8_t *)malloc(numLEDs * 3))) {
ehbmbed2 0:12e734116fea 24 memset(pixels, 0x80, numLEDs * 3); // Init to RGB 'off' state
ehbmbed2 0:12e734116fea 25 numLEDs = n;
ehbmbed2 0:12e734116fea 26 }
ehbmbed2 0:12e734116fea 27 }
ehbmbed2 0:12e734116fea 28
ehbmbed2 0:12e734116fea 29 void LPD8806::begin(void) {
ehbmbed2 0:12e734116fea 30
ehbmbed2 0:12e734116fea 31 // Setup the spi for 8 bit data, low steady state clock,
ehbmbed2 0:12e734116fea 32 // first edge capture, with a 2MHz clock rate
ehbmbed2 0:12e734116fea 33 spi.format(8,0);
ehbmbed2 0:12e734116fea 34 spi.frequency(2000000);
ehbmbed2 0:12e734116fea 35
ehbmbed2 0:12e734116fea 36 // Issue initial latch to 'wake up' strip (latch length varies w/numLEDs)
ehbmbed2 0:12e734116fea 37 writezeros(3 * ((numLEDs + 63) / 64));
ehbmbed2 0:12e734116fea 38 }
ehbmbed2 0:12e734116fea 39
ehbmbed2 0:12e734116fea 40 uint16_t LPD8806::numPixels(void) {
ehbmbed2 0:12e734116fea 41 return numLEDs;
ehbmbed2 0:12e734116fea 42 }
ehbmbed2 0:12e734116fea 43
ehbmbed2 0:12e734116fea 44 void LPD8806::writezeros(uint16_t n) {
ehbmbed2 0:12e734116fea 45 while (n--) spi.write(0x00);
ehbmbed2 0:12e734116fea 46 }
ehbmbed2 0:12e734116fea 47
ehbmbed2 0:12e734116fea 48 // This is how data is pushed to the strip. Unfortunately, the company
ehbmbed2 0:12e734116fea 49 // that makes the chip didnt release the protocol document or you need
ehbmbed2 0:12e734116fea 50 // to sign an NDA or something stupid like that, but we reverse engineered
ehbmbed2 0:12e734116fea 51 // this from a strip controller and it seems to work very nicely!
ehbmbed2 0:12e734116fea 52 void LPD8806::show(void) {
awatt196 2:7478c1ea3fe4 53 uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED
ehbmbed2 0:12e734116fea 54
awatt196 2:7478c1ea3fe4 55 for (i=0; i<nl3; i++ ) { //nl3 = 96
ehbmbed2 0:12e734116fea 56 spi.write(pixels[i]);
ehbmbed2 0:12e734116fea 57 }
ehbmbed2 0:12e734116fea 58
ehbmbed2 0:12e734116fea 59 // Write latch at end of data; latch length varies with number of LEDs
ehbmbed2 0:12e734116fea 60 writezeros(3 * ((numLEDs + 63) / 64));
ehbmbed2 0:12e734116fea 61
ehbmbed2 0:12e734116fea 62 // We need to have a delay here, a few ms seems to do the job
ehbmbed2 0:12e734116fea 63 // shorter may be OK as well - need to experiment :(
ehbmbed2 0:12e734116fea 64 // wait_ms(3);
ehbmbed2 0:12e734116fea 65 }
ehbmbed2 0:12e734116fea 66
ehbmbed2 0:12e734116fea 67 // Convert R,G,B to combined 32-bit color
ehbmbed2 0:12e734116fea 68 uint32_t LPD8806::Color(uint8_t r, uint8_t g, uint8_t b) {
ehbmbed2 0:12e734116fea 69 // Take the lowest 7 bits of each value and append them end to end
ehbmbed2 0:12e734116fea 70 // We have the top bit set high (its a 'parity-like' bit in the protocol
ehbmbed2 0:12e734116fea 71 // and must be set!)
ehbmbed2 0:12e734116fea 72 return 0x808080 | ((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b;
ehbmbed2 0:12e734116fea 73 }
ehbmbed2 0:12e734116fea 74
ehbmbed2 0:12e734116fea 75 // store the rgb component in our array
ehbmbed2 0:12e734116fea 76 void LPD8806::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
ehbmbed2 0:12e734116fea 77 if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
ehbmbed2 0:12e734116fea 78
ehbmbed2 0:12e734116fea 79 pixels[n*3 ] = g | 0x80;
ehbmbed2 0:12e734116fea 80 pixels[n*3+1] = r | 0x80;
ehbmbed2 0:12e734116fea 81 pixels[n*3+2] = b | 0x80;
ehbmbed2 0:12e734116fea 82 }
ehbmbed2 0:12e734116fea 83
ehbmbed2 0:12e734116fea 84 void LPD8806::setPixelColor(uint16_t n, uint32_t c) {
ehbmbed2 0:12e734116fea 85 if (n >= numLEDs) return; // '>=' because arrays are 0-indexed
ehbmbed2 0:12e734116fea 86
ehbmbed2 0:12e734116fea 87 pixels[n*3 ] = (c >> 16) | 0x80;
ehbmbed2 0:12e734116fea 88 pixels[n*3+1] = (c >> 8) | 0x80;
ehbmbed2 0:12e734116fea 89 pixels[n*3+2] = c | 0x80;
ehbmbed2 0:12e734116fea 90 }