Ned Konz / Multi_WS2811

Dependents:   Multi_WS2811_test

Revision:
3:df4319053bfa
Parent:
1:86a910560879
Child:
4:990838718b51
diff -r 9447404f2d16 -r df4319053bfa WS2811.h
--- a/WS2811.h	Thu Jun 11 15:32:07 2015 +0000
+++ b/WS2811.h	Fri Jun 12 18:23:03 2015 -0700
@@ -1,165 +1,165 @@
-//! @file WS2811.h
-// Mbed library to control WS2801-based RGB LED Strips
-// some portions (c) 2011 Jelmer Tiete
-// This library is ported from the Arduino implementation of Adafruit Industries
-// found at: http://github.com/adafruit/LPD8806
-// and their strips: http://www.adafruit.com/products/306
-// Released under the MIT License: http://mbed.org/license/mit
-//
-/*****************************************************************************/
-
-// Heavily modified by Jas Strong, 2012-10-04
-// Changed to use a virtual base class and to use software SPI.
-//
-// Modified by Ned Konz, December 2013.
-// Using three-phase DMA ala Paul Stoffegren's version.
-// Example:
-// @code
-// #include <mbed.h>
-// // In one file that includes this one,
-// // #define INSTANTIATE_TEMPLATES as non-zero before including this file:
-// #define INSTANTIATE_TEMPLATES 1
-// #include "WS2811.h"
-// // Then declare a template class with the maximum number of LEDs per strip that you will need:
-// unsigned const maxLEDs = 30;
-// template class WS2811<maxLEDs>;
-// // You can reduce typing using a typedef:
-// typedef WS2811<maxLEDs> MyWS2811;
-// // Later, define instances of this template class, each with up to the maximum number of LEDs:
-// MyWS2811 lightStrip1(nLEDs, DATA_OUT_PIN1);
-// MyWS2811 lightStrip2(nLEDs, DATA_OUT_PIN2);
-// @endcode
-
-#ifndef MBED_WS2811_H
-#define MBED_WS2811_H
-
-#include "LedStrip.h"
-
-//
-// Configuration
-//
-
-#ifndef WS2811_IO_PORT
-#define WS2811_IO_PORT PORTD
-#endif
-
-#ifndef WS2811_IO_GPIO
-#define WS2811_IO_GPIO PTD
-#endif
-
-// define WS2811_DEBUG_PIN to identify a pin in WS2811_IOPORT used for debug output
-// #define WS2811_DEBUG_PIN 4 /* PTD4 debugOut */
-
-// Define WS2811_MONITOR_TPM0_PWM as non-zero to monitor PWM timing on PTD0 and PTD1
-// PTD0 TPM0/CH0 PWM_1 J2/06
-// PTD1 TPM0/CH1 PWM_2 J2/12 (also LED_BLUE)
-#define WS2811_MONITOR_TPM0_PWM 0
-
-extern "C" void DMA0_IRQHandler();
-extern "C" void TPM0_IRQHandler();
-
-template <unsigned MAX_LEDS_PER_STRIP>
-class WS2811 : public LedStrip
-{
-public:    
-    WS2811(unsigned n, unsigned pinNumber)
-        : LedStrip(n)
-        , pinMask(1U << pinNumber)
-    {
-        enabledPins |= pinMask;
-        initialized = false;
-    }
-
-    virtual void show()
-    {
-        uint16_t i, n = numPixels(); // 3 bytes per LED
-        uint8_t *p = pixels;
-    
-        for (i=0; i<n; i++ ) {
-            writePixel(i, p);
-            p += 3;
-        }
-    }
-    
-    virtual void begin()
-    {
-        blank();
-        show();
-    }
-
-    virtual void blank()
-    {
-        std::memset(pixels, 0x00, numPixelBytes());
-    
-    #if DEBUG
-        for (unsigned i = DMA_LEADING_ZEROS; i < DMA_LEADING_ZEROS + BITS_PER_RGB; i++)
-            dmaData.dmaWords[i] = DEBUG_MASK;
-    #else
-        std::memset(dmaData.dmaWords, 0x00, sizeof(dmaData.dmaWords));
-    #endif
-    }
-
-    static void startDMA();
-    static unsigned maxLEDsPerStrip() { return MAX_LEDS_PER_STRIP; }
-
-private:
-    uint32_t pinMask;
-
-    void writePixel(unsigned n, uint8_t *p)
-    {
-        uint32_t *dest = dmaData.dmaWords + n * BITS_PER_RGB;
-        writeByte(*p++, pinMask, dest + 0); // G
-        writeByte(*p++, pinMask, dest + 8); // R
-        writeByte(*p, pinMask, dest + 16); // B
-    }
-
-    // Class Static:
-
-    static bool initialized;
-    static uint32_t enabledPins;
-    static void wait_for_dma_done();
-
-    static void writeByte(uint8_t byte, uint32_t mask, uint32_t *dest)
-    {
-        for (uint8_t bm = 0x80; bm; bm >>= 1) {
-            // MSBit first
-            if (byte & bm)
-                *dest |= mask;
-            else
-                *dest &= ~mask;
-            dest++;
-        }
-    }
-
-    static void hw_init();
-    static void io_init();
-    static void clock_init();
-    static void dma_init();
-    static void tpm_init();
-    static void dma_data_init();
-        
-    friend void TPM0_IRQHandler();
-    
-    static const unsigned DMA_LEADING_ZEROS = 2;
-    static const unsigned BITS_PER_RGB      = 24;
-    static const unsigned DMA_TRAILING_ZEROS = 1;
-
-    struct DMALayout {
-        uint32_t start_t1_low[ DMA_LEADING_ZEROS ];
-        uint32_t dmaWords[ BITS_PER_RGB * MAX_LEDS_PER_STRIP ];
-        uint32_t trailing_zeros_1[ DMA_TRAILING_ZEROS ];
-    
-        uint32_t start_t0_high[ DMA_LEADING_ZEROS - 1 ];
-        uint32_t allOnes[ BITS_PER_RGB * MAX_LEDS_PER_STRIP ];
-        uint32_t trailing_zeros_2[ DMA_TRAILING_ZEROS + 1 ];
-    };
-    
-    static DMALayout dmaData;
-};
-
-#endif
-
-#if INSTANTIATE_TEMPLATES
-#include "WS2811.cpp"
-#endif
-
+//! @file WS2811.h
+// Mbed library to control WS2801-based RGB LED Strips
+// some portions (c) 2011 Jelmer Tiete
+// This library is ported from the Arduino implementation of Adafruit Industries
+// found at: http://github.com/adafruit/LPD8806
+// and their strips: http://www.adafruit.com/products/306
+// Released under the MIT License: http://mbed.org/license/mit
+//
+/*****************************************************************************/
+
+// Heavily modified by Jas Strong, 2012-10-04
+// Changed to use a virtual base class and to use software SPI.
+//
+// Modified by Ned Konz, December 2013.
+// Using three-phase DMA ala Paul Stoffegren's version.
+// Example:
+// @code
+// #include <mbed.h>
+// // In one file that includes this one,
+// // #define INSTANTIATE_TEMPLATES as non-zero before including this file:
+// #define INSTANTIATE_TEMPLATES 1
+// #include "WS2811.h"
+// // Then declare a template class with the maximum number of LEDs per strip that you will need:
+// unsigned const maxLEDs = 30;
+// template class WS2811<maxLEDs>;
+// // You can reduce typing using a typedef:
+// typedef WS2811<maxLEDs> MyWS2811;
+// // Later, define instances of this template class, each with up to the maximum number of LEDs:
+// MyWS2811 lightStrip1(nLEDs, DATA_OUT_PIN1);
+// MyWS2811 lightStrip2(nLEDs, DATA_OUT_PIN2);
+// @endcode
+
+#ifndef MBED_WS2811_H
+#define MBED_WS2811_H
+
+#include "LedStrip.h"
+
+//
+// Configuration
+//
+
+#ifndef WS2811_IO_PORT
+#define WS2811_IO_PORT PORTD
+#endif
+
+#ifndef WS2811_IO_GPIO
+#define WS2811_IO_GPIO PTD
+#endif
+
+// define WS2811_DEBUG_PIN to identify a pin in WS2811_IOPORT used for debug output
+// #define WS2811_DEBUG_PIN 4 /* PTD4 debugOut */
+
+// Define WS2811_MONITOR_TPM0_PWM as non-zero to monitor PWM timing on PTD0 and PTD1
+// PTD0 TPM0/CH0 PWM_1 J2/06
+// PTD1 TPM0/CH1 PWM_2 J2/12 (also LED_BLUE)
+#define WS2811_MONITOR_TPM0_PWM 0
+
+extern "C" void DMA0_IRQHandler();
+extern "C" void TPM0_IRQHandler();
+
+template <unsigned MAX_LEDS_PER_STRIP>
+class WS2811 : public LedStrip
+{
+public:    
+    WS2811(unsigned n, unsigned pinNumber)
+        : LedStrip(n)
+        , pinMask(1U << pinNumber)
+    {
+        enabledPins |= pinMask;
+        initialized = false;
+    }
+
+    virtual void show()
+    {
+        uint16_t i, n = numPixels(); // 3 bytes per LED
+        uint8_t *p = pixels;
+    
+        for (i=0; i<n; i++ ) {
+            writePixel(i, p);
+            p += 3;
+        }
+    }
+    
+    virtual void begin()
+    {
+        blank();
+        show();
+    }
+
+    virtual void blank()
+    {
+        std::memset(pixels, 0x00, numPixelBytes());
+    
+    #if DEBUG
+        for (unsigned i = DMA_LEADING_ZEROS; i < DMA_LEADING_ZEROS + BITS_PER_RGB; i++)
+            dmaData.dmaWords[i] = DEBUG_MASK;
+    #else
+        std::memset(dmaData.dmaWords, 0x00, sizeof(dmaData.dmaWords));
+    #endif
+    }
+
+    static void startDMA();
+    static unsigned maxLEDsPerStrip() { return MAX_LEDS_PER_STRIP; }
+    static void wait_for_dma_done();
+
+private:
+    uint32_t pinMask;
+
+    void writePixel(unsigned n, uint8_t *p)
+    {
+        uint32_t *dest = dmaData.dmaWords + n * BITS_PER_RGB;
+        writeByte(*p++, pinMask, dest + 0); // G
+        writeByte(*p++, pinMask, dest + 8); // R
+        writeByte(*p, pinMask, dest + 16); // B
+    }
+
+    // Class Static:
+
+    static bool initialized;
+    static uint32_t enabledPins;
+
+    static void writeByte(uint8_t byte, uint32_t mask, uint32_t *dest)
+    {
+        for (uint8_t bm = 0x80; bm; bm >>= 1) {
+            // MSBit first
+            if (byte & bm)
+                *dest |= mask;
+            else
+                *dest &= ~mask;
+            dest++;
+        }
+    }
+
+    static void hw_init();
+    static void io_init();
+    static void clock_init();
+    static void dma_init();
+    static void tpm_init();
+    static void dma_data_init();
+        
+    friend void TPM0_IRQHandler();
+    
+    static const unsigned DMA_LEADING_ZEROS = 2;
+    static const unsigned BITS_PER_RGB      = 24;
+    static const unsigned DMA_TRAILING_ZEROS = 1;
+
+    struct DMALayout {
+        uint32_t start_t1_low[ DMA_LEADING_ZEROS ];
+        uint32_t dmaWords[ BITS_PER_RGB * MAX_LEDS_PER_STRIP ];
+        uint32_t trailing_zeros_1[ DMA_TRAILING_ZEROS ];
+    
+        uint32_t start_t0_high[ DMA_LEADING_ZEROS - 1 ];
+        uint32_t allOnes[ BITS_PER_RGB * MAX_LEDS_PER_STRIP ];
+        uint32_t trailing_zeros_2[ DMA_TRAILING_ZEROS + 1 ];
+    };
+    
+    static DMALayout dmaData;
+};
+
+#endif
+
+#if INSTANTIATE_TEMPLATES
+#include "WS2811.cpp"
+#endif
+