|
|
|
|
|
|
|
|
{ |
|
|
{ |
|
|
#if defined(__IMXRT1062__) // Teensy 3.x |
|
|
#if defined(__IMXRT1062__) // Teensy 3.x |
|
|
uint32_t hwtrigger; |
|
|
uint32_t hwtrigger; |
|
|
#else |
|
|
|
|
|
|
|
|
#else |
|
|
uint32_t divisor, portconfig, hwtrigger; |
|
|
uint32_t divisor, portconfig, hwtrigger; |
|
|
KINETISK_UART_t *uart; |
|
|
KINETISK_UART_t *uart; |
|
|
#endif |
|
|
#endif |
|
|
|
|
|
|
|
|
#elif defined(KINETISL) // Teensy LC |
|
|
#elif defined(KINETISL) // Teensy LC |
|
|
case 1: // Serial1 |
|
|
case 1: // Serial1 |
|
|
case 5: |
|
|
case 5: |
|
|
// NOT SURE HOW THIS WORKS ON LC????? |
|
|
|
|
|
|
|
|
// NOT SURE HOW THIS WORKS ON LC????? |
|
|
uart = &KINETISK_UART0; |
|
|
uart = &KINETISK_UART0; |
|
|
divisor = 1; |
|
|
divisor = 1; |
|
|
portconfig = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); |
|
|
portconfig = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); |
|
|
|
|
|
|
|
|
#if defined(ARDUINO_TEENSY41) |
|
|
#if defined(ARDUINO_TEENSY41) |
|
|
case 53: |
|
|
case 53: |
|
|
#endif |
|
|
#endif |
|
|
uart = &IMXRT_LPUART6; |
|
|
|
|
|
|
|
|
uart = &IMXRT_LPUART6; |
|
|
CCM_CCGR3 |= CCM_CCGR3_LPUART6(CCM_CCGR_ON); |
|
|
CCM_CCGR3 |= CCM_CCGR3_LPUART6(CCM_CCGR_ON); |
|
|
hwtrigger = DMAMUX_SOURCE_LPUART6_TX; |
|
|
|
|
|
|
|
|
hwtrigger = DMAMUX_SOURCE_LPUART6_TX; |
|
|
break; |
|
|
break; |
|
|
case 8: // Serial2 |
|
|
case 8: // Serial2 |
|
|
uart = &IMXRT_LPUART4; |
|
|
|
|
|
|
|
|
uart = &IMXRT_LPUART4; |
|
|
CCM_CCGR1 |= CCM_CCGR1_LPUART4(CCM_CCGR_ON); |
|
|
CCM_CCGR1 |= CCM_CCGR1_LPUART4(CCM_CCGR_ON); |
|
|
hwtrigger = DMAMUX_SOURCE_LPUART4_TX; |
|
|
|
|
|
|
|
|
hwtrigger = DMAMUX_SOURCE_LPUART4_TX; |
|
|
break; |
|
|
break; |
|
|
case 14: // Serial3 |
|
|
case 14: // Serial3 |
|
|
uart = &IMXRT_LPUART2; |
|
|
|
|
|
|
|
|
uart = &IMXRT_LPUART2; |
|
|
CCM_CCGR0 |= CCM_CCGR0_LPUART2(CCM_CCGR_ON); |
|
|
CCM_CCGR0 |= CCM_CCGR0_LPUART2(CCM_CCGR_ON); |
|
|
hwtrigger = DMAMUX_SOURCE_LPUART2_TX; |
|
|
|
|
|
|
|
|
hwtrigger = DMAMUX_SOURCE_LPUART2_TX; |
|
|
break; |
|
|
break; |
|
|
case 17: // Serial4 |
|
|
case 17: // Serial4 |
|
|
uart = &IMXRT_LPUART3; |
|
|
|
|
|
|
|
|
uart = &IMXRT_LPUART3; |
|
|
CCM_CCGR0 |= CCM_CCGR0_LPUART3(CCM_CCGR_ON); |
|
|
CCM_CCGR0 |= CCM_CCGR0_LPUART3(CCM_CCGR_ON); |
|
|
hwtrigger = DMAMUX_SOURCE_LPUART3_TX; |
|
|
|
|
|
|
|
|
hwtrigger = DMAMUX_SOURCE_LPUART3_TX; |
|
|
break; |
|
|
break; |
|
|
case 20: // Serial5 |
|
|
case 20: // Serial5 |
|
|
#if defined(ARDUINO_TEENSY40) |
|
|
#if defined(ARDUINO_TEENSY40) |
|
|
|
|
|
|
|
|
#elif defined(ARDUINO_TEENSY41) |
|
|
#elif defined(ARDUINO_TEENSY41) |
|
|
case 47: |
|
|
case 47: |
|
|
#endif |
|
|
#endif |
|
|
uart = &IMXRT_LPUART8; |
|
|
|
|
|
|
|
|
uart = &IMXRT_LPUART8; |
|
|
CCM_CCGR6 |= CCM_CCGR6_LPUART8(CCM_CCGR_ON); |
|
|
CCM_CCGR6 |= CCM_CCGR6_LPUART8(CCM_CCGR_ON); |
|
|
hwtrigger = DMAMUX_SOURCE_LPUART8_TX; |
|
|
|
|
|
|
|
|
hwtrigger = DMAMUX_SOURCE_LPUART8_TX; |
|
|
break; |
|
|
break; |
|
|
case 24: // Serial6 |
|
|
case 24: // Serial6 |
|
|
uart = &IMXRT_LPUART1; |
|
|
|
|
|
|
|
|
uart = &IMXRT_LPUART1; |
|
|
CCM_CCGR5 |= CCM_CCGR5_LPUART1(CCM_CCGR_ON); |
|
|
CCM_CCGR5 |= CCM_CCGR5_LPUART1(CCM_CCGR_ON); |
|
|
hwtrigger = DMAMUX_SOURCE_LPUART1_TX; |
|
|
|
|
|
|
|
|
hwtrigger = DMAMUX_SOURCE_LPUART1_TX; |
|
|
break; |
|
|
break; |
|
|
case 29: // Serial7 |
|
|
case 29: // Serial7 |
|
|
uart = &IMXRT_LPUART7; |
|
|
|
|
|
|
|
|
uart = &IMXRT_LPUART7; |
|
|
CCM_CCGR5 |= CCM_CCGR5_LPUART7(CCM_CCGR_ON); |
|
|
CCM_CCGR5 |= CCM_CCGR5_LPUART7(CCM_CCGR_ON); |
|
|
hwtrigger = DMAMUX_SOURCE_LPUART7_TX; |
|
|
|
|
|
|
|
|
hwtrigger = DMAMUX_SOURCE_LPUART7_TX; |
|
|
break; |
|
|
break; |
|
|
#if defined(ARDUINO_TEENSY41) |
|
|
#if defined(ARDUINO_TEENSY41) |
|
|
case 35: |
|
|
case 35: |
|
|
uart = &IMXRT_LPUART5; |
|
|
|
|
|
|
|
|
uart = &IMXRT_LPUART5; |
|
|
CCM_CCGR3 |= CCM_CCGR3_LPUART5(CCM_CCGR_ON); |
|
|
CCM_CCGR3 |= CCM_CCGR3_LPUART5(CCM_CCGR_ON); |
|
|
hwtrigger = DMAMUX_SOURCE_LPUART5_TX; |
|
|
|
|
|
|
|
|
hwtrigger = DMAMUX_SOURCE_LPUART5_TX; |
|
|
break; |
|
|
break; |
|
|
#endif |
|
|
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|
#endif |
|
|
default: |
|
|
default: |
|
|
return false; // pin not supported |
|
|
return false; // pin not supported |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
#if defined(__IMXRT1062__) |
|
|
#if defined(__IMXRT1062__) |
|
|
// Convert Baud |
|
|
// Convert Baud |
|
|
// Computed values for 4mhz |
|
|
|
|
|
|
|
|
// Computed values for 4mhz |
|
|
uart->CTRL = 0; // clear everything |
|
|
uart->CTRL = 0; // clear everything |
|
|
uart->BAUD = LPUART_BAUD_OSR(5) | LPUART_BAUD_SBR(1) | LPUART_BAUD_TDMAE; // set baud configure for transfer DMA |
|
|
uart->BAUD = LPUART_BAUD_OSR(5) | LPUART_BAUD_SBR(1) | LPUART_BAUD_TDMAE; // set baud configure for transfer DMA |
|
|
uart->PINCFG = 0; |
|
|
uart->PINCFG = 0; |
|
|
uint16_t tx_fifo_size = (((uart->FIFO >> 4) & 0x7) << 2); |
|
|
uint16_t tx_fifo_size = (((uart->FIFO >> 4) & 0x7) << 2); |
|
|
uint8_t tx_water = (tx_fifo_size < 16) ? tx_fifo_size >> 1 : 7; |
|
|
uint8_t tx_water = (tx_fifo_size < 16) ? tx_fifo_size >> 1 : 7; |
|
|
// uart->WATER = LPUART_WATER_TXWATER(1); // guessing here? |
|
|
|
|
|
|
|
|
// uart->WATER = LPUART_WATER_TXWATER(1); // guessing here? |
|
|
// uart->FIFO = 0; // disable the fifo. |
|
|
// uart->FIFO = 0; // disable the fifo. |
|
|
uart->WATER = LPUART_WATER_TXWATER(tx_water); |
|
|
uart->WATER = LPUART_WATER_TXWATER(tx_water); |
|
|
uart->FIFO |= LPUART_FIFO_TXFE; |
|
|
uart->FIFO |= LPUART_FIFO_TXFE; |
|
|
|
|
|
|
|
|
#endif |
|
|
#endif |
|
|
*(portConfigRegister(pin)) = portconfig; |
|
|
*(portConfigRegister(pin)) = portconfig; |
|
|
dma->destination(uart->D); |
|
|
dma->destination(uart->D); |
|
|
#endif |
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
dma->triggerAtHardwareEvent(hwtrigger); |
|
|
dma->triggerAtHardwareEvent(hwtrigger); |
|
|
memset(drawBuffer, 0, numled * 3); |
|
|
memset(drawBuffer, 0, numled * 3); |
|
|
|
|
|
|
|
|
const uint8_t *end = p + (numled * 3); |
|
|
const uint8_t *end = p + (numled * 3); |
|
|
uint8_t *fb = frameBuffer; |
|
|
uint8_t *fb = frameBuffer; |
|
|
while (p < end) { |
|
|
while (p < end) { |
|
|
uint8_t b = *p++; |
|
|
|
|
|
uint8_t g = *p++; |
|
|
|
|
|
uint8_t r = *p++; |
|
|
|
|
|
uint32_t mult = brightness + 1; |
|
|
|
|
|
b = (b * mult) >> 8; |
|
|
|
|
|
g = (g * mult) >> 8; |
|
|
|
|
|
r = (r * mult) >> 8; |
|
|
|
|
|
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; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
union pixel |
|
|
|
|
|
{ |
|
|
|
|
|
uint8_t b[4]; |
|
|
|
|
|
uint32_t n; |
|
|
|
|
|
} pix; |
|
|
|
|
|
pix.b[1] = *p++; |
|
|
|
|
|
pix.b[2] = *p++; |
|
|
|
|
|
pix.b[0] = *p++; |
|
|
const uint8_t *stop = fb + 12; |
|
|
const uint8_t *stop = fb + 12; |
|
|
do { |
|
|
do { |
|
|
uint8_t x = 0x08; |
|
|
uint8_t x = 0x08; |
|
|
if (!(n & 0x00800000)) x |= 0x07; |
|
|
|
|
|
if (!(n & 0x00400000)) x |= 0xE0; |
|
|
|
|
|
n <<= 2; |
|
|
|
|
|
|
|
|
if (!(pix.n & 0x00800000)) x |= 0x07; |
|
|
|
|
|
if (!(pix.n & 0x00400000)) x |= 0xE0; |
|
|
|
|
|
pix.n <<= 2; |
|
|
*fb++ = x; |
|
|
*fb++ = x; |
|
|
} while (fb < stop); |
|
|
} while (fb < stop); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
#elif defined(__IMXRT1062__) |
|
|
#elif defined(__IMXRT1062__) |
|
|
// See if we need to muck with DMA cache... |
|
|
// See if we need to muck with DMA cache... |
|
|
if ((uint32_t)frameBuffer >= 0x20200000u) arm_dcache_flush(frameBuffer, numled * bytes_per_led); |
|
|
if ((uint32_t)frameBuffer >= 0x20200000u) arm_dcache_flush(frameBuffer, numled * bytes_per_led); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
dma->sourceBuffer(frameBuffer, numled * bytes_per_led); |
|
|
dma->sourceBuffer(frameBuffer, numled * bytes_per_led); |
|
|
// dma->transferSize(1); |
|
|
// dma->transferSize(1); |
|
|
dma->transferCount(numled * bytes_per_led); |
|
|
dma->transferCount(numled * bytes_per_led); |
|
|
|
|
|
|
|
|
/* Serial.printf("%x %x:", (uint32_t)dma, (uint32_t)dma->TCD); |
|
|
/* Serial.printf("%x %x:", (uint32_t)dma, (uint32_t)dma->TCD); |
|
|
|
|
|
|
|
|
Serial.printf("SA:%x SO:%d AT:%x NB:%x SL:%d DA:%x DO: %d CI:%x DL:%x CS:%x BI:%x\n", (uint32_t)dma->TCD->SADDR, |
|
|
Serial.printf("SA:%x SO:%d AT:%x NB:%x SL:%d DA:%x DO: %d CI:%x DL:%x CS:%x BI:%x\n", (uint32_t)dma->TCD->SADDR, |
|
|
dma->TCD->SOFF, dma->TCD->ATTR, dma->TCD->NBYTES, dma->TCD->SLAST, (uint32_t)dma->TCD->DADDR, |
|
|
|
|
|
|
|
|
dma->TCD->SOFF, dma->TCD->ATTR, dma->TCD->NBYTES, dma->TCD->SLAST, (uint32_t)dma->TCD->DADDR, |
|
|
dma->TCD->DOFF, dma->TCD->CITER, dma->TCD->DLASTSGA, dma->TCD->CSR, dma->TCD->BITER); |
|
|
dma->TCD->DOFF, dma->TCD->CITER, dma->TCD->DLASTSGA, dma->TCD->CSR, dma->TCD->BITER); |
|
|
*/ |
|
|
*/ |
|
|
uart->STAT = 0; // try clearing out the status |
|
|
uart->STAT = 0; // try clearing out the status |