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

Revision:
1:d09c288b8eb3
Parent:
0:bae97ff743a6
diff -r bae97ff743a6 -r d09c288b8eb3 DotStar.h
--- a/DotStar.h	Fri Mar 25 07:41:51 2016 +0000
+++ b/DotStar.h	Wed Apr 06 08:49:21 2016 +0000
@@ -30,51 +30,130 @@
 #define DOTSTAR_BGR (2 | (1 << 2) | (0 << 4))
 #define DOTSTAR_MONO 0 // Single-color strip WIP DO NOT USE YET
 
+#define USE_HW_SPI NC // Assign this to dataPin to indicate 'hard' SPI
+
+
 class Adafruit_DotStar {
 
- public:
+public:
 
-    Adafruit_DotStar(uint16_t n, uint8_t o=DOTSTAR_BRG);
-    Adafruit_DotStar(uint16_t n, uint8_t d, uint8_t c, uint8_t o=DOTSTAR_BRG);
-   ~Adafruit_DotStar(void);
-  void
-    begin(void),                            // Prime pins/SPI for output
-    clear(),                                // Set all pixel data to zero
-    setBrightness(uint8_t),                 // Set global brightness 0-255
-    setPixelColor(uint16_t n, uint32_t c),
-    setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b),
-    show(void),                             // Issue color data to strip
-    // updatePins(void),                       // Change pin assignments (HW)
-    // updatePins(uint8_t d, uint8_t c),       // Change pin assignments (SW)
-    updateLength(uint16_t n);               // Change length
-  uint32_t
-    Color(uint8_t r, uint8_t g, uint8_t b), // R,G,B to 32-bit color
-    getPixelColor(uint16_t n) const;        // Return 32-bit pixel color
-  uint16_t
-    numPixels(void);                        // Return number of pixels
-  uint8_t
-    getBrightness(void) const,              // Return global brightness
-   *getPixels(void) const;                  // Return pixel data pointer
+    Adafruit_DotStar(uint16_t n, PinName miso, PinName mosi, PinName sclk, int hz = 8000000, uint8_t o=DOTSTAR_BRG);
+    Adafruit_DotStar(uint16_t n, PinName d, PinName c, uint8_t o=DOTSTAR_BRG);
+    Adafruit_DotStar(uint16_t n, PortName p, int d_mask, int c_mask, uint8_t o=DOTSTAR_BRG);
+    ~Adafruit_DotStar(void);
+   
+    void begin(void);                            // Prime pins/SPI for output
+    void clear();                                // Set all pixel data to zero
+    void setBrightness(uint8_t);                 // Set global brightness 0-255
+    void setPixelColor(uint16_t n, uint32_t c);
+    void setPixelColor(uint16_t n, uint8_t r, uint8_t g, uint8_t b)
+    {
+        if(n < numLEDs) {
+            uint8_t *p = &pixels[n * 3];
+            p[rOffset] = r;
+            p[gOffset] = g;
+            p[bOffset] = b;
+        }
+    }
+    void show(void)                             // Issue color data to strip
+    {
+        if(!pixels) return;
+        
+        uint8_t *ptr = pixels;            // -> LED data
+        uint16_t n   = numLEDs;              // Counter
+        uint16_t b16 = (uint16_t)brightness; // Type-convert for fixed-point math
+        
+        if(dataPin == USE_HW_SPI) {
+          
+            for(size_t i=0; i<4; i++) spi->write(0x00);    // 4 byte start-frame marker
+            if(brightness) {                     // Scale pixel brightness on output
+                for (size_t i=n; i>0; i--) {
+                    spi->write(0xFF);                   //  Pixel start
+                    for(size_t j=0; j<3; j++) spi->write((*ptr++ * b16) >> 8); // Scale, write RGB
+                }
+            } else {                             // Full brightness (no scaling)
+                for (size_t i=n; i>0; i--) {
+                    spi->write(0xFF);                   //  Pixel start
+                    for(size_t j=0; j<3; j++) spi->write(*ptr++); // Write R,G,B
+                }
+            }
+            // Four end-frame bytes are seemingly indistinguishable from a white
+            // pixel, and empirical testing suggests it can be left out...but it's
+            // always a good idea to follow the datasheet, in case future hardware
+            // revisions are more strict (e.g. might mandate use of end-frame
+            // before start-frame marker).  i.e. let's not remove this.
+            for(size_t i=0; i<4; i++) spi->write(0xFF);
+        
+        } else {                               // Soft (bitbang) SPI
+        
+            for(size_t i=0; i<4; i++) sw_spi_out(0);    // Start-frame marker
+            if(brightness) {                     // Scale pixel brightness on output
+                do {                               // For each pixel...
+                    sw_spi_out(0xFF);                //  Pixel start
+                    for(size_t i=0; i<3; i++) sw_spi_out((*ptr++ * b16) >> 8); // Scale, write
+                } while(--n);
+            } else {                             // Full brightness (no scaling)
+                do {                               // For each pixel...
+                    sw_spi_out(0xFF);                //  Pixel start
+                    for(size_t i=0; i<3; i++) sw_spi_out(*ptr++); // R,G,B
+                } while(--n);
+            }
+            for(size_t i=0; i<4; i++) sw_spi_out(0xFF); // End-frame marker (see note above)
+        }
+    }
+    void updatePins(void);                       // Change pin assignments (HW)
+    void updatePins(PinName d, PinName c);       // Change pin assignments (SW)
+    void updateLength(uint16_t n);               // Change length
+    uint32_t Color(uint8_t r, uint8_t g, uint8_t b); // R,G,B to 32-bit color
+    uint32_t getPixelColor(uint16_t n) const;        // Return 32-bit pixel color
+    uint16_t numPixels(void);                        // Return number of pixels
+    uint8_t  getBrightness(void) const;              // Return global brightness
+    uint8_t* getPixels(void) const;                  // Return pixel data pointer
 
  private:
 
