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

Revision:
0:bae97ff743a6
Child:
1:d09c288b8eb3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DotStar.cpp	Fri Mar 25 07:41:51 2016 +0000
@@ -0,0 +1,210 @@
+/*------------------------------------------------------------------------
+  Arduino library to control Adafruit Dot Star addressable RGB LEDs.
+
+  Written by Limor Fried and Phil Burgess for Adafruit Industries.
+
+  Adafruit invests time and resources providing this open source code,
+  please support Adafruit and open-source hardware by purchasing products
+  from Adafruit!
+
+  ------------------------------------------------------------------------
+  This file is part of the Adafruit Dot Star library.
+
+  Adafruit Dot Star is free software: you can redistribute it and/or
+  modify it under the terms of the GNU Lesser General Public License
+  as published by the Free Software Foundation, either version 3 of
+  the License, or (at your option) any later version.
+
+  Adafruit Dot Star is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with DotStar.  If not, see <http://www.gnu.org/licenses/>.
+  ------------------------------------------------------------------------*/
+
+#include "DotStar.h"
+// #include <SPI.h>
+
+SPI spi(p5, p6, p7); // mosi, miso, sclk
+
+// Constructor for hardware SPI -- must connect to MOSI, SCK pins
+Adafruit_DotStar::Adafruit_DotStar(uint16_t n, uint8_t o) :
+ numLEDs(n), dataPin(p5), brightness(0), pixels(NULL),
+ rOffset(o & 3), gOffset((o >> 2) & 3), bOffset((o >> 4) & 3)
+{
+  updateLength(n);
+}
+
+// Constructor for 'soft' (bitbang) SPI -- any two pins can be used
+Adafruit_DotStar::Adafruit_DotStar(uint16_t n, uint8_t data, uint8_t clock,
+  uint8_t o) :
+ dataPin(data), clockPin(clock), 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)   free(pixels);
+  hw_spi_end();
+}
+
+void Adafruit_DotStar::begin(void) { // Initialize SPI
+  hw_spi_init();
+}
+
+// Length can be changed post-constructor for similar reasons (sketch
+// config not hardcoded).  But DON'T use this for "recycling" strip RAM...
+// all that reallocation is likely to fragment and eventually fail.
+// Instead, set length once to longest strip.
+void Adafruit_DotStar::updateLength(uint16_t n) {
+  if(pixels) free(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 = (uint8_t *)malloc(bytes))) {
+    numLEDs = n;
+    clear();
+  } else {
+    numLEDs = 0;
+  }
+}
+
+// SPI STUFF ---------------------------------------------------------------
+
+void Adafruit_DotStar::hw_spi_init(void) { // Initialize hardware SPI
+  // SPI.begin();
+  // SPI.setClockDivider((F_CPU + 4000000L) / 8000000L); // 8-ish MHz on Due
+  // SPI.setBitOrder(MSBFIRST);
+  // SPI.setDataMode(SPI_MODE0);   // Clock Polarity: 0, Clock Phase: 0
+
+  spi.format(8, 0);   // 8bit, mode:0
+  spi.frequency(8000000); // Hz
+
+}
+
+void Adafruit_DotStar::hw_spi_end(void) { // Stop hardware SPI
+  // SPI.end();
+}
+
+
+// All other boards have full-featured hardware support for SPI
+
+//#define spi_out(n) (void)spi.write(n)
+// Pipelining reads next byte while current byte is clocked out
+
+
+/* ISSUE DATA TO LED STRIP -------------------------------------------------
+
+  Although the LED driver has an additional per-pixel 5-bit brightness
+  setting, it is NOT used or supported here because it's a brain-dead
+  misfeature that's counter to the whole point of Dot Stars, which is to
+  have a much faster PWM rate than NeoPixels.  It gates the high-speed
+  PWM output through a second, much slower PWM (about 400 Hz), rendering
+  it useless for POV.  This brings NOTHING to the table that can't be
+  already handled better in one's sketch code.  If you really can't live
+  without this abomination, you can fork the library and add it for your
+  own use, but any pull requests for this will NOT be merged, nuh uh!
+*/
+
+void Adafruit_DotStar::show(void) {
+  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
+
+      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);
+}
+
+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;
+}