LPD8806 osc communication
Dependents: LineLedControl LineLedControl2
Fork of LPD8806 by
LPD8806.cpp@2:0d8eb41bb976, 2013-08-19 (annotated)
- Committer:
- sfjmt
- Date:
- Mon Aug 19 12:12:30 2013 +0000
- Revision:
- 2:0d8eb41bb976
- Parent:
- 1:6ebd3ac910b6
- Child:
- 3:4ff7fdb41bd2
line led (LPD8806) control
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 |
sfjmt | 2:0d8eb41bb976 | 10 | // DATA -> P5( mosi ) or P11( mosi ) |
sfjmt | 2:0d8eb41bb976 | 11 | // CLOCK -> p7( sclk ) or p13( sclk ) |
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 |
sfjmt | 2:0d8eb41bb976 | 18 | //example...SPI spi(p5, p6, p7); // mosi, miso, sclk (if don't use ... NC(not connected)) |
sfjmt | 2:0d8eb41bb976 | 19 | |
sfjmt | 2:0d8eb41bb976 | 20 | //SPI spi(p5, NC, p7); // mosi, miso, sclk (if don't use ... NC(not connected)) |
sfjmt | 2:0d8eb41bb976 | 21 | SPI spi(p11, NC, p13); // mosi(data), miso, sclk(clock) (if don't use ... NC(not connected)) |
ehbmbed2 | 0:12e734116fea | 22 | |
ehbmbed2 | 0:12e734116fea | 23 | LPD8806::LPD8806(uint16_t n) { |
ehbmbed2 | 0:12e734116fea | 24 | // Allocate 3 bytes per pixel: |
ehbmbed2 | 0:12e734116fea | 25 | if (NULL != (pixels = (uint8_t *)malloc(numLEDs * 3))) { |
ehbmbed2 | 0:12e734116fea | 26 | memset(pixels, 0x80, numLEDs * 3); // Init to RGB 'off' state |
ehbmbed2 | 0:12e734116fea | 27 | numLEDs = n; |
ehbmbed2 | 0:12e734116fea | 28 | } |
ehbmbed2 | 0:12e734116fea | 29 | } |
ehbmbed2 | 0:12e734116fea | 30 | |
ehbmbed2 | 0:12e734116fea | 31 | void LPD8806::begin(void) { |
ehbmbed2 | 0:12e734116fea | 32 | |
ehbmbed2 | 0:12e734116fea | 33 | // Setup the spi for 8 bit data, low steady state clock, |
ehbmbed2 | 0:12e734116fea | 34 | // first edge capture, with a 2MHz clock rate |
sfjmt | 2:0d8eb41bb976 | 35 | // spi.format(8,3); |
sfjmt | 2:0d8eb41bb976 | 36 | // spi.frequency(2000000); |
ehbmbed2 | 0:12e734116fea | 37 | spi.format(8,0); |
ehbmbed2 | 0:12e734116fea | 38 | spi.frequency(2000000); |
sfjmt | 2:0d8eb41bb976 | 39 | // spi2.format(8,0); |
sfjmt | 2:0d8eb41bb976 | 40 | // spi2.frequency(2000000); |
ehbmbed2 | 0:12e734116fea | 41 | |
ehbmbed2 | 0:12e734116fea | 42 | // Issue initial latch to 'wake up' strip (latch length varies w/numLEDs) |
ehbmbed2 | 0:12e734116fea | 43 | writezeros(3 * ((numLEDs + 63) / 64)); |
ehbmbed2 | 0:12e734116fea | 44 | } |
ehbmbed2 | 0:12e734116fea | 45 | |
ehbmbed2 | 0:12e734116fea | 46 | uint16_t LPD8806::numPixels(void) { |
ehbmbed2 | 0:12e734116fea | 47 | return numLEDs; |
ehbmbed2 | 0:12e734116fea | 48 | } |
ehbmbed2 | 0:12e734116fea | 49 | |
ehbmbed2 | 0:12e734116fea | 50 | void LPD8806::writezeros(uint16_t n) { |
sfjmt | 2:0d8eb41bb976 | 51 | while (n--){ |
sfjmt | 2:0d8eb41bb976 | 52 | spi.write(0x00); |
sfjmt | 2:0d8eb41bb976 | 53 | // spi2.write(0x00); |
sfjmt | 2:0d8eb41bb976 | 54 | } |
ehbmbed2 | 0:12e734116fea | 55 | } |
ehbmbed2 | 0:12e734116fea | 56 | |
ehbmbed2 | 0:12e734116fea | 57 | // This is how data is pushed to the strip. Unfortunately, the company |
ehbmbed2 | 0:12e734116fea | 58 | // that makes the chip didnt release the protocol document or you need |
ehbmbed2 | 0:12e734116fea | 59 | // to sign an NDA or something stupid like that, but we reverse engineered |
ehbmbed2 | 0:12e734116fea | 60 | // this from a strip controller and it seems to work very nicely! |
ehbmbed2 | 0:12e734116fea | 61 | void LPD8806::show(void) { |
ehbmbed2 | 0:12e734116fea | 62 | uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED |
ehbmbed2 | 0:12e734116fea | 63 | |
ehbmbed2 | 0:12e734116fea | 64 | for (i=0; i<nl3; i++ ) { |
ehbmbed2 | 0:12e734116fea | 65 | spi.write(pixels[i]); |
sfjmt | 2:0d8eb41bb976 | 66 | // spi2.write(pixels[i]); |
ehbmbed2 | 0:12e734116fea | 67 | } |
ehbmbed2 | 0:12e734116fea | 68 | |
ehbmbed2 | 0:12e734116fea | 69 | // Write latch at end of data; latch length varies with number of LEDs |
ehbmbed2 | 0:12e734116fea | 70 | writezeros(3 * ((numLEDs + 63) / 64)); |
ehbmbed2 | 0:12e734116fea | 71 | |
ehbmbed2 | 0:12e734116fea | 72 | // We need to have a delay here, a few ms seems to do the job |
ehbmbed2 | 0:12e734116fea | 73 | // shorter may be OK as well - need to experiment :( |
ehbmbed2 | 0:12e734116fea | 74 | // wait_ms(3); |
ehbmbed2 | 0:12e734116fea | 75 | } |
ehbmbed2 | 0:12e734116fea | 76 | |
ehbmbed2 | 0:12e734116fea | 77 | // Convert R,G,B to combined 32-bit color |
ehbmbed2 | 0:12e734116fea | 78 | uint32_t LPD8806::Color(uint8_t r, uint8_t g, uint8_t b) { |
ehbmbed2 | 0:12e734116fea | 79 | // Take the lowest 7 bits of each value and append them end to end |
ehbmbed2 | 0:12e734116fea | 80 | // We have the top bit set high (its a 'parity-like' bit in the protocol |
ehbmbed2 | 0:12e734116fea | 81 | // and must be set!) |
ehbmbed2 | 0:12e734116fea | 82 | return 0x808080 | ((uint32_t)g << 16) | ((uint32_t)r << 8) | (uint32_t)b; |
ehbmbed2 | 0:12e734116fea | 83 | } |
ehbmbed2 | 0:12e734116fea | 84 | |
ehbmbed2 | 0:12e734116fea | 85 | // store the rgb component in our array |
ehbmbed2 | 0:12e734116fea | 86 | void LPD8806::setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) { |
ehbmbed2 | 0:12e734116fea | 87 | if (n >= numLEDs) return; // '>=' because arrays are 0-indexed |
ehbmbed2 | 0:12e734116fea | 88 | |
ehbmbed2 | 0:12e734116fea | 89 | pixels[n*3 ] = g | 0x80; |
ehbmbed2 | 0:12e734116fea | 90 | pixels[n*3+1] = r | 0x80; |
ehbmbed2 | 0:12e734116fea | 91 | pixels[n*3+2] = b | 0x80; |
ehbmbed2 | 0:12e734116fea | 92 | } |
ehbmbed2 | 0:12e734116fea | 93 | |
ehbmbed2 | 0:12e734116fea | 94 | void LPD8806::setPixelColor(uint16_t n, uint32_t c) { |
ehbmbed2 | 0:12e734116fea | 95 | if (n >= numLEDs) return; // '>=' because arrays are 0-indexed |
ehbmbed2 | 0:12e734116fea | 96 | |
ehbmbed2 | 0:12e734116fea | 97 | pixels[n*3 ] = (c >> 16) | 0x80; |
ehbmbed2 | 0:12e734116fea | 98 | pixels[n*3+1] = (c >> 8) | 0x80; |
ehbmbed2 | 0:12e734116fea | 99 | pixels[n*3+2] = c | 0x80; |
ehbmbed2 | 0:12e734116fea | 100 | } |