The port of adafruit dotstar library for arduino https://github.com/adafruit/Adafruit_DotStar
Diff: DotStar.h
- Revision:
- 1:d09c288b8eb3
- Parent:
- 0:bae97ff743a6
--- 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_