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