John Rattray / Mbed 2 deprecated Spark

Dependencies:   BLE_API mbed nRF51822

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers DotStar.cpp Source File

DotStar.cpp

00001 #include "DotStar.h"
00002 
00003 SPI SPI1(P0_5,NC,P0_4);
00004 
00005 // Constructor for 'soft' (bitbang) SPI -- any two pins can be used
00006 DotStar::DotStar(uint16_t n, uint8_t data, uint8_t clock) :
00007  dataPin(data), clockPin(clock), brightness(0), pixels(NULL)
00008 {
00009   updateLength(n);
00010 }
00011 
00012 void DotStar::begin(void) { // Initialize SPI
00013     //SPI1.begin(clockPin, dataPin, P0_29);//SCK, MOSI, MISO
00014     //SPI1.transfer(0xFF);
00015 }
00016 
00017 void DotStar::updateLength(uint16_t n) {
00018   if(pixels) free(pixels);
00019   uint16_t bytes = n * 3;              // COLOR: 3 bytes/pixel
00020   if((pixels = (uint8_t *)malloc(bytes))) {
00021     numLEDs = n;
00022     clear();
00023   } else {
00024     numLEDs = 0;
00025   }
00026 }
00027 
00028 //-------------------------------------------------------------------------------
00029 //-------------------------------------------------------------------------------
00030 void DotStar::show(void) {
00031 
00032     if(!pixels) return;
00033     
00034     
00035     uint8_t *ptr = pixels, i;            // -> LED data
00036     uint16_t n   = numLEDs;              // Counter
00037     uint16_t b16 = (uint16_t)brightness; // Type-convert for fixed-point math
00038     
00039     // Soft (bitbang) SPI
00040 
00041     for(i=0; i<4; i++) SPI1.write(0x00);    // Start-frame marker
00042     if(brightness) {                     // Scale pixel brightness on output
00043       do {                               // For each pixel...
00044         SPI1.write(0xFF);                //  Pixel start
00045         for(i=0; i<3; i++) SPI1.write((*ptr++ * b16) >> 8); // Scale, write
00046       } while(--n);
00047     } else {                             // Full brightness (no scaling)
00048       do {                               // For each pixel...
00049         SPI1.write(0xFF);                //  Pixel start
00050         for(i=0; i<3; i++) SPI1.write(*ptr++); // R,G,B
00051       } while(--n);
00052     }
00053     //Remove end-frame below if last led goes all white
00054     //for(i=0; i<4; i++) SPI1.write(0xFF); // End-frame marker (see note above)
00055     
00056 }
00057 
00058 
00059 void DotStar::clear() { // Write 0s (off) to full pixel buffer
00060   memset(pixels, 0, numLEDs * 3);                   // COLOR: 3 bytes/pixel
00061 }
00062 
00063 // Set pixel color, separate R,G,B values (0-255 ea.)
00064 void DotStar::setPixelColor(
00065  uint16_t n, uint8_t r, uint8_t g, uint8_t b) {
00066   if(n < numLEDs) {
00067     uint8_t *p = &pixels[n * 3];
00068     p[0] = r;
00069     p[1] = g;
00070     p[2] = b;
00071     //SPI1.transfer(0xFF);
00072   }
00073 }
00074 
00075 // Set pixel color, 'packed' RGB value (0x000000 - 0xFFFFFF)
00076 void DotStar::setPixelColor(uint16_t n, uint32_t c) {
00077   if(n < numLEDs) {
00078     uint8_t *p = &pixels[n * 3];
00079     p[0] = (uint8_t)(c >> 16);
00080     p[1] = (uint8_t)(c >>  8);
00081     p[2] = (uint8_t)c;
00082   }
00083 }
00084 
00085 // Convert separate R,G,B to packed value
00086 uint32_t DotStar::Color(uint8_t r, uint8_t g, uint8_t b) {
00087   return ((uint32_t)r << 16) | ((uint32_t)g << 8) | b;
00088 }
00089 
00090 // Read color from previously-set pixel, returns packed RGB value.
00091 uint32_t DotStar::getPixelColor(uint16_t n) const {
00092   if(n >= numLEDs) return 0;
00093   uint8_t *p = &pixels[n * 3];
00094   return ((uint32_t)p[0] << 16) |
00095          ((uint32_t)p[1] <<  8) |
00096           (uint32_t)p[2];
00097 }
00098 
00099 uint16_t DotStar::numPixels(void) { // Ret. strip length
00100   return numLEDs;
00101 }
00102 
00103 // Set global strip brightness.  This does not have an immediate effect;
00104 // must be followed by a call to show().  Not a fan of this...for various
00105 // reasons I think it's better handled in one's sketch, but it's here for
00106 // parity with the NeoPixel library.  Good news is that brightness setting
00107 // in this library is 'non destructive' -- it's applied as color data is
00108 // being issued to the strip, not during setPixel(), and also means that
00109 // getPixelColor() returns the exact value originally stored.
00110 void DotStar::setBrightness(uint8_t b) {
00111   // Stored brightness value is different than what's passed.  This
00112   // optimizes the actual scaling math later, allowing a fast 8x8-bit
00113   // multiply and taking the MSB.  'brightness' is a uint8_t, adding 1
00114   // here may (intentionally) roll over...so 0 = max brightness (color
00115   // values are interpreted literally; no scaling), 1 = min brightness
00116   // (off), 255 = just below max brightness.
00117   brightness = b + 1;
00118 }
00119 
00120 uint8_t DotStar::getBrightness(void) const {
00121   return brightness - 1; // Reverse above operation
00122 }
00123 
00124 // Return pointer to the library's pixel data buffer.  Use carefully,
00125 // much opportunity for mayhem.  It's mostly for code that needs fast
00126 // transfers, e.g. SD card to LEDs.  Color data is in BGR order.
00127 uint8_t *DotStar::getPixels(void) const {
00128   return pixels;
00129 }