Robert Bui / Multi_WS2811

Fork of Multi_WS2811 by Richard Thompson

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WS2811.h Source File

WS2811.h

00001 // Mbed library to control WS2801-based RGB LED Strips
00002 // some portions (c) 2011 Jelmer Tiete
00003 // This library is ported from the Arduino implementation of Adafruit Industries
00004 // found at: http://github.com/adafruit/LPD8806
00005 // and their strips: http://www.adafruit.com/products/306
00006 // Released under the MIT License: http://mbed.org/license/mit
00007 //
00008 /*****************************************************************************/
00009 
00010 // Heavily modified by Jas Strong, 2012-10-04
00011 // Changed to use a virtual base class and to use software SPI.
00012 //
00013 // Modified by Ned Konz, December 2013.
00014 // Using three-phase DMA ala Paul Stoffegren's version.
00015 //
00016 // Modified by richard Thompson, March 2014.
00017 // Uses 8-bit DMA transfers instead of 32-bit, uses 1/4 of the RAM (static)
00018 // Now capable of running 240 LEDs on one pin
00019 
00020 #ifndef MBED_WS2811_H
00021 #define MBED_WS2811_H
00022 
00023 #include "mbed.h"
00024 #include "LedStrip.h"
00025 
00026 //! Maximum number of LEDs per strip
00027 #define MAX_LEDS_PER_STRIP 200
00028 
00029 extern "C" void DMA0_IRQHandler();
00030 extern "C" void TPM0_IRQHandler();
00031 
00032 /**
00033 * WS2811/WS2812/WS2812B
00034 * LED Strip controller\n
00035 * For FRDM-KL25Z and FRDM-KL46Z
00036 
00037  RAM usage:\n
00038  Per individual LED: 3 bytes (malloc'd) for RGB data
00039 
00040  Strip length per LED:\n
00041           24 bytes (static) for bit data\n
00042         + 24 bytes (static) for ones data\n
00043         = 48 bytes
00044 
00045         240 LEDs max per string = 11,520 bytes static
00046 
00047       One string:\n
00048         240 LEDs  : 11520 + 240*3 = 12,240 bytes
00049 
00050       Eight strings:\n
00051         240*8 LEDs: 11520 + (240*3) * 8 = 17,280 bytes
00052 
00053 Example usage:
00054 @code
00055 #include "mbed.h"
00056 #include "WS2811.h"
00057 #include "Colors.h"
00058 
00059 static void showRainbow(WS2811 &strip, float startHue, float sat, float brite, float hueShift)
00060 {
00061     unsigned nLEDs = strip.numPixels();
00062     float hue = startHue;
00063     for (unsigned i = 0; i < nLEDs; i++) {
00064         uint8_t r, g, b;
00065         Colors::HSBtoRGB(hue, sat, brite, &r, &g, &b);
00066         strip.setPixelColor(i, r, g, b);
00067         hue += hueShift;
00068         if (hue > 1.0) hue = 0.0;
00069     }
00070     strip.show();
00071 }
00072 
00073 static void showSolidColor(WS2811 &strip, uint8_t r, uint8_t g, uint8_t b)
00074 {
00075     unsigned nLEDs = strip.numPixels();
00076     for (unsigned i = 0; i < nLEDs; i++) {
00077         strip.setPixelColor(i, r, g, b);
00078     }
00079     strip.show();
00080 }
00081 
00082 int main(void)
00083 {
00084     WS2811 lightStrip1(nLEDs, 2);
00085     WS2811 lightStrip2(nLEDs, 3);
00086     WS2811 lightStrip3(nLEDs, 4);
00087 
00088     lightStrip1.begin();
00089     lightStrip2.begin();
00090     lightStrip3.begin();
00091 
00092     uint8_t r =0;
00093     uint8_t g =0;
00094     uint8_t b =0;
00095 
00096     bool fadeUp = true;
00097 
00098     float startHue = 0.0;
00099     for (;;) {
00100         startHue += 0.01;
00101         if (startHue > 1.0) startHue = 0.0;
00102         if (fadeUp) {
00103             if (r == 255) fadeUp = false;
00104             else {
00105                 ++r;
00106                 ++g;
00107                 ++b;
00108             }
00109         } else {
00110             if (r == 0) fadeUp = true;
00111             else {
00112                 --r;
00113                 --g;
00114                 --b;
00115             }
00116         }
00117 
00118         // Solid fading white
00119         showSolidColor(lightStrip1, r, g, b);
00120         // Maximum saturation rainbow
00121         showRainbow(lightStrip2, startHue, 1.0, 1.0, 1.0/nLEDs);
00122         // Pastel rainbow
00123         showRainbow(lightStrip3, startHue, 0.5, 1.0, 1.0/nLEDs);
00124 
00125         WS2811::startDMA();
00126         wait_ms(25);
00127         frames++;
00128     }
00129 }
00130 @endcode
00131 */
00132 class WS2811 : public LedStrip
00133 {
00134 public:
00135     /** Set up the LED strip
00136     @param pixelCount Number of RGB LEDs on the strip. No more than MAX_LEDS_PER_STRIP (240)
00137     @param pinNumber Pin number on PORTD. 0-7.
00138     */
00139     WS2811(uint16_t pixelCount, uint8_t pinNumber);
00140 
00141     virtual void begin();
00142     virtual void show();
00143     virtual void blank();
00144 
00145     /** Send a level update to all the WS2811 LED strips\n
00146     * All updates happen in parallel, ensure all (max 8) strips have complete data before calling this.
00147     */
00148     static void startDMA();
00149 
00150 private:
00151     uint32_t pinMask;
00152 
00153     void writePixel(unsigned n, uint8_t *p);
00154 
00155     // Class Static:
00156 
00157     static bool initialized;
00158     static uint32_t enabledPins;
00159     static volatile bool dma_done;
00160     static void wait_for_dma_done() {
00161         while (!dma_done) __WFI();
00162     }
00163 
00164     static void writeByte(uint8_t byte, uint32_t mask, uint8_t *dest);
00165 
00166     static void hw_init();
00167     static void io_init();
00168     static void clock_init();
00169     static void dma_init();
00170     static void tpm_init();
00171     static void dma_data_init();
00172 
00173     friend void TPM0_IRQHandler();
00174 };
00175 
00176 #endif
00177