share

Dependencies:   RotationMat_ SDFileSystem math mbed trigonometric_fanc

Adafruit_DotStar.h

Committer:
shuhei2306
Date:
2016-02-08
Revision:
3:5b09187939a2
Parent:
2:b09caaa3de96

File content as of revision 3:5b09187939a2:

#include "mbed.h"

// Color-order flag for LED pixels (optional extra parameter to constructor):
// Bits 0,1 = R index (0-2), bits 2,3 = G index, bits 4,5 = B index
#define DOTSTAR_BGR (0 | (1 << 2) | (2 << 4))
#define DOTSTAR_GBR (0 | (2 << 2) | (1 << 4))
#define DOTSTAR_BRG (1 | (0 << 2) | (2 << 4))
#define DOTSTAR_RBG (2 | (0 << 2) | (1 << 4))
#define DOTSTAR_GRB (1 | (2 << 2) | (0 << 4))
#define DOTSTAR_RGB (2 | (1 << 2) | (0 << 4))
#define DOTSTAR_MONO 0 // Single-color strip WIP DO NOT USE YET
SPI spi(p5,p6,p7);

class Adafruit_DotStar
{

public:
  
    Adafruit_DotStar(uint16_t n, uint8_t o=DOTSTAR_RGB);
    ~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
          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

private:

    uint16_t
    numLEDs;                                // Number of pixels
    uint8_t
    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
    spi_init(void);
};

Adafruit_DotStar::Adafruit_DotStar(uint16_t n, uint8_t o):
    brightness(0), pixels(NULL),
    rOffset(o & 3), gOffset((o >> 2) & 3), bOffset((o >> 4) & 3)
{
    updateLength(n);
}

Adafruit_DotStar::~Adafruit_DotStar(void)   // Destructor
{
    if(pixels)                delete[] pixels;
}

void Adafruit_DotStar::begin(void)   // Initialize SPI
{
    spi_init();
}

void Adafruit_DotStar::updateLength(uint16_t n)
{
    if(pixels) delete[] pixels;
    uint16_t bytes = (rOffset == gOffset) ?
                     n + ((n + 3) / 4) : // MONO: 10 bits/pixel, round up to next byte
                     n * 3;              // COLOR: 3 bytes/pixel
    if(pixels = new uint8_t[bytes]) {
        numLEDs = n;
        clear();
    } else {
        numLEDs = 0;
    }
}

// SPI STUFF ---------------------------------------------------------------
void Adafruit_DotStar::spi_init(void)
{
    // Setup the spi for 8 bit data,
    // second edge capture, with a 1MHz clock rate
    spi.format(8, 0); // mode0 POL:positive PHA:ラッチ先行
    spi.frequency(12000000);
 //   spi.frequency(1000000);
}

void Adafruit_DotStar::show(void)
{

    if(!pixels) return;

    uint8_t *ptr = pixels, i;            // -> LED data
    uint16_t n   = numLEDs;              // Counter
    uint16_t b16 = (uint16_t)brightness; // Type-convert for fixed-point math

    for(i=0; i<4; i++) spi.write(0);    // Start-frame marker
    if(brightness) {                     // Scale pixel brightness on output
        do {                               // For each pixel...
            spi.write(0xFF);                //  Pixel start
            for(i=0; i<3; i++) spi.write((*ptr++ * b16) >> 8); // Scale, write
        } while(--n);
    } else {                             // Full brightness (no scaling)
        do {                               // For each pixel...
            spi.write(0xFF);    //  Pixel start
            for(i=0; i<3; i++) spi.write(*ptr++); // R,G,B
        } while(--n);
    }
    for(i=0; i<4; i++) spi.write(0xFF); // End-frame marker (see note above)

}

void Adafruit_DotStar::clear()   // Write 0s (off) to full pixel buffer
{
    memset(pixels, 0, (rOffset == gOffset) ?
           numLEDs + ((numLEDs + 3) / 4) : // MONO: 10 bits/pixel
           numLEDs * 3);                   // COLOR: 3 bytes/pixel
}

// Set pixel color, separate R,G,B values (0-255 ea.)
void Adafruit_DotStar::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;
    }
}

// Set pixel color, 'packed' RGB value (0x000000 - 0xFFFFFF)
void Adafruit_DotStar::setPixelColor(uint16_t n, uint32_t c)
{
    if(n < numLEDs) {
        uint8_t *p = &pixels[n * 3];
        p[rOffset] = (uint8_t)(c >> 16);
        p[gOffset] = (uint8_t)(c >>  8);
        p[bOffset] = (uint8_t)c;
    }
}

// Convert separate R,G,B to packed value
uint32_t Adafruit_DotStar::Color(uint8_t r, uint8_t g, uint8_t b)
{
    return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
}

// Read color from previously-set pixel, returns packed RGB value.
uint32_t Adafruit_DotStar::getPixelColor(uint16_t n) const
{
    if(n >= numLEDs) return 0;
    uint8_t *p = &pixels[n * 3];
    return ((uint32_t)p[rOffset] << 16) |
           ((uint32_t)p[gOffset] <<  8) |
           (uint32_t)p[bOffset];
}

uint16_t Adafruit_DotStar::numPixels(void)   // Ret. strip length
{
    return numLEDs;
}

// Set global strip brightness.  This does not have an immediate effect;
// must be followed by a call to show().  Not a fan of this...for various
// reasons I think it's better handled in one's sketch, but it's here for
// parity with the NeoPixel library.  Good news is that brightness setting
// in this library is 'non destructive' -- it's applied as color data is
// being issued to the strip, not during setPixel(), and also means that
// getPixelColor() returns the exact value originally stored.
void Adafruit_DotStar::setBrightness(uint8_t b)
{
    // Stored brightness value is different than what's passed.  This
    // optimizes the actual scaling math later, allowing a fast 8x8-bit
    // multiply and taking the MSB.  'brightness' is a uint8_t, adding 1
    // here may (intentionally) roll over...so 0 = max brightness (color
    // values are interpreted literally; no scaling), 1 = min brightness
    // (off), 255 = just below max brightness.
    brightness = b + 1;
}

uint8_t Adafruit_DotStar::getBrightness(void) const
{
    return brightness - 1; // Reverse above operation
}

// Return pointer to the library's pixel data buffer.  Use carefully,
// much opportunity for mayhem.  It's mostly for code that needs fast
// transfers, e.g. SD card to LEDs.  Color data is in BGR order.
uint8_t *Adafruit_DotStar::getPixels(void) const
{
    return pixels;
}