浏览代码

don't reorder pixel values

main_ledos
John Robinson 3 年前
父节点
当前提交
fea119f39c
找不到此签名对应的密钥
共有 2 个文件被更改,包括 37 次插入82 次删除
  1. +35
    -43
      WS2812Serial.cpp
  2. +2
    -39
      WS2812Serial.h

+ 35
- 43
WS2812Serial.cpp 查看文件

@@ -27,7 +27,7 @@ bool WS2812Serial::begin()
{
#if defined(__IMXRT1062__) // Teensy 3.x
uint32_t hwtrigger;
#else
#else
uint32_t divisor, portconfig, hwtrigger;
KINETISK_UART_t *uart;
#endif
@@ -97,7 +97,7 @@ bool WS2812Serial::begin()
#elif defined(KINETISL) // Teensy LC
case 1: // Serial1
case 5:
// NOT SURE HOW THIS WORKS ON LC?????
// NOT SURE HOW THIS WORKS ON LC?????
uart = &KINETISK_UART0;
divisor = 1;
portconfig = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3);
@@ -124,24 +124,24 @@ bool WS2812Serial::begin()
#if defined(ARDUINO_TEENSY41)
case 53:
#endif
uart = &IMXRT_LPUART6;
uart = &IMXRT_LPUART6;
CCM_CCGR3 |= CCM_CCGR3_LPUART6(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART6_TX;
hwtrigger = DMAMUX_SOURCE_LPUART6_TX;
break;
case 8: // Serial2
uart = &IMXRT_LPUART4;
uart = &IMXRT_LPUART4;
CCM_CCGR1 |= CCM_CCGR1_LPUART4(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART4_TX;
hwtrigger = DMAMUX_SOURCE_LPUART4_TX;
break;
case 14: // Serial3
uart = &IMXRT_LPUART2;
uart = &IMXRT_LPUART2;
CCM_CCGR0 |= CCM_CCGR0_LPUART2(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART2_TX;
hwtrigger = DMAMUX_SOURCE_LPUART2_TX;
break;
case 17: // Serial4
uart = &IMXRT_LPUART3;
uart = &IMXRT_LPUART3;
CCM_CCGR0 |= CCM_CCGR0_LPUART3(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART3_TX;
hwtrigger = DMAMUX_SOURCE_LPUART3_TX;
break;
case 20: // Serial5
#if defined(ARDUINO_TEENSY40)
@@ -149,27 +149,27 @@ bool WS2812Serial::begin()
#elif defined(ARDUINO_TEENSY41)
case 47:
#endif
uart = &IMXRT_LPUART8;
uart = &IMXRT_LPUART8;
CCM_CCGR6 |= CCM_CCGR6_LPUART8(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART8_TX;
hwtrigger = DMAMUX_SOURCE_LPUART8_TX;
break;
case 24: // Serial6
uart = &IMXRT_LPUART1;
uart = &IMXRT_LPUART1;
CCM_CCGR5 |= CCM_CCGR5_LPUART1(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART1_TX;
hwtrigger = DMAMUX_SOURCE_LPUART1_TX;
break;
case 29: // Serial7
uart = &IMXRT_LPUART7;
uart = &IMXRT_LPUART7;
CCM_CCGR5 |= CCM_CCGR5_LPUART7(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART7_TX;
hwtrigger = DMAMUX_SOURCE_LPUART7_TX;
break;
#if defined(ARDUINO_TEENSY41)
case 35:
uart = &IMXRT_LPUART5;
uart = &IMXRT_LPUART5;
CCM_CCGR3 |= CCM_CCGR3_LPUART5(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART5_TX;
hwtrigger = DMAMUX_SOURCE_LPUART5_TX;
break;
#endif
#endif
#endif
default:
return false; // pin not supported
@@ -180,13 +180,13 @@ bool WS2812Serial::begin()
}
#if defined(__IMXRT1062__)
// Convert Baud
// Computed values for 4mhz
// Computed values for 4mhz
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->PINCFG = 0;
uint16_t tx_fifo_size = (((uart->FIFO >> 4) & 0x7) << 2);
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->WATER = LPUART_WATER_TXWATER(tx_water);
uart->FIFO |= LPUART_FIFO_TXFE;
@@ -222,7 +222,7 @@ bool WS2812Serial::begin()
#endif
*(portConfigRegister(pin)) = portconfig;
dma->destination(uart->D);
#endif
#endif

dma->triggerAtHardwareEvent(hwtrigger);
memset(drawBuffer, 0, numled * 3);
@@ -256,28 +256,20 @@ void WS2812Serial::show()
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 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;
do {
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;
} while (fb < stop);
}
@@ -363,7 +355,7 @@ void WS2812Serial::show()
#elif defined(__IMXRT1062__)
// See if we need to muck with DMA cache...
if ((uint32_t)frameBuffer >= 0x20200000u) arm_dcache_flush(frameBuffer, numled * bytes_per_led);
dma->sourceBuffer(frameBuffer, numled * bytes_per_led);
// dma->transferSize(1);
dma->transferCount(numled * bytes_per_led);
@@ -372,7 +364,7 @@ void WS2812Serial::show()
/* 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,
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);
*/
uart->STAT = 0; // try clearing out the status

+ 2
- 39
WS2812Serial.h 查看文件

@@ -66,57 +66,20 @@ public:
frameBuffer((uint8_t *)fb), drawBuffer((uint8_t *)db), dma(dma_chan) {
}
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() {
memset(drawBuffer, 0, numled * 3);
}
}
void show();
bool busy();
uint16_t numPixels() {
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) {
brightness = n;
}
uint8_t getBrightness() {
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:
const uint16_t numled;
const uint8_t pin;
@@ -127,7 +90,7 @@ private:
uint32_t prior_micros = 0;
uint8_t brightness = 255;
#if defined(__IMXRT1062__) // Teensy 3.x
IMXRT_LPUART_t *uart = nullptr;
IMXRT_LPUART_t *uart = nullptr;
#endif
};


正在加载...
取消
保存