-  uint16_t
-    numLEDs;                                // Number of pixels
-  uint8_t
-    dataPin,                                // If soft SPI, data pin #
-    clockPin,                               // If soft SPI, clock pin #
-    brightness,                             // Global brightness setting
-   *pixels,                                 // LED RGB values (3 bytes ea.)
-    rOffset,                                // Index of red in 3-byte pixel
-    gOffset,                                // Index of green byte
-    bOffset;                                // Index of blue byte
-  void
-    hw_spi_init(void),                      // Start hardware SPI
-    hw_spi_end(void);                       // Stop hardware SPI
-    // sw_spi_init(void),                      // Start bitbang SPI
-    // sw_spi_out(uint8_t n),                  // Bitbang SPI write
-    // sw_spi_end(void);                       // Stop bitbang SPI
-
+    uint16_t numLEDs;                                // Number of pixels
+    PinName dataPin;                                // If soft SPI, data pin #
+    PinName clockPin;                               // If soft SPI, clock pin #
+    SPI* spi;
+    PinName miso_;
+    PinName mosi_;
+    PinName sclk_;
+    DigitalOut* data_out;
+    DigitalOut* sclk_out;
+    PortName port;
+    PortOut* port_out;
+    int d_mask;
+    int c_mask;
+    bool b_use_port;
+    uint8_t brightness;                             // Global brightness setting
+    uint8_t* pixels;                                 // LED RGB values (3 bytes ea.)
+    uint8_t rOffset;                                // Index of red in 3-byte pixel
+    uint8_t gOffset;                                // Index of green byte
+    uint8_t bOffset;                                // Index of blue byte
+    
+    void hw_spi_init(void);                      // Start hardware SPI
+    void hw_spi_end(void);                       // Stop hardware SPI
+    void sw_spi_init(void);                      // Start bitbang SPI
+    void sw_spi_end(void);                       // Stop bitbang SPI
+    inline void sw_spi_out(uint8_t n)                  // Bitbang SPI write
+    {
+        if (b_use_port) {
+            for(uint8_t i=8; i--; n <<= 1) {
+                int mask = (n & 0x80) ? (d_mask | c_mask) : c_mask;
+                *port_out = mask;
+                *port_out = (mask & ~c_mask);
+            }
+        } else {
+            for(uint8_t i=8; i--; n <<= 1) {
+                if(n & 0x80) *data_out = 1;
+                else         *data_out = 0;
+                *sclk_out = 1;
+                *sclk_out = 0;
+            }
+        }
+    }
+    
 };
 
 #endif // _ADAFRUIT_DOT_STAR_H_