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 use a fixed sized buffer rather than malloc - if we use malloc rtos is unhappy...
Fork of LPD8806 by
LPD8806.cpp@2:5d654eba3240, 2014-05-30 (annotated)
- Committer:
- Jasper
- Date:
- Fri May 30 03:37:16 2014 +0000
- Revision:
- 2:5d654eba3240
- Parent:
- 1:6ebd3ac910b6
use a static buffer rather than using malloc - for some reason the malloc memory is somewhere that clashes with the RTOS/Ethernet/Internet stuff, don't know why...
Who changed what in which revision?
User | Revision | Line number | New 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 |
ehbmbed2 | 0:12e734116fea | 18 | SPI spi(p5, p6, p7); // 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: |
Jasper | 2:5d654eba3240 | 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; |
Jasper | 2:5d654eba3240 | 26 | // } |
Jasper | 2:5d654eba3240 | 27 | } |
Jasper | 2:5d654eba3240 | 28 | |
Jasper | 2:5d654eba3240 | 29 | int LPD8806::pixels_ok(void) { |
Jasper | 2:5d654eba3240 | 30 | if (pixels != NULL) |
Jasper | 2:5d654eba3240 | 31 | return 1; |
Jasper | 2:5d654eba3240 | 32 | else |
Jasper | 2:5d654eba3240 | 33 | return 0; |
ehbmbed2 | 0:12e734116fea | 34 | } |
ehbmbed2 | 0:12e734116fea | 35 | |
ehbmbed2 | 0:12e734116fea | 36 | void LPD8806::begin(void) { |
ehbmbed2 | 0:12e734116fea | 37 | |
ehbmbed2 | 0:12e734116fea | 38 | // Setup the spi for 8 bit data, low steady state clock, |
ehbmbed2 | 0:12e734116fea | 39 | // first edge capture, with a 2MHz clock rate |
ehbmbed2 | 0:12e734116fea | 40 | spi.format(8,0); |
ehbmbed2 | 0:12e734116fea | 41 | spi.frequency(2000000); |
ehbmbed2 | 0:12e734116fea | 42 | |
ehbmbed2 | 0:12e734116fea | 43 | // Issue initial latch to 'wake up' strip (latch length varies w/numLEDs) |
ehbmbed2 | 0:12e734116fea | 44 | writezeros(3 * ((numLEDs + 63) / 64)); |
ehbmbed2 | 0:12e734116fea | 45 | } |
ehbmbed2 | 0:12e734116fea | 46 | |
ehbmbed2 | 0:12e734116fea | 47 | uint16_t LPD8806::numPixels(void) { |
ehbmbed2 | 0:12e734116fea | 48 | return numLEDs; |
ehbmbed2 | 0:12e734116fea | 49 | } |
ehbmbed2 | 0:12e734116fea | 50 | |
ehbmbed2 | 0:12e734116fea | 51 | void LPD8806::writezeros(uint16_t n) { |
ehbmbed2 | 0:12e734116fea | 52 | while (n--) spi.write(0x00); |
ehbmbed2 | 0:12e734116fea | 53 | } |
ehbmbed2 | 0:12e734116fea | 54 | |
ehbmbed2 | 0:12e734116fea | 55 | // This is how data is pushed to the strip. Unfortunately, the company |
ehbmbed2 | 0:12e734116fea | 56 | // that makes the chip didnt release the protocol document or you need |
ehbmbed2 | 0:12e734116fea | 57 | // to sign an NDA or something stupid like that, but we reverse engineered |
ehbmbed2 | 0:12e734116fea | 58 | // this from a strip controller and it seems to work very nicely! |
ehbmbed2 | 0:12e734116fea | 59 | void LPD8806::show(void) { |
ehbmbed2 | 0:12e734116fea | 60 | uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED |
ehbmbed2 | 0:12e734116fea | 61 | |
ehbmbed2 | 0:12e734116fea | 62 | for (i=0; i<nl3; i++ ) { |
ehbmbed2 | 0:12e734116fea | 63 | spi.write(pixels[i]); |
ehbmbed2 | 0:12e734116fea | 64 | } |
ehbmbed2 | 0:12e734116fea | 65 | |
ehbmbed2 | 0:12e734116fea | 66 | // Write latch at end of data; latch length varies with number of LEDs |
ehbmbed2 | 0:12e734116fea | 67 | writezeros(3 * ((numLEDs + 63) / 64)); |
ehbmbed2 | 0:12e734116fea | 68 | |
ehbmbed2 | 0:12e734116fea | 69 | // We need to have a delay here, a few ms seems to do the job |
ehbmbed2 | 0:12e734116fea | 70 | // shorter may be OK as well - need to experiment :( |
Jasper | 2:5d654eba3240 | 71 | wait_ms(3); |
ehbmbed2 | 0:12e734116fea | 72 | } |
ehbmbed2 | 0:12e734116fea | 73 | |
ehbmbed2 | 0:12e734116fea | 74 | // Convert R,G,B to combined 32-bit color |
ehbmbed2 | 0:12e734116fea | 75 | uint32_t LPD8806::Color(uint8_t r, uint8_t g, uint8_t b) { |
ehbmbed2 | 0:12e734116fea | 76 | // Take the lowest 7 bits of each value and append them end to end |
ehbmbed2 | 0:12e734116fea | 77 | // We have the top bit set high (its a 'parity-like' bit in the protocol |
ehbmbed2 | 0:12e734116fea | 78 | // and must be set!) |
ehbmbed2 | 0:12e734116fea | 79 | return 0x808080 | ((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b; |
ehbmbed2 | 0:12e734116fea | 80 | } |
ehbmbed2 | 0:12e734116fea | 81 | |
ehbmbed2 | 0:12e734116fea | 82 | // store the rgb component in our array |
ehbmbed2 | 0:12e734116fea | 83 | void LPD8806::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) { |
ehbmbed2 | 0:12e734116fea | 84 | if (n >= numLEDs) return; // '>=' because arrays are 0-indexed |
ehbmbed2 | 0:12e734116fea | 85 | |
Jasper | 2:5d654eba3240 | 86 | pixels[(n * 3) ] = g | 0x80; |
Jasper | 2:5d654eba3240 | 87 | pixels[(n * 3) +1 ] = r | 0x80; |
Jasper | 2:5d654eba3240 | 88 | pixels[(n * 3) +2 ] = b | 0x80; |
ehbmbed2 | 0:12e734116fea | 89 | } |
ehbmbed2 | 0:12e734116fea | 90 | |
ehbmbed2 | 0:12e734116fea | 91 | void LPD8806::setPixelColor(uint16_t n, uint32_t c) { |
ehbmbed2 | 0:12e734116fea | 92 | if (n >= numLEDs) return; // '>=' because arrays are 0-indexed |
ehbmbed2 | 0:12e734116fea | 93 | |
Jasper | 2:5d654eba3240 | 94 | pixels[(n * 3) ] = ((c >> 16) & 0xff)| 0x80; |
Jasper | 2:5d654eba3240 | 95 | pixels[(n * 3) + 1] = ((c >> 8) & 0xff)| 0x80; |
Jasper | 2:5d654eba3240 | 96 | pixels[(n * 3) + 2] = ( c & 0xff)| 0x80; |
ehbmbed2 | 0:12e734116fea | 97 | } |