Optimised fork of bikeNomad's WS2811 LED control library. Supports KL25Z and KL46Z
Fork of Multi_WS2811 by
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, committed 2014-04-02
- 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();
