my small LPD8806
Fork of LPD8806 by
LPD8806.cpp@1:6ebd3ac910b6, 2011-12-16 (annotated)
- Committer:
- ehbmbed2
- Date:
- Fri Dec 16 10:26:35 2011 +0000
- Revision:
- 1:6ebd3ac910b6
- Parent:
- 0:12e734116fea
- Child:
- 2:e07140e9f281
Updated comments
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: |
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) { |
ehbmbed2 | 0:12e734116fea | 53 | uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED |
ehbmbed2 | 0:12e734116fea | 54 | |
ehbmbed2 | 0:12e734116fea | 55 | for (i=0; i<nl3; i++ ) { |
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 | } |