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.
WS2811.h
00001 //! @file WS2811.h 00002 // Mbed library to control WS2801-based RGB LED Strips 00003 // some portions (c) 2011 Jelmer Tiete 00004 // This library is ported from the Arduino implementation of Adafruit Industries 00005 // found at: http://github.com/adafruit/LPD8806 00006 // and their strips: http://www.adafruit.com/products/306 00007 // Released under the MIT License: http://mbed.org/license/mit 00008 // 00009 /*****************************************************************************/ 00010 00011 // Heavily modified by Jas Strong, 2012-10-04 00012 // Changed to use a virtual base class and to use software SPI. 00013 // 00014 // Modified by Ned Konz, December 2013. 00015 // Using three-phase DMA ala Paul Stoffegren's version. 00016 // Example: 00017 // @code 00018 // #include <mbed.h> 00019 // // In one file that includes this one, 00020 // // #define INSTANTIATE_TEMPLATES as non-zero before including this file: 00021 // #define INSTANTIATE_TEMPLATES 1 00022 // #include "WS2811.h" 00023 // // Then declare a template class with the maximum number of LEDs per strip that you will need: 00024 // unsigned const maxLEDs = 30; 00025 // template class WS2811<maxLEDs>; 00026 // // You can reduce typing using a typedef: 00027 // typedef WS2811<maxLEDs> MyWS2811; 00028 // // Later, define instances of this template class, each with up to the maximum number of LEDs: 00029 // MyWS2811 lightStrip1(nLEDs, DATA_OUT_PIN1); 00030 // MyWS2811 lightStrip2(nLEDs, DATA_OUT_PIN2); 00031 // @endcode 00032 00033 #ifndef MBED_WS2811_H 00034 #define MBED_WS2811_H 00035 00036 #include "LedStrip.h" 00037 00038 // 00039 // Configuration 00040 // 00041 00042 #ifndef WS2811_IO_PORT 00043 #define WS2811_IO_PORT PORTD 00044 #endif 00045 00046 #ifndef WS2811_IO_GPIO 00047 #define WS2811_IO_GPIO PTD 00048 #endif 00049 00050 // define WS2811_DEBUG_PIN to identify a pin in WS2811_IOPORT used for debug output 00051 // #define WS2811_DEBUG_PIN 4 /* PTD4 debugOut */ 00052 00053 // Define WS2811_MONITOR_TPM0_PWM as non-zero to monitor PWM timing on PTD0 and PTD1 00054 // PTD0 TPM0/CH0 PWM_1 J2/06 00055 // PTD1 TPM0/CH1 PWM_2 J2/12 (also LED_BLUE) 00056 #define WS2811_MONITOR_TPM0_PWM 0 00057 00058 extern "C" void DMA0_IRQHandler(); 00059 extern "C" void TPM0_IRQHandler(); 00060 00061 template <unsigned MAX_LEDS_PER_STRIP> 00062 class WS2811 : public LedStrip 00063 { 00064 public: 00065 WS2811(unsigned n, unsigned pinNumber) 00066 : LedStrip(n) 00067 , pinMask(1U << pinNumber) 00068 { 00069 enabledPins |= pinMask; 00070 initialized = false; 00071 } 00072 00073 virtual void show() 00074 { 00075 uint16_t i, n = numPixels(); // 3 bytes per LED 00076 uint8_t *p = pixels; 00077 00078 for (i=0; i<n; i++ ) 00079 { 00080 writePixel(i, p); 00081 p += 3; 00082 } 00083 } 00084 00085 virtual void begin() 00086 { 00087 blank(); 00088 show(); 00089 } 00090 00091 virtual void blank() 00092 { 00093 std::memset(pixels, 0x00, numPixelBytes()); 00094 00095 std::memset(dmaData.dmaWords, 0x00, sizeof(dmaData.dmaWords)); 00096 } 00097 00098 static void startDMA(); 00099 static unsigned maxLEDsPerStrip() { return MAX_LEDS_PER_STRIP; } 00100 static void wait_for_dma_done(); 00101 00102 private: 00103 uint32_t pinMask; 00104 00105 void writePixel(unsigned n, uint8_t *p) 00106 { 00107 uint32_t *dest = dmaData.dmaWords + n * BITS_PER_RGB; 00108 writeByte(*p++, pinMask, dest + 0); // G 00109 writeByte(*p++, pinMask, dest + 8); // R 00110 writeByte(*p, pinMask, dest + 16); // B 00111 } 00112 00113 // Class Static: 00114 00115 static bool initialized; 00116 static uint32_t enabledPins; 00117 00118 static void writeByte(uint8_t byte, uint32_t mask, uint32_t *dest) 00119 { 00120 for (uint8_t bm = 0x80; bm; bm >>= 1) 00121 { 00122 // MSBit first 00123 if (byte & bm) 00124 *dest |= mask; 00125 else 00126 *dest &= ~mask; 00127 dest++; 00128 } 00129 } 00130 00131 static void hw_init(); 00132 static void io_init(); 00133 static void clock_init(); 00134 static void dma_init(); 00135 static void tpm_init(); 00136 static void dma_data_init(); 00137 00138 friend void TPM0_IRQHandler(); 00139 00140 static const unsigned DMA_LEADING_ZEROS = 2; 00141 static const unsigned BITS_PER_RGB = 24; 00142 static const unsigned DMA_TRAILING_ZEROS = 1; 00143 00144 struct DMALayout 00145 { 00146 uint32_t start_t1_low[ DMA_LEADING_ZEROS ]; 00147 uint32_t dmaWords[ BITS_PER_RGB * MAX_LEDS_PER_STRIP ]; 00148 uint32_t trailing_zeros_1[ DMA_TRAILING_ZEROS ]; 00149 00150 uint32_t start_t0_high[ DMA_LEADING_ZEROS - 1 ]; 00151 uint32_t allOnes[ BITS_PER_RGB * MAX_LEDS_PER_STRIP ]; 00152 uint32_t trailing_zeros_2[ DMA_TRAILING_ZEROS + 1 ]; 00153 }; 00154 00155 static DMALayout dmaData; 00156 }; 00157 00158 #endif 00159 00160 #if INSTANTIATE_TEMPLATES 00161 #include "WS2811.cpp" 00162 #endif 00163
Generated on Wed Jul 13 2022 13:18:58 by
1.7.2
Generic WS2811/WS2812