ソースを参照

Constructor using pin number rather than port name

main_ledos
PaulStoffregen 7年前
コミット
47638d1f00
2個のファイルの変更37行の追加37行の削除
  1. +32
    -30
      WS2812Serial.cpp
  2. +5
    -7
      WS2812Serial.h

+ 32
- 30
WS2812Serial.cpp ファイルの表示

@@ -1,37 +1,45 @@

#include "WS2812Serial.h"

void WS2812Serial::begin()
bool 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;
uint32_t divisor, portconfig, hwtrigger;
KINETISK_UART_t *uart;

switch (pin) {
case 1:
uart = &KINETISK_UART0;
divisor = BAUD2DIV(2400000);
portconfig = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3);
hwtrigger = DMAMUX_SOURCE_UART0_TX;
SIM_SCGC4 |= SIM_SCGC4_UART0;
break;
default:
return false; // pin not supported
}
if (!dma) {
dma = new DMAChannel;
if (!dma) return false; // unable to allocate DMA channel
}
uart->BDH = (divisor >> 13) & 0x1F;
uart->BDL = (divisor >> 5) & 0xFF;
uart->C4 = divisor & 0x1F;
uart->C1 = 0;
uart->PFIFO = 0;
uart->C2 = UART_C2_TE | UART_C2_TIE;
uart->C3 = UART_C3_TXINV;
uart->C5 = UART_C5_TDMAS;
*(portConfigRegister(pin)) = portconfig;
dma->destination(uart->D);
dma->triggerAtHardwareEvent(hwtrigger);
memset(drawBuffer, 0, numled * 3);
return true;
}

void WS2812Serial::show()
{

//UART0_D = 0xDB;
//UART0_D = 0xDA;
//UART0_D = 0xDB;
// TODO: wait if prior DMA in progress
// TODO: wait 300us WS2812 reset time
const uint8_t *p = drawBuffer;
const uint8_t *end = p + (numled * 3);
uint8_t *fb = frameBuffer;
@@ -48,7 +56,6 @@ void WS2812Serial::show()
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;
@@ -59,15 +66,10 @@ void WS2812Serial::show()
*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;
}



+ 5
- 7
WS2812Serial.h ファイルの表示

@@ -13,13 +13,11 @@

class WS2812Serial {
public:
constexpr WS2812Serial(uint16_t n, void *f, void *d, HardwareSerial &s, uint8_t c) :
numled(n), config(c),
frameBuffer((uint8_t *)f), drawBuffer((uint8_t *)d),
uart( &s == &Serial1 ? &KINETISK_UART0 : nullptr)
{
constexpr WS2812Serial(uint16_t num, void *fb, void *db, uint8_t pin, uint8_t cfg) :
numled(num), pin(pin), config(cfg),
frameBuffer((uint8_t *)fb), drawBuffer((uint8_t *)db) {
}
void begin();
bool begin();
void setPixel(uint32_t num, int color) {
if (num >= numled) return;
num *= 3;
@@ -41,10 +39,10 @@ public:
}
private:
const uint16_t numled;
const uint8_t pin;
const uint8_t config;
uint8_t *frameBuffer;
uint8_t *drawBuffer;
KINETISK_UART_t *uart;
DMAChannel *dma = nullptr;
};


読み込み中…
キャンセル
保存