The port of adafruit dotstar library for arduino https://github.com/adafruit/Adafruit_DotStar

Committer:
hideakitai
Date:
Wed Apr 06 08:49:21 2016 +0000
Revision:
1:d09c288b8eb3
Parent:
0:bae97ff743a6
support SPI, PortOut

Who changed what in which revision?

UserRevisionLine numberNew 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_