From e82dba6210c2eb59967d6ac4341004e74e41493d Mon Sep 17 00:00:00 2001 From: PaulStoffregen Date: Fri, 25 Feb 2022 07:27:48 -0800 Subject: [PATCH] Add support for Teensy 4 --- Tlc5940.cpp | 35 ++++++++++++++++++++++++++++++++++- Tlc5940.h | 7 +++++++ pinouts/Teensy_IMXRT.h | 37 +++++++++++++++++++++++++++++++++++++ pinouts/chip_includes.h | 4 ++++ pinouts/pin_functions.h | 4 +++- 5 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 pinouts/Teensy_IMXRT.h diff --git a/Tlc5940.cpp b/Tlc5940.cpp index 179a933..e1bf9bf 100644 --- a/Tlc5940.cpp +++ b/Tlc5940.cpp @@ -71,13 +71,20 @@ ISR(TIMER1_OVF_vect) } #elif defined(__arm__) && defined(TEENSYDUINO) +#if defined(__IMXRT1062__) +void flexpwm42_isr(void) +{ + FLEXPWM4_SM2STS = FLEXPWM_SMSTS_RF; + Tlc5940_interrupt(); +} +#else void ftm1_isr(void) { uint32_t sc = FTM1_SC; if (sc & 0x80) FTM1_SC = sc & 0x7F; Tlc5940_interrupt(); } - +#endif #endif /** \defgroup ReqVPRG_ENABLED Functions that Require VPRG_ENABLED @@ -162,6 +169,31 @@ void Tlc5940::init(uint16_t initialValue) TCCR1B |= _BV(CS10); // no prescale, (start pwm output) #elif defined(__arm__) && defined(TEENSYDUINO) + #if defined(__IMXRT1062__) + /* Teensy 4.0, 4.1, MicroMod */ + clear_pin(XLAT_DDR, XLAT_PIN); + analogWriteFrequency(5, 4000000); + analogWrite(5, 128); + const uint32_t newdiv = (uint32_t)((float)F_BUS_ACTUAL / 4 / 1000 + 0.5f); + FLEXPWM4_MCTRL |= FLEXPWM_MCTRL_CLDOK(4); + FLEXPWM4_SM2CTRL = FLEXPWM_SMCTRL_FULL | FLEXPWM_SMCTRL_PRSC(2); // 3146 + FLEXPWM4_SM2VAL0 = newdiv - 1; + FLEXPWM4_SM2VAL1 = newdiv - 1; + FLEXPWM4_SM2VAL2 = newdiv - 7; // pin 2 = FlexPWM4_2_A = BLANK + FLEXPWM4_SM2VAL3 = newdiv - 1; + FLEXPWM4_SM2VAL4 = newdiv - 6; // pin 3 = FlexPWM4_2_B = XLAT + FLEXPWM4_SM2VAL5 = newdiv - 2; + FLEXPWM4_OUTEN = FLEXPWM_OUTEN_PWMA_EN(4) | FLEXPWM_OUTEN_PWMB_EN(4); + FLEXPWM4_MCTRL |= FLEXPWM_MCTRL_LDOK(4); + CORE_PIN2_CONFIG = 1; + CORE_PIN2_PADCONFIG = IOMUXC_PAD_DSE(7); + CORE_PIN3_PADCONFIG = IOMUXC_PAD_DSE(7); + FLEXPWM4_SM2INTEN = 0; + FLEXPWM4_SM2STS = 0x3FFF; + attachInterruptVector(IRQ_FLEXPWM4_2, flexpwm42_isr); + NVIC_ENABLE_IRQ(IRQ_FLEXPWM4_2); + #else + /* Teensy 3.0, 3.1, 3.2, 3.5, 3.6 */ clear_pin(XLAT_DDR, XLAT_PIN); SIM_SCGC4 |= SIM_SCGC4_CMT; CMT_MSC = 0; @@ -185,6 +217,7 @@ void Tlc5940::init(uint16_t initialValue) FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS; NVIC_ENABLE_IRQ(IRQ_FTM1); CORE_PIN4_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE; + #endif #endif update(); } diff --git a/Tlc5940.h b/Tlc5940.h index c3507cf..2a1cdd3 100644 --- a/Tlc5940.h +++ b/Tlc5940.h @@ -50,10 +50,17 @@ #define disable_XLAT_pulses() TCCR1A = _BV(COM1B1) #elif defined(__arm__) && defined(TEENSYDUINO) +#if defined(__IMXRT1062__) +#define set_XLAT_interrupt() FLEXPWM4_SM2STS = FLEXPWM_SMSTS_RF; FLEXPWM4_SM2INTEN = FLEXPWM_SMINTEN_RIE; +#define clear_XLAT_interrupt() FLEXPWM4_SM2INTEN = 0; +#define enable_XLAT_pulses() CORE_PIN3_CONFIG = 1; +#define disable_XLAT_pulses() CORE_PIN3_CONFIG = 5; +#else #define set_XLAT_interrupt() FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS | FTM_SC_TOIE | (FTM1_SC & FTM_SC_PS(7)) #define clear_XLAT_interrupt() FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_CPWMS | (FTM1_SC & FTM_SC_PS(7)) #define enable_XLAT_pulses() CORE_PIN3_CONFIG = PORT_PCR_MUX(3)|PORT_PCR_DSE|PORT_PCR_SRE #define disable_XLAT_pulses() CORE_PIN3_CONFIG = PORT_PCR_MUX(1)|PORT_PCR_DSE|PORT_PCR_SRE +#endif #endif diff --git a/pinouts/Teensy_IMXRT.h b/pinouts/Teensy_IMXRT.h new file mode 100644 index 0000000..3e7f1c2 --- /dev/null +++ b/pinouts/Teensy_IMXRT.h @@ -0,0 +1,37 @@ +#ifndef TLC_Teensy_IMXRT_h +#define TLC_Teensy_IMXRT_h + +// bitbang I/O is pretty fast on Teensy 3.1 +// and avoids SPI sharing problems +#ifdef DATA_TRANSFER_MODE +#undef DATA_TRANSFER_MODE +#endif +#define DATA_TRANSFER_MODE TLC_BITBANG + +// Teensy pin 6 -> SIN (TLC pin 26) +#define DEFAULT_BB_SIN_PIN 6 +#define DEFAULT_BB_SIN_PORT 6 +#define DEFAULT_BB_SIN_DDR 6 + +// Teensy pin 7 -> SCLK (TLC pin 25) +#define DEFAULT_BB_SCLK_PIN 7 +#define DEFAULT_BB_SCLK_PORT 7 +#define DEFAULT_BB_SCLK_DDR 7 + +// FTM1_CH0 (Teensy pin 3) -> XLAT (TLC pin 24) +#define XLAT_PIN 3 +#define XLAT_PORT 3 +#define XLAT_DDR 3 + +// FTM1_CH1 (Teensy pin 4) -> BLANK (TLC pin 23) +#define BLANK_PIN 2 +#define BLANK_PORT 2 +#define BLANK_DDR 2 + +// CMTOUT (Teensy pin 5) -> GSCLK (TLC pin 18) +#define GSCLK_PIN 5 +#define GSCLK_PORT 5 +#define GSCLK_DDR 5 + + +#endif diff --git a/pinouts/chip_includes.h b/pinouts/chip_includes.h index 32e8da3..b831a93 100644 --- a/pinouts/chip_includes.h +++ b/pinouts/chip_includes.h @@ -120,6 +120,10 @@ /* Teensy 3.0 & 3.1 & 3.2 & 3.5 & 3.6*/ #include "Teensy_KinetisK20.h" +#elif defined (__IMXRT1062__) + +/* Teensy 4.0, 4.1, MicroMod */ +#include "Teensy_IMXRT.h" #else #error "Unknown Chip!" diff --git a/pinouts/pin_functions.h b/pinouts/pin_functions.h index 223c93b..b0f6bd8 100644 --- a/pinouts/pin_functions.h +++ b/pinouts/pin_functions.h @@ -8,7 +8,9 @@ #define output_pin(ddr, pin) ddr |= _BV(pin) #define pullup_pin(ddr, port, pin) ddr &= ~_BV(pin); port |= _BV(pin) #elif defined(TEENSYDUINO) - #if F_CPU > 48000000 + #if F_CPU > 120000000 + #define pulse_pin(port, pin) delayNanoseconds(10); digitalWriteFast(pin, HIGH); delayNanoseconds(20); digitalWriteFast(pin, LOW) + #elif F_CPU > 48000000 #define pulse_pin(port, pin) digitalWriteFast(pin, HIGH); asm("nop"); digitalWriteFast(pin, LOW) #else #define pulse_pin(port, pin) digitalWriteFast(pin, HIGH); digitalWriteFast(pin, LOW)