Просмотр исходного кода

Merge pull request #8 from KurtE/T4

T4 Support
main_ledos
Paul Stoffregen 6 лет назад
Родитель
Сommit
520b6bdc7f
Аккаунт пользователя с таким Email не найден
5 измененных файлов: 103 добавлений и 9 удалений
  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 Просмотреть файл



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 Просмотреть файл

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 Просмотреть файл

// 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 Просмотреть файл

// 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 Просмотреть файл



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

Загрузка…
Отмена
Сохранить