Optimised fork of bikeNomad's WS2811 LED control library. Supports KL25Z and KL46Z

Dependents:   CubicHand

Fork of Multi_WS2811 by Ned Konz

Optimised to use far less RAM than the original.

Capable of running up to 8 strings of 240 LEDs each with plenty of RAM to spare on the KL46Z.

Should run at least three strings of 240 LEDs on the KL25Z (RAM limited)

Files at this revision

API Documentation at this revision

Comitter:
Tomo2k
Date:
Wed Apr 02 10:53:43 2014 +0000
Parent:
1:7b2d0ea091fb
Child:
3:2b5b03a3c0a5
Commit message:
Support for 240 x WS2812B LEDs on one pin across 8 pins

Changed in this revision

WS2811.cpp Show annotated file Show diff for this revision Revisions of this file
WS2811.h Show annotated file Show diff for this revision Revisions of this file
--- a/WS2811.cpp	Tue Apr 01 11:23:33 2014 +0000
+++ b/WS2811.cpp	Wed Apr 02 10:53:43 2014 +0000
@@ -83,20 +83,21 @@
 uint32_t WS2811::enabledPins = 0;
 
 #define WORD_ALIGNED __attribute__ ((aligned(4)))
+#define BYTE_ALIGNED __attribute__ ((aligned(1)))
 
 #define DMA_LEADING_ZEROS  2
 #define BITS_PER_RGB       24
 #define DMA_TRAILING_ZEROS 1
 
 static struct {
-    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 ];
+    uint8_t start_t1_low[ DMA_LEADING_ZEROS ];
+    uint8_t dmaWords[ BITS_PER_RGB * MAX_LEDS_PER_STRIP ];
+    uint8_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 ];
-} dmaData WORD_ALIGNED;
+    uint8_t start_t0_high[ DMA_LEADING_ZEROS - 1 ];
+    uint8_t allOnes[ BITS_PER_RGB * MAX_LEDS_PER_STRIP ];
+    uint8_t trailing_zeros_2[ DMA_TRAILING_ZEROS + 1 ];
+} dmaData BYTE_ALIGNED;
 
 // class static
 void WS2811::hw_init()
@@ -289,37 +290,37 @@
                                        | DMA_DCR_D_REQ_MASK // clear ERQ on end of transfer
                                        | DMA_DCR_SINC_MASK // increment source each transfer
                                        | DMA_DCR_CS_MASK
-                                       | DMA_DCR_SSIZE(0) // 32-bit source transfers
-                                       | DMA_DCR_DSIZE(0); // 32-bit destination transfers
+                                       | DMA_DCR_SSIZE(1) // 8-bit source transfers
+                                       | DMA_DCR_DSIZE(1); // 8-bit destination transfers
 
     dma->DMA[DMA_CHAN_1_LOW].DCR     = DMA_DCR_EINT_MASK // enable interrupt on end of transfer
                                        | DMA_DCR_ERQ_MASK
                                        | DMA_DCR_D_REQ_MASK // clear ERQ on end of transfer
                                        | DMA_DCR_CS_MASK
-                                       | DMA_DCR_SSIZE(0) // 32-bit source transfers
-                                       | DMA_DCR_DSIZE(0); // 32-bit destination transfers
+                                       | DMA_DCR_SSIZE(1) // 8-bit source transfers
+                                       | DMA_DCR_DSIZE(1); // 8-bit destination transfers
 
     dma->DMA[DMA_CHAN_START].DCR     = DMA_DCR_EINT_MASK // enable interrupt on end of transfer
                                        | DMA_DCR_ERQ_MASK
                                        | DMA_DCR_D_REQ_MASK // clear ERQ on end of transfer
                                        | DMA_DCR_SINC_MASK // increment source each transfer
                                        | DMA_DCR_CS_MASK
-                                       | DMA_DCR_SSIZE(0) // 32-bit source transfers
-                                       | DMA_DCR_DSIZE(0);
+                                       | DMA_DCR_SSIZE(1) // 8-bit source transfers
+                                       | DMA_DCR_DSIZE(1);
 
     tpm->SC |= TPM_SC_CMOD(1);         // enable internal clocking
 }
 
 void WS2811::writePixel(unsigned n, uint8_t *p)
 {
-    uint32_t *dest = dmaData.dmaWords + n * BITS_PER_RGB;
+    uint8_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
-void WS2811::writeByte(uint8_t byte, uint32_t mask, uint32_t *dest)
+void WS2811::writeByte(uint8_t byte, uint32_t mask, uint8_t *dest)
 {
     for (uint8_t bm = 0x80; bm; bm >>= 1) {
         // MSBit first
--- a/WS2811.h	Tue Apr 01 11:23:33 2014 +0000
+++ b/WS2811.h	Wed Apr 02 10:53:43 2014 +0000
@@ -19,7 +19,7 @@
 #include "mbed.h"
 #include "LedStrip.h"
 
-#define MAX_LEDS_PER_STRIP 60
+#define MAX_LEDS_PER_STRIP 240
 
 extern "C" void DMA0_IRQHandler();
 extern "C" void TPM0_IRQHandler();
@@ -47,7 +47,7 @@
     static volatile bool dma_done;
     static void wait_for_dma_done() { while (!dma_done) __WFI(); }
 
-    static void writeByte(uint8_t byte, uint32_t mask, uint32_t *dest);
+    static void writeByte(uint8_t byte, uint32_t mask, uint8_t *dest);
 
     static void hw_init();
         static void io_init();