Browse Source

don't reorder pixel values

main_ledos
John Robinson 3 years ago
parent
commit
fea119f39c
No known key found for this signature in database
2 changed files with 37 additions and 82 deletions
  1. +35
    -43
      WS2812Serial.cpp
  2. +2
    -39
      WS2812Serial.h

+ 35
- 43
WS2812Serial.cpp View File

{ {
#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

+ 2
- 39
WS2812Serial.h View File

frameBuffer((uint8_t *)fb), drawBuffer((uint8_t *)db), dma(dma_chan) { frameBuffer((uint8_t *)fb), drawBuffer((uint8_t *)db), dma(dma_chan) {
} }
bool begin(); bool begin();
void setPixel(uint32_t num, uint32_t color) {
if (num >= numled) return;
if (config < 6) {
num *= 3;
drawBuffer[num+0] = color & 255;
drawBuffer[num+1] = (color >> 8) & 255;
drawBuffer[num+2] = (color >> 16) & 255;
} else {
num *= 4;
drawBuffer[num+0] = color & 255;
drawBuffer[num+1] = (color >> 8) & 255;
drawBuffer[num+2] = (color >> 16) & 255;
drawBuffer[num+3] = (color >> 24) & 255;
}
}
void setPixel(uint32_t num, uint8_t red, uint8_t green, uint8_t blue) {
setPixel(num, Color(red, green, blue));
}
void setPixel(uint32_t num, uint8_t red, uint8_t green, uint8_t blue, uint8_t white) {
setPixel(num, Color(red, green, blue, white));
}
void clear() { void clear() {
memset(drawBuffer, 0, numled * 3); memset(drawBuffer, 0, numled * 3);
}
}
void show(); void show();
bool busy(); bool busy();
uint16_t numPixels() { uint16_t numPixels() {
return numled; return numled;
} }
// Functions for compatibility with Adafruit_NeoPixel
void setPixelColor(uint16_t num, uint32_t color) {
setPixel(num, color);
}
void setPixelColor(uint16_t num, uint8_t red, uint8_t green, uint8_t blue) {
setPixel(num, red, green, blue);
}
void setPixelColor(uint16_t num, uint8_t red, uint8_t green, uint8_t blue, uint8_t white) {
setPixel(num, red, green, blue, white);
}
void setBrightness(uint8_t n) { void setBrightness(uint8_t n) {
brightness = n; brightness = n;
} }
uint8_t getBrightness() { uint8_t getBrightness() {
return brightness; return brightness;
} }
uint32_t Color(uint8_t red, uint8_t green, uint8_t blue) {
return (red << 16) | (green << 8) | blue;
}
uint32_t Color(uint8_t red, uint8_t green, uint8_t blue, uint8_t white) {
return (white << 24) | (red << 16) | (green << 8) | blue;
}
private: private:
const uint16_t numled; const uint16_t numled;
const uint8_t pin; const uint8_t pin;
uint32_t prior_micros = 0; uint32_t prior_micros = 0;
uint8_t brightness = 255; uint8_t brightness = 255;
#if defined(__IMXRT1062__) // Teensy 3.x #if defined(__IMXRT1062__) // Teensy 3.x
IMXRT_LPUART_t *uart = nullptr;
IMXRT_LPUART_t *uart = nullptr;
#endif #endif
}; };



Loading…
Cancel
Save