Selaa lähdekoodia

Merge pull request #8 from KurtE/T4

T4 Support
main_ledos
Paul Stoffregen 5 vuotta sitten
vanhempi
commit
520b6bdc7f
No account linked to committer's email address
5 muutettua tiedostoa jossa 103 lisäystä ja 9 poistoa
  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 Näytä tiedosto



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

#endif
switch (pin) { switch (pin) {
#if defined(KINETISK) // Teensy 3.x #if defined(KINETISK) // Teensy 3.x
case 1: // Serial1 case 1: // Serial1
#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?????
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);
hwtrigger = DMAMUX_SOURCE_UART0_TX; hwtrigger = DMAMUX_SOURCE_UART0_TX;
SIM_SCGC4 |= SIM_SCGC4_UART0; SIM_SCGC4 |= SIM_SCGC4_UART0;
break; 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 #endif
default: default:
return false; // pin not supported return false; // pin not supported
dma = new DMAChannel; dma = new DMAChannel;
if (!dma) return false; // unable to allocate DMA channel 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 defined(KINETISK)
if (divisor < 32) divisor = 32; if (divisor < 32) divisor = 32;
uart->BDH = (divisor >> 13) & 0x1F; uart->BDH = (divisor >> 13) & 0x1F;
#endif #endif
*(portConfigRegister(pin)) = portconfig; *(portConfigRegister(pin)) = portconfig;
dma->destination(uart->D); dma->destination(uart->D);
#endif

dma->triggerAtHardwareEvent(hwtrigger); dma->triggerAtHardwareEvent(hwtrigger);
memset(drawBuffer, 0, numled * 3); memset(drawBuffer, 0, numled * 3);
return true; return true;
while ((dma->CFG->DCR & DMA_DCR_ERQ)) { while ((dma->CFG->DCR & DMA_DCR_ERQ)) {
yield(); yield();
} }
#elif defined(__IMXRT1062__)
//Serial.println("Show called");
while ((DMA_ERQ & (1 << dma->channel))) {
yield();
}
//Serial.println("After Yield");
#endif #endif
// copy drawing buffer to frame buffer // copy drawing buffer to frame buffer
const uint8_t *p = drawBuffer; const uint8_t *p = drawBuffer;
dma->CFG->DSR_BCR = numled * 12; dma->CFG->DSR_BCR = numled * 12;
dma->CFG->DCR = DMA_DCR_ERQ | DMA_DCR_CS | DMA_DCR_SSIZE(1) | dma->CFG->DCR = DMA_DCR_ERQ | DMA_DCR_CS | DMA_DCR_SSIZE(1) |
DMA_DCR_SINC | DMA_DCR_DSIZE(1) | DMA_DCR_D_REQ; 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 #endif
} }



+ 3
- 0
WS2812Serial.h Näytä tiedosto

uint8_t *drawBuffer; uint8_t *drawBuffer;
DMAChannel *dma = nullptr; DMAChannel *dma = nullptr;
uint32_t prior_micros = 0; uint32_t prior_micros = 0;
#if defined(__IMXRT1062__) // Teensy 3.x
IMXRT_LPUART_t *uart = nullptr;
#endif
}; };


#endif #endif

+ 1
- 0
examples/BasicTest/BasicTest.ino Näytä tiedosto

// Teensy 3.2: 1, 5, 8, 10, 31 (overclock to 120 MHz for pin 8) // 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.5: 1, 5, 8, 10, 26, 32, 33, 48
// Teensy 3.6: 1, 5, 8, 10, 26, 32, 33 // 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 byte drawingMemory[numled*3]; // 3 bytes per LED
DMAMEM byte displayMemory[numled*12]; // 12 bytes per LED DMAMEM byte displayMemory[numled*12]; // 12 bytes per LED

+ 1
- 0
examples/FastLED_Cylon/FastLED_Cylon.ino Näytä tiedosto

// Teensy 3.2: 1, 5, 8, 10, 31 (overclock to 120 MHz for pin 8) // 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.5: 1, 5, 8, 10, 26, 32, 33, 48
// Teensy 3.6: 1, 5, 8, 10, 26, 32, 33 // 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 DATA_PIN 1


// Define the array of leds // Define the array of leds

+ 8
- 8
readme.md Näytä tiedosto



## Supported Pins & Serial Ports ## 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 Serial2 & Serial3 on Teensy LC are not supported, due to lack of configurable
oversampling needed to run at the high speed required. oversampling needed to run at the high speed required.

Loading…
Peruuta
Tallenna