#include "WS2812Serial.h" void WS2812Serial::begin() { if (!uart) return; if (!dma) dma = new DMAChannel; if (!dma) return; SIM_SCGC4 |= SIM_SCGC4_UART0; uint32_t divisor = BAUD2DIV(2400000); CORE_PIN1_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); UART0_BDH = (divisor >> 13) & 0x1F; UART0_BDL = (divisor >> 5) & 0xFF; UART0_C4 = divisor & 0x1F; UART0_C1 = 0; UART0_PFIFO = 0; UART0_C2 = UART_C2_TE; UART0_C3 = UART_C3_TXINV; UART0_C5 = UART_C5_TDMAS; memset(drawBuffer, 0, numled * 3); } void WS2812Serial::show() { //UART0_D = 0xDB; //UART0_D = 0xDA; //UART0_D = 0xDB; const uint8_t *p = drawBuffer; const uint8_t *end = p + (numled * 3); uint8_t *fb = frameBuffer; while (p < end) { uint8_t b = *p++; uint8_t g = *p++; uint8_t r = *p++; uint32_t n=0; switch (config) { case WS2812_RGB: n = (r << 16) | (g << 8) | b; break; case WS2812_RBG: n = (r << 16) | (b << 8) | g; break; case WS2812_GRB: n = (g << 16) | (r << 8) | b; break; case WS2812_GBR: n = (g << 16) | (b << 8) | r; break; case WS2812_BRG: n = (b << 16) | (r << 8) | g; break; case WS2812_BGR: n = (b << 16) | (g << 8) | r; break; } //Serial.printf("n = %06X\n", n); const uint8_t *stop = fb + 8; do { uint8_t x = 0x92; if (!(n & 0x00800000)) x |= 0x01; if (!(n & 0x00400000)) x |= 0x04; if (!(n & 0x00200000)) x |= 0x20; n <<= 3; *fb++ = x; } while (fb < stop); } dma->sourceBuffer(frameBuffer, numled * 8); dma->destination(UART0_D); dma->transferSize(1); dma->transferCount(numled * 8); dma->disableOnCompletion(); dma->triggerAtHardwareEvent(DMAMUX_SOURCE_UART0_TX); dma->enable(); UART0_C2 = UART_C2_TE | UART_C2_TIE; }