Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Diff: WS2811.h
- 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
+
Generic WS2811/WS2812