Pārlūkot izejas kodu

Merge pull request #8 from KurtE/T4

T4 Support
main_ledos
Paul Stoffregen pirms 5 gadiem
vecāks
revīzija
520b6bdc7f
Revīzijas autora e-pasta adrese nav piesaistīta nevienam kontam
5 mainītis faili ar 103 papildinājumiem un 9 dzēšanām
  1. +90
    -1
      WS2812Serial.cpp
  2. +3
    -0
      WS2812Serial.h
  3. +1
    -0
      examples/BasicTest/BasicTest.ino
  4. +1
    -0
      examples/FastLED_Cylon/FastLED_Cylon.ino
  5. +8
    -8
      readme.md

+ 90
- 1
WS2812Serial.cpp Parādīt failu

@@ -25,9 +25,12 @@

bool WS2812Serial::begin()
{
#if defined(__IMXRT1062__) // Teensy 3.x
uint32_t hwtrigger;
#else
uint32_t divisor, portconfig, hwtrigger;
KINETISK_UART_t *uart;

#endif
switch (pin) {
#if defined(KINETISK) // Teensy 3.x
case 1: // Serial1
@@ -94,6 +97,7 @@ bool WS2812Serial::begin()
#elif defined(KINETISL) // Teensy LC
case 1: // Serial1
case 5:
// NOT SURE HOW THIS WORKS ON LC?????
uart = &KINETISK_UART0;
divisor = 1;
portconfig = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3);
@@ -114,6 +118,44 @@ bool WS2812Serial::begin()
hwtrigger = DMAMUX_SOURCE_UART0_TX;
SIM_SCGC4 |= SIM_SCGC4_UART0;
break;

#elif defined(__IMXRT1062__)
case 1: // Serial1
uart = &IMXRT_LPUART6;
CCM_CCGR3 |= CCM_CCGR3_LPUART6(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART6_TX;
break;
case 8: // Serial2
uart = &IMXRT_LPUART4;
CCM_CCGR1 |= CCM_CCGR1_LPUART4(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART4_TX;
break;
case 14: // Serial3
uart = &IMXRT_LPUART2;
CCM_CCGR0 |= CCM_CCGR0_LPUART2(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART2_TX;
break;
case 17: // Serial4
uart = &IMXRT_LPUART3;
CCM_CCGR0 |= CCM_CCGR0_LPUART3(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART3_TX;
break;
case 20: // Serial5
case 39: // Serial5 alt
uart = &IMXRT_LPUART8;
CCM_CCGR6 |= CCM_CCGR6_LPUART8(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART8_TX;
break;
case 24: // Serial6
uart = &IMXRT_LPUART1;
CCM_CCGR5 |= CCM_CCGR5_LPUART1(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART1_TX;
break;
case 29: // Serial7
uart = &IMXRT_LPUART7;
CCM_CCGR5 |= CCM_CCGR5_LPUART7(CCM_CCGR_ON);
hwtrigger = DMAMUX_SOURCE_LPUART7_TX;
break;
#endif
default:
return false; // pin not supported
@@ -122,6 +164,27 @@ bool WS2812Serial::begin()
dma = new DMAChannel;
if (!dma) return false; // unable to allocate DMA channel
}
#if defined(__IMXRT1062__)
// Convert Baud
// 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->FIFO = 0; // disable the fifo.
uart->WATER = LPUART_WATER_TXWATER(tx_water);
uart->FIFO |= LPUART_FIFO_TXFE;

uart->CTRL = (LPUART_CTRL_TE /*| LPUART_CTRL_TIE */ | LPUART_CTRL_TXINV); // enable transmitter and invert
// We need to configure the TX pin now.
*(portControlRegister(pin)) = IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
*(portConfigRegister(pin)) = 2; // from hardware table for each one, but I think they are all 2...

dma->destination((volatile uint8_t&)uart->DATA);
//Serial.printf("HWTrigger: %x\n", hwtrigger);
#else
#if defined(KINETISK)
if (divisor < 32) divisor = 32;
uart->BDH = (divisor >> 13) & 0x1F;
@@ -141,6 +204,8 @@ bool WS2812Serial::begin()
#endif
*(portConfigRegister(pin)) = portconfig;
dma->destination(uart->D);
#endif

dma->triggerAtHardwareEvent(hwtrigger);
memset(drawBuffer, 0, numled * 3);
return true;
@@ -157,6 +222,12 @@ void WS2812Serial::show()
while ((dma->CFG->DCR & DMA_DCR_ERQ)) {
yield();
}
#elif defined(__IMXRT1062__)
//Serial.println("Show called");
while ((DMA_ERQ & (1 << dma->channel))) {
yield();
}
//Serial.println("After Yield");
#endif
// copy drawing buffer to frame buffer
const uint8_t *p = drawBuffer;
@@ -207,6 +278,24 @@ void WS2812Serial::show()
dma->CFG->DSR_BCR = numled * 12;
dma->CFG->DCR = DMA_DCR_ERQ | DMA_DCR_CS | DMA_DCR_SSIZE(1) |
DMA_DCR_SINC | DMA_DCR_DSIZE(1) | DMA_DCR_D_REQ;
#elif defined(__IMXRT1062__)
// See if we need to muck with DMA cache...
if ((uint32_t)frameBuffer >= 0x20200000u) arm_dcache_flush(frameBuffer, numled * 12);
dma->sourceBuffer(frameBuffer, numled * 12);
// dma->transferSize(1);
dma->transferCount(numled * 12);
dma->disableOnCompletion();

/* 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->DOFF, dma->TCD->CITER, dma->TCD->DLASTSGA, dma->TCD->CSR, dma->TCD->BITER);
*/
uart->STAT = 0; // try clearing out the status
dma->enable();

#endif
}


+ 3
- 0
WS2812Serial.h Parādīt failu

@@ -81,6 +81,9 @@ private:
uint8_t *drawBuffer;
DMAChannel *dma = nullptr;
uint32_t prior_micros = 0;
#if defined(__IMXRT1062__) // Teensy 3.x
IMXRT_LPUART_t *uart = nullptr;
#endif
};

#endif

+ 1
- 0
examples/BasicTest/BasicTest.ino Parādīt failu

@@ -14,6 +14,7 @@ const int pin = 1;
// Teensy 3.2: 1, 5, 8, 10, 31 (overclock to 120 MHz for pin 8)
// Teensy 3.5: 1, 5, 8, 10, 26, 32, 33, 48
// Teensy 3.6: 1, 5, 8, 10, 26, 32, 33
// Teensy 4.0: 1, 8, 14, 16, 20, 24, 29, 39

byte drawingMemory[numled*3]; // 3 bytes per LED
DMAMEM byte displayMemory[numled*12]; // 12 bytes per LED

+ 1
- 0
examples/FastLED_Cylon/FastLED_Cylon.ino Parādīt failu

@@ -12,6 +12,7 @@
// Teensy 3.2: 1, 5, 8, 10, 31 (overclock to 120 MHz for pin 8)
// Teensy 3.5: 1, 5, 8, 10, 26, 32, 33, 48
// Teensy 3.6: 1, 5, 8, 10, 26, 32, 33
// Teensy 4.0: 1, 8, 14, 16, 20, 24, 29, 39
#define DATA_PIN 1

// Define the array of leds

+ 8
- 8
readme.md Parādīt failu

@@ -25,14 +25,14 @@ used to transmit the data, making that port unavailable for other uses.

## Supported Pins & Serial Ports

| Port | Teensy LC | Teensy 3.2 | Teensy 3.5 | Teensy 3.6 |
| :------ | :---------: | :--------: | :--------: | :--------: |
| Serial1 | 1, 4, 5, 24 | 1, 5 | 1, 5, 26 | 1, 5, 26 |
| Serial2 | | 10, 31 | 10 | 10 |
| Serial3 | | 8 | 8 | 8 |
| Serial4 | | | 32 | 32 |
| Serial5 | | | 33 | 33 |
| Serial6 | | | 48 | |
| Port | Teensy LC | Teensy 3.2 | Teensy 3.5 | Teensy 3.6 | Teensy 4.0 |
| :------ | :---------: | :--------: | :--------: | :--------: | :--------: |
| Serial1 | 1, 4, 5, 24 | 1, 5 | 1, 5, 26 | 1, 5, 26 | 1 |
| Serial2 | | 10, 31 | 10 | 10 | 8 |
| Serial3 | | 8 | 8 | 8 | 14 |
| Serial4 | | | 32 | 32 | 17 |
| Serial5 | | | 33 | 33 | 20,39? |
| Serial6 | | | 48 | | 29 |

Serial2 & Serial3 on Teensy LC are not supported, due to lack of configurable
oversampling needed to run at the high speed required.

Notiek ielāde…
Atcelt
Saglabāt