Philip Walne / DotStar

Dependents:   335_project

Fork of DotStar by Hideaki Tai

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DotStar.h Source File

DotStar.h

00001 /*------------------------------------------------------------------------
00002   This file is part of the Adafruit Dot Star library.
00003 
00004   Adafruit Dot Star is free software: you can redistribute it and/or
00005   modify it under the terms of the GNU Lesser General Public License
00006   as published by the Free Software Foundation, either version 3 of
00007   the License, or (at your option) any later version.
00008 
00009   Adafruit Dot Star is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU Lesser General Public License for more details.
00013 
00014   You should have received a copy of the GNU Lesser General Public
00015   License along with DotStar.  If not, see <http://www.gnu.org/licenses/>.
00016   ------------------------------------------------------------------------*/
00017 
00018 #ifndef _ADAFRUIT_DOT_STAR_H_
00019 #define _ADAFRUIT_DOT_STAR_H_
00020 
00021 #include <mbed.h>
00022 
00023 // Color-order flag for LED pixels (optional extra parameter to constructor):
00024 // Bits 0,1 = R index (0-2), bits 2,3 = G index, bits 4,5 = B index
00025 #define DOTSTAR_RGB (0 | (1 << 2) | (2 << 4))
00026 #define DOTSTAR_RBG (0 | (2 << 2) | (1 << 4))
00027 #define DOTSTAR_GRB (1 | (0 << 2) | (2 << 4))
00028 #define DOTSTAR_GBR (2 | (0 << 2) | (1 << 4))
00029 #define DOTSTAR_BRG (1 | (2 << 2) | (0 << 4))
00030 #define DOTSTAR_BGR (2 | (1 << 2) | (0 << 4))
00031 #define DOTSTAR_MONO 0 // Single-color strip WIP DO NOT USE YET
00032 
00033 #define USE_HW_SPI NC // Assign this to dataPin to indicate 'hard' SPI
00034 
00035 
00036 class Adafruit_DotStar {
00037 
00038 public:
00039 
00040     Adafruit_DotStar(uint16_t n, PinName miso, PinName mosi, PinName sclk, int hz = 8000000, uint8_t o=DOTSTAR_BRG);
00041     Adafruit_DotStar(uint16_t n, PinName d, PinName c, uint8_t o=DOTSTAR_BRG);
00042     Adafruit_DotStar(uint16_t n, PortName p, int d_mask, int c_mask, uint8_t o=DOTSTAR_BRG);
00043     ~Adafruit_DotStar(void);
00044    
00045     void begin(void);                            // Prime pins/SPI for output
00046     void clear();                                // Set all pixel data to zero
00047     void setBrightness(uint8_t);                 // Set global brightness 0-255
00048     void setPixelColor(uint16_t n, uint32_t c);
00049     void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b)
00050     {
00051         if(n < numLEDs) {
00052             uint8_t *p = &pixels[n * 3];
00053             p[rOffset] = r;
00054             p[gOffset] = g;
00055             p[bOffset] = b;
00056         }
00057     }
00058     void show(void)                             // Issue color data to strip
00059     {
00060         if(!pixels) return;
00061         
00062         uint8_t *ptr = pixels;            // -> LED data
00063         uint16_t n   = numLEDs;              // Counter
00064         uint16_t b16 = (uint16_t)brightness; // Type-convert for fixed-point math
00065         
00066         if(dataPin == USE_HW_SPI) {
00067           
00068             for(size_t i=0; i<4; i++) spi->write(0x00);    // 4 byte start-frame marker
00069             if(brightness) {                     // Scale pixel brightness on output
00070                 for (size_t i=n; i>0; i--) {
00071                     spi->write(0xFF);                   //  Pixel start
00072                     for(size_t j=0; j<3; j++) spi->write((*ptr++ * b16) >> 8); // Scale, write RGB
00073                 }
00074             } else {                             // Full brightness (no scaling)
00075                 for (size_t i=n; i>0; i--) {
00076                     spi->write(0xFF);                   //  Pixel start
00077                     for(size_t j=0; j<3; j++) spi->write(*ptr++); // Write R,G,B
00078                 }
00079             }
00080             // Four end-frame bytes are seemingly indistinguishable from a white
00081             // pixel, and empirical testing suggests it can be left out...but it's
00082             // always a good idea to follow the datasheet, in case future hardware
00083             // revisions are more strict (e.g. might mandate use of end-frame
00084             // before start-frame marker).  i.e. let's not remove this.
00085             for(size_t i=0; i<4; i++) spi->write(0xFF);
00086         
00087         } else {                               // Soft (bitbang) SPI
00088         
00089             for(size_t i=0; i<4; i++) sw_spi_out(0);    // Start-frame marker
00090             if(brightness) {                     // Scale pixel brightness on output
00091                 do {                               // For each pixel...
00092                     sw_spi_out(0xFF);                //  Pixel start
00093                     for(size_t i=0; i<3; i++) sw_spi_out((*ptr++ * b16) >> 8); // Scale, write
00094                 } while(--n);
00095             } else {                             // Full brightness (no scaling)
00096                 do {                               // For each pixel...
00097                     sw_spi_out(0xFF);                //  Pixel start
00098                     for(size_t i=0; i<3; i++) sw_spi_out(*ptr++); // R,G,B
00099                 } while(--n);
00100             }
00101             for(size_t i=0; i<4; i++) sw_spi_out(0xFF); // End-frame marker (see note above)
00102         }
00103     }
00104     void updatePins(void);                       // Change pin assignments (HW)
00105     void updatePins(PinName d, PinName c);       // Change pin assignments (SW)
00106     void updateLength(uint16_t n);               // Change length
00107     uint32_t Color(uint8_t r, uint8_t g, uint8_t b); // R,G,B to 32-bit color
00108     uint32_t getPixelColor(uint16_t n) const;        // Return 32-bit pixel color
00109     uint16_t numPixels(void);                        // Return number of pixels
00110     uint8_t  getBrightness(void) const;              // Return global brightness
00111     uint8_t* getPixels(void) const;                  // Return pixel data pointer
00112 
00113  private:
00114 
00115     uint16_t numLEDs;                                // Number of pixels
00116     PinName dataPin;                                // If soft SPI, data pin #
00117     PinName clockPin;                               // If soft SPI, clock pin #
00118     SPI* spi;
00119     PinName miso_;
00120     PinName mosi_;
00121     PinName sclk_;
00122     DigitalOut* data_out;
00123     DigitalOut* sclk_out;
00124     PortName port;
00125     PortOut* port_out;
00126     int d_mask;
00127     int c_mask;
00128     bool b_use_port;
00129     uint8_t brightness;                             // Global brightness setting
00130     uint8_t* pixels;                                 // LED RGB values (3 bytes ea.)
00131     uint8_t rOffset;                                // Index of red in 3-byte pixel
00132     uint8_t gOffset;                                // Index of green byte
00133     uint8_t bOffset;                                // Index of blue byte
00134     
00135     void hw_spi_init(void);                      // Start hardware SPI
00136     void hw_spi_end(void);                       // Stop hardware SPI
00137     void sw_spi_init(void);                      // Start bitbang SPI
00138     void sw_spi_end(void);                       // Stop bitbang SPI
00139     inline void sw_spi_out(uint8_t n)                  // Bitbang SPI write
00140     {
00141         if (b_use_port) {
00142             for(uint8_t i=8; i--; n <<= 1) {
00143                 int mask = (n & 0x80) ? (d_mask | c_mask) : c_mask;
00144                 *port_out = mask;
00145                 *port_out = (mask & ~c_mask);
00146             }
00147         } else {
00148             for(uint8_t i=8; i--; n <<= 1) {
00149                 if(n & 0x80) *data_out = 1;
00150                 else         *data_out = 0;
00151                 *sclk_out = 1;
00152                 *sclk_out = 0;
00153             }
00154         }
00155     }
00156     
00157 };
00158 
00159 #endif // _ADAFRUIT_DOT_STAR_H_