Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SD600A by
LPD8806.cpp@2:af5af64e114d, 2012-09-16 (annotated)
- Committer:
- heroic
- Date:
- Sun Sep 16 13:09:54 2012 +0000
- Revision:
- 2:af5af64e114d
- Parent:
- 1:6ebd3ac910b6
- Child:
- 3:a415f73507c9
Add extra functions and parameterize; support software SPI.
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 | // |
heroic | 2:af5af64e114d | 8 | // Parameterized and modified to use soft SPI. |
heroic | 2:af5af64e114d | 9 | // Jas Strong <jasmine@electronpusher.org> |
ehbmbed2 | 0:12e734116fea | 10 | /*****************************************************************************/ |
ehbmbed2 | 0:12e734116fea | 11 | |
ehbmbed2 | 0:12e734116fea | 12 | #include "LPD8806.h" |
ehbmbed2 | 0:12e734116fea | 13 | |
heroic | 2:af5af64e114d | 14 | LPD8806::LPD8806(PinName dataPin, PinName clockPin, int n) : |
heroic | 2:af5af64e114d | 15 | dat(dataPin), |
heroic | 2:af5af64e114d | 16 | clk(clockPin) { |
ehbmbed2 | 0:12e734116fea | 17 | // Allocate 3 bytes per pixel: |
heroic | 2:af5af64e114d | 18 | numLEDs = n; |
ehbmbed2 | 0:12e734116fea | 19 | if (NULL != (pixels = (uint8_t *)malloc(numLEDs * 3))) { |
ehbmbed2 | 0:12e734116fea | 20 | memset(pixels, 0x80, numLEDs * 3); // Init to RGB 'off' state |
ehbmbed2 | 0:12e734116fea | 21 | } |
ehbmbed2 | 0:12e734116fea | 22 | } |
ehbmbed2 | 0:12e734116fea | 23 | |
heroic | 2:af5af64e114d | 24 | /* |
heroic | 2:af5af64e114d | 25 | * Soft SPI clock-out implementation (CPOL = 0, CPHA = 0). |
heroic | 2:af5af64e114d | 26 | * Certainly not the fastest in the world but it'll do. |
heroic | 2:af5af64e114d | 27 | * Gets about 3.6 MHz; could get several times as much |
heroic | 2:af5af64e114d | 28 | * using the bitbands directly - jas. |
heroic | 2:af5af64e114d | 29 | */ |
heroic | 2:af5af64e114d | 30 | |
heroic | 2:af5af64e114d | 31 | void LPD8806::write(uint8_t byte) { |
heroic | 2:af5af64e114d | 32 | for (int i=0; i<8; i++) { |
heroic | 2:af5af64e114d | 33 | clk = 0; |
heroic | 2:af5af64e114d | 34 | dat = (byte & 0x80); |
heroic | 2:af5af64e114d | 35 | clk = 1; |
heroic | 2:af5af64e114d | 36 | byte <<= 1; |
heroic | 2:af5af64e114d | 37 | } |
heroic | 2:af5af64e114d | 38 | clk = 0; |
heroic | 2:af5af64e114d | 39 | } |
ehbmbed2 | 0:12e734116fea | 40 | |
heroic | 2:af5af64e114d | 41 | void LPD8806::begin(void) { |
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) { |
heroic | 2:af5af64e114d | 52 | while (n--) write(0x00); |
heroic | 2:af5af64e114d | 53 | } |
heroic | 2:af5af64e114d | 54 | |
heroic | 2:af5af64e114d | 55 | void LPD8806::blank(void) { |
heroic | 2:af5af64e114d | 56 | memset(pixels, 0x80, numLEDs * 3); |
ehbmbed2 | 0:12e734116fea | 57 | } |
ehbmbed2 | 0:12e734116fea | 58 | |
ehbmbed2 | 0:12e734116fea | 59 | // This is how data is pushed to the strip. Unfortunately, the company |
ehbmbed2 | 0:12e734116fea | 60 | // that makes the chip didnt release the protocol document or you need |
ehbmbed2 | 0:12e734116fea | 61 | // to sign an NDA or something stupid like that, but we reverse engineered |
ehbmbed2 | 0:12e734116fea | 62 | // this from a strip controller and it seems to work very nicely! |
ehbmbed2 | 0:12e734116fea | 63 | void LPD8806::show(void) { |
ehbmbed2 | 0:12e734116fea | 64 | uint16_t i, nl3 = numLEDs * 3; // 3 bytes per LED |
ehbmbed2 | 0:12e734116fea | 65 | |
ehbmbed2 | 0:12e734116fea | 66 | for (i=0; i<nl3; i++ ) { |
heroic | 2:af5af64e114d | 67 | write(pixels[i]); |
ehbmbed2 | 0:12e734116fea | 68 | } |
ehbmbed2 | 0:12e734116fea | 69 | |
ehbmbed2 | 0:12e734116fea | 70 | // Write latch at end of data; latch length varies with number of LEDs |
ehbmbed2 | 0:12e734116fea | 71 | writezeros(3 * ((numLEDs + 63) / 64)); |
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 | |
ehbmbed2 | 0:12e734116fea | 86 | pixels[n*3 ] = g | 0x80; |
ehbmbed2 | 0:12e734116fea | 87 | pixels[n*3+1] = r | 0x80; |
ehbmbed2 | 0:12e734116fea | 88 | pixels[n*3+2] = b | 0x80; |
ehbmbed2 | 0:12e734116fea | 89 | } |
ehbmbed2 | 0:12e734116fea | 90 | |
heroic | 2:af5af64e114d | 91 | void LPD8806::setPixelGB(uint16_t n, uint8_t g, uint8_t b) { |
heroic | 2:af5af64e114d | 92 | if (n >= numLEDs) return; // '>=' because arrays are 0-indexed |
heroic | 2:af5af64e114d | 93 | |
heroic | 2:af5af64e114d | 94 | pixels[n*3 ] = g | 0x80; |
heroic | 2:af5af64e114d | 95 | pixels[n*3+2] = b | 0x80; |
heroic | 2:af5af64e114d | 96 | } |
heroic | 2:af5af64e114d | 97 | |
heroic | 2:af5af64e114d | 98 | void LPD8806::setPixelR(uint16_t n, uint8_t r) { |
heroic | 2:af5af64e114d | 99 | if (n >= numLEDs) return; // '>=' because arrays are 0-indexed |
heroic | 2:af5af64e114d | 100 | |
heroic | 2:af5af64e114d | 101 | pixels[n*3+1] = r | 0x80; |
heroic | 2:af5af64e114d | 102 | } |
heroic | 2:af5af64e114d | 103 | |
heroic | 2:af5af64e114d | 104 | void LPD8806::setPixelG(uint16_t n, uint8_t g) { |
heroic | 2:af5af64e114d | 105 | if (n >= numLEDs) return; // '>=' because arrays are 0-indexed |
heroic | 2:af5af64e114d | 106 | |
heroic | 2:af5af64e114d | 107 | pixels[n*3] = g | 0x80; |
heroic | 2:af5af64e114d | 108 | } |
heroic | 2:af5af64e114d | 109 | |
heroic | 2:af5af64e114d | 110 | void LPD8806::setPixelB(uint16_t n, uint8_t b) { |
heroic | 2:af5af64e114d | 111 | if (n >= numLEDs) return; // '>=' because arrays are 0-indexed |
heroic | 2:af5af64e114d | 112 | |
heroic | 2:af5af64e114d | 113 | pixels[n*3+2] = b | 0x80; |
heroic | 2:af5af64e114d | 114 | } |
heroic | 2:af5af64e114d | 115 | |
ehbmbed2 | 0:12e734116fea | 116 | void LPD8806::setPixelColor(uint16_t n, uint32_t c) { |
ehbmbed2 | 0:12e734116fea | 117 | if (n >= numLEDs) return; // '>=' because arrays are 0-indexed |
ehbmbed2 | 0:12e734116fea | 118 | |
ehbmbed2 | 0:12e734116fea | 119 | pixels[n*3 ] = (c >> 16) | 0x80; |
ehbmbed2 | 0:12e734116fea | 120 | pixels[n*3+1] = (c >> 8) | 0x80; |
ehbmbed2 | 0:12e734116fea | 121 | pixels[n*3+2] = c | 0x80; |
ehbmbed2 | 0:12e734116fea | 122 | } |