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)

Revision:
2:1c2c9c8788a8
Parent:
1:7b2d0ea091fb
Child:
6:3b5b8a367f40
diff -r 7b2d0ea091fb -r 1c2c9c8788a8 WS2811.cpp
--- 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