The port of adafruit dotstar library for arduino https://github.com/adafruit/Adafruit_DotStar
Fork of DotStar by
DotStar.h@2:51722225d46c, 2017-01-04 (annotated)
- Committer:
- pwalne
- Date:
- Wed Jan 04 20:53:35 2017 +0000
- Revision:
- 2:51722225d46c
- Parent:
- 1:d09c288b8eb3
Changes for mbed LPC1768
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hideakitai | 0:bae97ff743a6 | 1 | /*------------------------------------------------------------------------ |
hideakitai | 0:bae97ff743a6 | 2 | This file is part of the Adafruit Dot Star library. |
hideakitai | 0:bae97ff743a6 | 3 | |
hideakitai | 0:bae97ff743a6 | 4 | Adafruit Dot Star is free software: you can redistribute it and/or |
hideakitai | 0:bae97ff743a6 | 5 | modify it under the terms of the GNU Lesser General Public License |
hideakitai | 0:bae97ff743a6 | 6 | as published by the Free Software Foundation, either version 3 of |
hideakitai | 0:bae97ff743a6 | 7 | the License, or (at your option) any later version. |
hideakitai | 0:bae97ff743a6 | 8 | |
hideakitai | 0:bae97ff743a6 | 9 | Adafruit Dot Star is distributed in the hope that it will be useful, |
hideakitai | 0:bae97ff743a6 | 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
hideakitai | 0:bae97ff743a6 | 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
hideakitai | 0:bae97ff743a6 | 12 | GNU Lesser General Public License for more details. |
hideakitai | 0:bae97ff743a6 | 13 | |
hideakitai | 0:bae97ff743a6 | 14 | You should have received a copy of the GNU Lesser General Public |
hideakitai | 0:bae97ff743a6 | 15 | License along with DotStar. If not, see <http://www.gnu.org/licenses/>. |
hideakitai | 0:bae97ff743a6 | 16 | ------------------------------------------------------------------------*/ |
hideakitai | 0:bae97ff743a6 | 17 | |
hideakitai | 0:bae97ff743a6 | 18 | #ifndef _ADAFRUIT_DOT_STAR_H_ |
hideakitai | 0:bae97ff743a6 | 19 | #define _ADAFRUIT_DOT_STAR_H_ |
hideakitai | 0:bae97ff743a6 | 20 | |
hideakitai | 0:bae97ff743a6 | 21 | #include <mbed.h> |
hideakitai | 0:bae97ff743a6 | 22 | |
hideakitai | 0:bae97ff743a6 | 23 | // Color-order flag for LED pixels (optional extra parameter to constructor): |
hideakitai | 0:bae97ff743a6 | 24 | // Bits 0,1 = R index (0-2), bits 2,3 = G index, bits 4,5 = B index |
hideakitai | 0:bae97ff743a6 | 25 | #define DOTSTAR_RGB (0 | (1 << 2) | (2 << 4)) |
hideakitai | 0:bae97ff743a6 | 26 | #define DOTSTAR_RBG (0 | (2 << 2) | (1 << 4)) |
hideakitai | 0:bae97ff743a6 | 27 | #define DOTSTAR_GRB (1 | (0 << 2) | (2 << 4)) |
hideakitai | 0:bae97ff743a6 | 28 | #define DOTSTAR_GBR (2 | (0 << 2) | (1 << 4)) |
hideakitai | 0:bae97ff743a6 | 29 | #define DOTSTAR_BRG (1 | (2 << 2) | (0 << 4)) |
hideakitai | 0:bae97ff743a6 | 30 | #define DOTSTAR_BGR (2 | (1 << 2) | (0 << 4)) |
hideakitai | 0:bae97ff743a6 | 31 | #define DOTSTAR_MONO 0 // Single-color strip WIP DO NOT USE YET |
hideakitai | 0:bae97ff743a6 | 32 | |
hideakitai | 1:d09c288b8eb3 | 33 | #define USE_HW_SPI NC // Assign this to dataPin to indicate 'hard' SPI |
hideakitai | 1:d09c288b8eb3 | 34 | |
hideakitai | 1:d09c288b8eb3 | 35 | |
hideakitai | 0:bae97ff743a6 | 36 | class Adafruit_DotStar { |
hideakitai | 0:bae97ff743a6 | 37 | |
hideakitai | 1:d09c288b8eb3 | 38 | public: |
hideakitai | 0:bae97ff743a6 | 39 | |
hideakitai | 1:d09c288b8eb3 | 40 | Adafruit_DotStar(uint16_t n, PinName miso, PinName mosi, PinName sclk, int hz = 8000000, uint8_t o=DOTSTAR_BRG); |
hideakitai | 1:d09c288b8eb3 | 41 | Adafruit_DotStar(uint16_t n, PinName d, PinName c, uint8_t o=DOTSTAR_BRG); |
hideakitai | 1:d09c288b8eb3 | 42 | Adafruit_DotStar(uint16_t n, PortName p, int d_mask, int c_mask, uint8_t o=DOTSTAR_BRG); |
hideakitai | 1:d09c288b8eb3 | 43 | ~Adafruit_DotStar(void); |
hideakitai | 1:d09c288b8eb3 | 44 | |
hideakitai | 1:d09c288b8eb3 | 45 | void begin(void); // Prime pins/SPI for output |
hideakitai | 1:d09c288b8eb3 | 46 | void clear(); // Set all pixel data to zero |
hideakitai | 1:d09c288b8eb3 | 47 | void setBrightness(uint8_t); // Set global brightness 0-255 |
hideakitai | 1:d09c288b8eb3 | 48 | void setPixelColor(uint16_t n, uint32_t c); |
hideakitai | 1:d09c288b8eb3 | 49 | void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b) |
hideakitai | 1:d09c288b8eb3 | 50 | { |
hideakitai | 1:d09c288b8eb3 | 51 | if(n < numLEDs) { |
hideakitai | 1:d09c288b8eb3 | 52 | uint8_t *p = &pixels[n * 3]; |
hideakitai | 1:d09c288b8eb3 | 53 | p[rOffset] = r; |
hideakitai | 1:d09c288b8eb3 | 54 | p[gOffset] = g; |
hideakitai | 1:d09c288b8eb3 | 55 | p[bOffset] = b; |
hideakitai | 1:d09c288b8eb3 | 56 | } |
hideakitai | 1:d09c288b8eb3 | 57 | } |
hideakitai | 1:d09c288b8eb3 | 58 | void show(void) // Issue color data to strip |
hideakitai | 1:d09c288b8eb3 | 59 | { |
hideakitai | 1:d09c288b8eb3 | 60 | if(!pixels) return; |
hideakitai | 1:d09c288b8eb3 | 61 | |
hideakitai | 1:d09c288b8eb3 | 62 | uint8_t *ptr = pixels; // -> LED data |
hideakitai | 1:d09c288b8eb3 | 63 | uint16_t n = numLEDs; // Counter |
hideakitai | 1:d09c288b8eb3 | 64 | uint16_t b16 = (uint16_t)brightness; // Type-convert for fixed-point math |
hideakitai | 1:d09c288b8eb3 | 65 | |
hideakitai | 1:d09c288b8eb3 | 66 | if(dataPin == USE_HW_SPI) { |
hideakitai | 1:d09c288b8eb3 | 67 | |
hideakitai | 1:d09c288b8eb3 | 68 | for(size_t i=0; i<4; i++) spi->write(0x00); // 4 byte start-frame marker |
hideakitai | 1:d09c288b8eb3 | 69 | if(brightness) { // Scale pixel brightness on output |
hideakitai | 1:d09c288b8eb3 | 70 | for (size_t i=n; i>0; i--) { |
hideakitai | 1:d09c288b8eb3 | 71 | spi->write(0xFF); // Pixel start |
hideakitai | 1:d09c288b8eb3 | 72 | for(size_t j=0; j<3; j++) spi->write((*ptr++ * b16) >> 8); // Scale, write RGB |
hideakitai | 1:d09c288b8eb3 | 73 | } |
hideakitai | 1:d09c288b8eb3 | 74 | } else { // Full brightness (no scaling) |
hideakitai | 1:d09c288b8eb3 | 75 | for (size_t i=n; i>0; i--) { |
hideakitai | 1:d09c288b8eb3 | 76 | spi->write(0xFF); // Pixel start |
hideakitai | 1:d09c288b8eb3 | 77 | for(size_t j=0; j<3; j++) spi->write(*ptr++); // Write R,G,B |
hideakitai | 1:d09c288b8eb3 | 78 | } |
hideakitai | 1:d09c288b8eb3 | 79 | } |
hideakitai | 1:d09c288b8eb3 | 80 | // Four end-frame bytes are seemingly indistinguishable from a white |
hideakitai | 1:d09c288b8eb3 | 81 | // pixel, and empirical testing suggests it can be left out...but it's |
hideakitai | 1:d09c288b8eb3 | 82 | // always a good idea to follow the datasheet, in case future hardware |
hideakitai | 1:d09c288b8eb3 | 83 | // revisions are more strict (e.g. might mandate use of end-frame |
hideakitai | 1:d09c288b8eb3 | 84 | // before start-frame marker). i.e. let's not remove this. |
hideakitai | 1:d09c288b8eb3 | 85 | for(size_t i=0; i<4; i++) spi->write(0xFF); |
hideakitai | 1:d09c288b8eb3 | 86 | |
hideakitai | 1:d09c288b8eb3 | 87 | } else { // Soft (bitbang) SPI |
hideakitai | 1:d09c288b8eb3 | 88 | |
hideakitai | 1:d09c288b8eb3 | 89 | for(size_t i=0; i<4; i++) sw_spi_out(0); // Start-frame marker |
hideakitai | 1:d09c288b8eb3 | 90 | if(brightness) { // Scale pixel brightness on output |
hideakitai | 1:d09c288b8eb3 | 91 | do { // For each pixel... |
hideakitai | 1:d09c288b8eb3 | 92 | sw_spi_out(0xFF); // Pixel start |
hideakitai | 1:d09c288b8eb3 | 93 | for(size_t i=0; i<3; i++) sw_spi_out((*ptr++ * b16) >> 8); // Scale, write |
hideakitai | 1:d09c288b8eb3 | 94 | } while(--n); |
hideakitai | 1:d09c288b8eb3 | 95 | } else { // Full brightness (no scaling) |
hideakitai | 1:d09c288b8eb3 | 96 | do { // For each pixel... |
hideakitai | 1:d09c288b8eb3 | 97 | sw_spi_out(0xFF); // Pixel start |
hideakitai | 1:d09c288b8eb3 | 98 | for(size_t i=0; i<3; i++) sw_spi_out(*ptr++); // R,G,B |
hideakitai | 1:d09c288b8eb3 | 99 | } while(--n); |
hideakitai | 1:d09c288b8eb3 | 100 | } |
hideakitai | 1:d09c288b8eb3 | 101 | for(size_t i=0; i<4; i++) sw_spi_out(0xFF); // End-frame marker (see note above) |
hideakitai | 1:d09c288b8eb3 | 102 | } |
hideakitai | 1:d09c288b8eb3 | 103 | } |
hideakitai | 1:d09c288b8eb3 | 104 | void updatePins(void); // Change pin assignments (HW) |
hideakitai | 1:d09c288b8eb3 | 105 | void updatePins(PinName d, PinName c); // Change pin assignments (SW) |
hideakitai | 1:d09c288b8eb3 | 106 | void updateLength(uint16_t n); // Change length |
hideakitai | 1:d09c288b8eb3 | 107 | uint32_t Color(uint8_t r, uint8_t g, uint8_t b); // R,G,B to 32-bit color |
hideakitai | 1:d09c288b8eb3 | 108 | uint32_t getPixelColor(uint16_t n) const; // Return 32-bit pixel color |
hideakitai | 1:d09c288b8eb3 | 109 | uint16_t numPixels(void); // Return number of pixels |
hideakitai | 1:d09c288b8eb3 | 110 | uint8_t getBrightness(void) const; // Return global brightness |
hideakitai | 1:d09c288b8eb3 | 111 | uint8_t* getPixels(void) const; // Return pixel data pointer |
hideakitai | 0:bae97ff743a6 | 112 | |
hideakitai | 0:bae97ff743a6 | 113 | private: |
hideakitai | 0:bae97ff743a6 | 114 | |
hideakitai | 1:d09c288b8eb3 | 115 | uint16_t numLEDs; // Number of pixels |
hideakitai | 1:d09c288b8eb3 | 116 | PinName dataPin; // If soft SPI, data pin # |
hideakitai | 1:d09c288b8eb3 | 117 | PinName clockPin; // If soft SPI, clock pin # |
hideakitai | 1:d09c288b8eb3 | 118 | SPI* spi; |
hideakitai | 1:d09c288b8eb3 | 119 | PinName miso_; |
hideakitai | 1:d09c288b8eb3 | 120 | PinName mosi_; |
hideakitai | 1:d09c288b8eb3 | 121 | PinName sclk_; |
hideakitai | 1:d09c288b8eb3 | 122 | DigitalOut* data_out; |
hideakitai | 1:d09c288b8eb3 | 123 | DigitalOut* sclk_out; |
hideakitai | 1:d09c288b8eb3 | 124 | PortName port; |
hideakitai | 1:d09c288b8eb3 | 125 | PortOut* port_out; |
hideakitai | 1:d09c288b8eb3 | 126 | int d_mask; |
hideakitai | 1:d09c288b8eb3 | 127 | int c_mask; |
hideakitai | 1:d09c288b8eb3 | 128 | bool b_use_port; |
hideakitai | 1:d09c288b8eb3 | 129 | uint8_t brightness; // Global brightness setting |
hideakitai | 1:d09c288b8eb3 | 130 | uint8_t* pixels; // LED RGB values (3 bytes ea.) |
hideakitai | 1:d09c288b8eb3 | 131 | uint8_t rOffset; // Index of red in 3-byte pixel |
hideakitai | 1:d09c288b8eb3 | 132 | uint8_t gOffset; // Index of green byte |
hideakitai | 1:d09c288b8eb3 | 133 | uint8_t bOffset; // Index of blue byte |
hideakitai | 1:d09c288b8eb3 | 134 | |
hideakitai | 1:d09c288b8eb3 | 135 | void hw_spi_init(void); // Start hardware SPI |
hideakitai | 1:d09c288b8eb3 | 136 | void hw_spi_end(void); // Stop hardware SPI |
hideakitai | 1:d09c288b8eb3 | 137 | void sw_spi_init(void); // Start bitbang SPI |
hideakitai | 1:d09c288b8eb3 | 138 | void sw_spi_end(void); // Stop bitbang SPI |
hideakitai | 1:d09c288b8eb3 | 139 | inline void sw_spi_out(uint8_t n) // Bitbang SPI write |
hideakitai | 1:d09c288b8eb3 | 140 | { |
hideakitai | 1:d09c288b8eb3 | 141 | if (b_use_port) { |
hideakitai | 1:d09c288b8eb3 | 142 | for(uint8_t i=8; i--; n <<= 1) { |
hideakitai | 1:d09c288b8eb3 | 143 | int mask = (n & 0x80) ? (d_mask | c_mask) : c_mask; |
hideakitai | 1:d09c288b8eb3 | 144 | *port_out = mask; |
hideakitai | 1:d09c288b8eb3 | 145 | *port_out = (mask & ~c_mask); |
hideakitai | 1:d09c288b8eb3 | 146 | } |
hideakitai | 1:d09c288b8eb3 | 147 | } else { |
hideakitai | 1:d09c288b8eb3 | 148 | for(uint8_t i=8; i--; n <<= 1) { |
hideakitai | 1:d09c288b8eb3 | 149 | if(n & 0x80) *data_out = 1; |
hideakitai | 1:d09c288b8eb3 | 150 | else *data_out = 0; |
hideakitai | 1:d09c288b8eb3 | 151 | *sclk_out = 1; |
hideakitai | 1:d09c288b8eb3 | 152 | *sclk_out = 0; |
hideakitai | 1:d09c288b8eb3 | 153 | } |
hideakitai | 1:d09c288b8eb3 | 154 | } |
hideakitai | 1:d09c288b8eb3 | 155 | } |
hideakitai | 1:d09c288b8eb3 | 156 | |
hideakitai | 0:bae97ff743a6 | 157 | }; |
hideakitai | 0:bae97ff743a6 | 158 | |
hideakitai | 0:bae97ff743a6 | 159 | #endif // _ADAFRUIT_DOT_STAR_H_ |