diff --git a/teensy/FS.h b/teensy/FS.h index b4ea60d0..dd8c43af 100644 --- a/teensy/FS.h +++ b/teensy/FS.h @@ -265,6 +265,7 @@ class FS { public: FS() {} + virtual ~FS() {} virtual File open(const char *filename, uint8_t mode = FILE_READ) = 0; virtual bool exists(const char *filepath) = 0; virtual bool mkdir(const char *filepath) = 0; diff --git a/teensy3/FS.h b/teensy3/FS.h index 5672f38c..71e3726a 100644 --- a/teensy3/FS.h +++ b/teensy3/FS.h @@ -271,6 +271,7 @@ class FS { public: FS() {} + virtual ~FS() {} virtual File open(const char *filename, uint8_t mode = FILE_READ) = 0; virtual bool exists(const char *filepath) = 0; virtual bool mkdir(const char *filepath) = 0; diff --git a/teensy3/HardwareSerial.h b/teensy3/HardwareSerial.h index afa16d7a..f6dd5703 100644 --- a/teensy3/HardwareSerial.h +++ b/teensy3/HardwareSerial.h @@ -282,10 +282,7 @@ class HardwareSerial : public Stream #else //(__MK64FX512__) || defined(__MK66FX1M0__) enum {CNT_HARDWARE_SERIAL = 3}; #endif - virtual void begin(uint32_t baud); - virtual void begin(uint32_t baud, uint32_t format) { - serial_begin(BAUD2DIV(baud)); - serial_format(format); } + virtual void begin(uint32_t baud, uint32_t format=(uint32_t)-1); virtual void end(void) { serial_end(); } virtual void transmitterEnable(uint8_t pin) { serial_set_transmit_pin(pin); } virtual void setRX(uint8_t pin) { serial_set_rx(pin); } @@ -336,10 +333,7 @@ class HardwareSerial2 : public HardwareSerial { public: constexpr HardwareSerial2(void (* const se)()) : HardwareSerial(se) {} - virtual void begin(uint32_t baud); - virtual void begin(uint32_t baud, uint32_t format) { - serial2_begin(BAUD2DIV2(baud)); - serial2_format(format); } + virtual void begin(uint32_t baud, uint32_t format=(uint32_t)-1); virtual void end(void) { serial2_end(); } virtual void transmitterEnable(uint8_t pin) { serial2_set_transmit_pin(pin); } virtual void setRX(uint8_t pin) { serial2_set_rx(pin); } @@ -375,10 +369,7 @@ class HardwareSerial3 : public HardwareSerial { public: constexpr HardwareSerial3(void (* const se)()) : HardwareSerial(se) {} - virtual void begin(uint32_t baud); - virtual void begin(uint32_t baud, uint32_t format) { - serial3_begin(BAUD2DIV3(baud)); - serial3_format(format); } + virtual void begin(uint32_t baud, uint32_t format=(uint32_t)-1); virtual void end(void) { serial3_end(); } virtual void transmitterEnable(uint8_t pin) { serial3_set_transmit_pin(pin); } virtual void setRX(uint8_t pin) { serial3_set_rx(pin); } @@ -414,10 +405,7 @@ class HardwareSerial4 : public HardwareSerial { public: constexpr HardwareSerial4(void (* const se)()) : HardwareSerial(se) {} - virtual void begin(uint32_t baud); - virtual void begin(uint32_t baud, uint32_t format) { - serial4_begin(BAUD2DIV3(baud)); - serial4_format(format); } + virtual void begin(uint32_t baud, uint32_t format=(uint32_t)-1); virtual void end(void) { serial4_end(); } virtual void transmitterEnable(uint8_t pin) { serial4_set_transmit_pin(pin); } virtual void setRX(uint8_t pin) { serial4_set_rx(pin); } @@ -453,10 +441,7 @@ class HardwareSerial5 : public HardwareSerial { public: constexpr HardwareSerial5(void (* const se)()) : HardwareSerial(se) {} - virtual void begin(uint32_t baud); - virtual void begin(uint32_t baud, uint32_t format) { - serial5_begin(BAUD2DIV3(baud)); - serial5_format(format); } + virtual void begin(uint32_t baud, uint32_t format=(uint32_t)-1); virtual void end(void) { serial5_end(); } virtual void transmitterEnable(uint8_t pin) { serial5_set_transmit_pin(pin); } virtual void setRX(uint8_t pin) { serial5_set_rx(pin); } @@ -492,17 +477,7 @@ class HardwareSerial6 : public HardwareSerial { public: constexpr HardwareSerial6(void (* const se)()) : HardwareSerial(se) {} -#if defined(__MK66FX1M0__) // For LPUART just pass baud straight in. - virtual void begin(uint32_t baud); - virtual void begin(uint32_t baud, uint32_t format) { - serial6_begin(baud); - serial6_format(format); } -#else - virtual void begin(uint32_t baud); - virtual void begin(uint32_t baud, uint32_t format) { - serial6_begin(BAUD2DIV3(baud)); - serial6_format(format); } -#endif + virtual void begin(uint32_t baud, uint32_t format=(uint32_t)-1); virtual void end(void) { serial6_end(); } virtual void transmitterEnable(uint8_t pin) { serial6_set_transmit_pin(pin); } virtual void setRX(uint8_t pin) { serial6_set_rx(pin); } diff --git a/teensy3/HardwareSerial1.cpp b/teensy3/HardwareSerial1.cpp index fd625ad5..9a13d2d5 100644 --- a/teensy3/HardwareSerial1.cpp +++ b/teensy3/HardwareSerial1.cpp @@ -36,8 +36,9 @@ uint8_t _serialEvent1_default __attribute__((weak)) PROGMEM = 0 ; HardwareSerial Serial1(&serialEvent1); -void HardwareSerial::begin(uint32_t baud) { +void HardwareSerial::begin(uint32_t baud, uint32_t format) { serial_begin(BAUD2DIV(baud)); + if (format != (uint32_t)-1) serial_format(format); if (!_serialEvent1_default) addToSerialEventsList(); } diff --git a/teensy3/HardwareSerial2.cpp b/teensy3/HardwareSerial2.cpp index 8e10cc35..f2738860 100644 --- a/teensy3/HardwareSerial2.cpp +++ b/teensy3/HardwareSerial2.cpp @@ -34,7 +34,8 @@ HardwareSerial2 Serial2(&serialEvent2); uint8_t _serialEvent2_default __attribute__((weak)) PROGMEM = 0 ; -void HardwareSerial2::begin(uint32_t baud) { +void HardwareSerial2::begin(uint32_t baud, uint32_t format) { serial2_begin(BAUD2DIV2(baud)); + if (format != (uint32_t)-1) serial2_format(format); if (!_serialEvent2_default) addToSerialEventsList(); } diff --git a/teensy3/HardwareSerial3.cpp b/teensy3/HardwareSerial3.cpp index 176736aa..722af351 100644 --- a/teensy3/HardwareSerial3.cpp +++ b/teensy3/HardwareSerial3.cpp @@ -35,7 +35,8 @@ HardwareSerial3 Serial3(&serialEvent3); uint8_t _serialEvent3_default __attribute__((weak)) PROGMEM = 0 ; -void HardwareSerial3::begin(uint32_t baud) { +void HardwareSerial3::begin(uint32_t baud, uint32_t format) { serial3_begin(BAUD2DIV3(baud)); + if (format != (uint32_t)-1) serial3_format(format); if (!_serialEvent3_default) addToSerialEventsList(); } diff --git a/teensy3/HardwareSerial4.cpp b/teensy3/HardwareSerial4.cpp index b25c87fb..f3884bf8 100644 --- a/teensy3/HardwareSerial4.cpp +++ b/teensy3/HardwareSerial4.cpp @@ -37,8 +37,9 @@ HardwareSerial4 Serial4(&serialEvent4); uint8_t _serialEvent4_default __attribute__((weak)) PROGMEM = 0 ; -void HardwareSerial4::begin(uint32_t baud) { +void HardwareSerial4::begin(uint32_t baud, uint32_t format) { serial4_begin(BAUD2DIV3(baud)); + if (format != (uint32_t)-1) serial4_format(format); if (!_serialEvent4_default) addToSerialEventsList(); } diff --git a/teensy3/HardwareSerial5.cpp b/teensy3/HardwareSerial5.cpp index 15b7473d..d61aa83d 100644 --- a/teensy3/HardwareSerial5.cpp +++ b/teensy3/HardwareSerial5.cpp @@ -37,8 +37,9 @@ HardwareSerial5 Serial5(&serialEvent5); uint8_t _serialEvent5_default __attribute__((weak)) PROGMEM = 0 ; -void HardwareSerial5::begin(uint32_t baud) { +void HardwareSerial5::begin(uint32_t baud, uint32_t format) { serial5_begin(BAUD2DIV3(baud)); + if (format != (uint32_t)-1) serial5_format(format); if (!_serialEvent5_default) addToSerialEventsList(); } diff --git a/teensy3/HardwareSerial6.cpp b/teensy3/HardwareSerial6.cpp index 3d80baf7..5364c3ba 100644 --- a/teensy3/HardwareSerial6.cpp +++ b/teensy3/HardwareSerial6.cpp @@ -37,12 +37,13 @@ HardwareSerial6 Serial6(&serialEvent6); uint8_t _serialEvent6_default __attribute__((weak)) PROGMEM = 0 ; -void HardwareSerial6::begin(uint32_t baud) { +void HardwareSerial6::begin(uint32_t baud, uint32_t format) { #if defined(__MK66FX1M0__) // For LPUART just pass baud straight in. serial6_begin(baud); #else serial6_begin(BAUD2DIV3(baud)); #endif + if (format != (uint32_t)-1) serial6_format(format); if (!_serialEvent6_default) addToSerialEventsList(); } diff --git a/teensy3/core_cmInstr.h b/teensy3/core_cmInstr.h index 971ae7e9..bfdfcacd 100644 --- a/teensy3/core_cmInstr.h +++ b/teensy3/core_cmInstr.h @@ -316,7 +316,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) */ #define __SSAT(ARG1,ARG2) \ ({ \ - uint32_t __RES, __ARG1 = (ARG1); \ + int32_t __RES, __ARG1 = (ARG1); \ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) diff --git a/teensy4/FS.h b/teensy4/FS.h index be15d5af..8321c477 100644 --- a/teensy4/FS.h +++ b/teensy4/FS.h @@ -273,6 +273,7 @@ class FS { public: FS() {} + virtual ~FS() {} virtual File open(const char *filename, uint8_t mode = FILE_READ) = 0; virtual bool exists(const char *filepath) = 0; virtual bool mkdir(const char *filepath) = 0; diff --git a/teensy4/HardwareSerial.cpp b/teensy4/HardwareSerial.cpp index 43007d83..4b933b7f 100644 --- a/teensy4/HardwareSerial.cpp +++ b/teensy4/HardwareSerial.cpp @@ -244,11 +244,13 @@ void HardwareSerialIMXRT::begin(uint32_t baud, uint16_t format) inline void HardwareSerialIMXRT::rts_assert() { - DIRECT_WRITE_LOW(rts_pin_baseReg_, rts_pin_bitmask_); + if (rts_pin_invert_) DIRECT_WRITE_HIGH(rts_pin_baseReg_, rts_pin_bitmask_); + else DIRECT_WRITE_LOW(rts_pin_baseReg_, rts_pin_bitmask_); } inline void HardwareSerialIMXRT::rts_deassert() { + if (rts_pin_invert_) DIRECT_WRITE_LOW(rts_pin_baseReg_, rts_pin_bitmask_); DIRECT_WRITE_HIGH(rts_pin_baseReg_, rts_pin_bitmask_); } @@ -318,7 +320,7 @@ void HardwareSerialIMXRT::setRX(uint8_t pin) // configure the pin. *(portControlRegister(pin)) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS;; *(portConfigRegister(pin)) = pin_to_xbar_info[i].mux_val; - port->MODIR |= LPUART_MODIR_TXCTSE; + if (pin_to_xbar_info[i].select_input_register) *(pin_to_xbar_info[i].select_input_register) = pin_to_xbar_info[i].select_val; //Serial.printf("SerialX::begin stat:%x ctrl:%x fifo:%x water:%x\n", port->STAT, port->CTRL, port->FIFO, port->WATER ); //Serial.printf(" PINCFG: %x MODIR: %x\n", port->PINCFG, port->MODIR); @@ -365,6 +367,23 @@ bool HardwareSerialIMXRT::attachRts(uint8_t pin) if (pin < CORE_NUM_DIGITAL) { rts_pin_baseReg_ = PIN_TO_BASEREG(pin); rts_pin_bitmask_ = PIN_TO_BITMASK(pin); + rts_pin_invert_ = false; + pinMode(pin, OUTPUT); + rts_assert(); + } else { + rts_pin_baseReg_ = NULL; + return 0; + } + return 1; +} + +bool HardwareSerialIMXRT::attachRtsInverted(uint8_t pin) +{ + if (!(hardware->ccm_register & hardware->ccm_value)) return 0; + if (pin < CORE_NUM_DIGITAL) { + rts_pin_baseReg_ = PIN_TO_BASEREG(pin); + rts_pin_bitmask_ = PIN_TO_BITMASK(pin); + rts_pin_invert_ = true; pinMode(pin, OUTPUT); rts_assert(); } else { @@ -717,7 +736,7 @@ void HardwareSerialIMXRT::addToSerialEventsList() { } -const pin_to_xbar_info_t PROGMEM pin_to_xbar_info[] = { +extern const pin_to_xbar_info_t PROGMEM pin_to_xbar_info[] __attribute__((weak)) = { {0, 17, 1, &IOMUXC_XBAR1_IN17_SELECT_INPUT, 0x1}, {1, 16, 1, nullptr, 0}, {2, 6, 3, &IOMUXC_XBAR1_IN06_SELECT_INPUT, 0x0}, @@ -757,5 +776,5 @@ const pin_to_xbar_info_t PROGMEM pin_to_xbar_info[] = { #endif }; -const uint8_t PROGMEM count_pin_to_xbar_info = sizeof(pin_to_xbar_info)/sizeof(pin_to_xbar_info[0]); +extern const uint8_t PROGMEM count_pin_to_xbar_info __attribute__((weak)) = sizeof(pin_to_xbar_info)/sizeof(pin_to_xbar_info[0]); diff --git a/teensy4/HardwareSerial.h b/teensy4/HardwareSerial.h index f585bfcd..9a29409a 100644 --- a/teensy4/HardwareSerial.h +++ b/teensy4/HardwareSerial.h @@ -182,20 +182,25 @@ class HardwareSerialIMXRT : public HardwareSerial } pin_info_t; typedef struct { + // General settings for this Serial object. uint8_t serial_index; // which object are we? 0 based - IRQ_NUMBER_t irq; void (*irq_handler)(void); void (* _serialEvent)(void); + const uint16_t irq_priority; + const uint16_t rts_low_watermark; + const uint16_t rts_high_watermark; + + // Settings that apply to underlying LPUART object. + IRQ_NUMBER_t irq; volatile uint32_t &ccm_register; const uint32_t ccm_value; + const uint8_t xbar_out_lpuartX_trig_input; + + // Pin lists pin_info_t rx_pins[cnt_rx_pins]; pin_info_t tx_pins[cnt_tx_pins]; const uint8_t cts_pin; const uint8_t cts_mux_val; - const uint16_t irq_priority; - const uint16_t rts_low_watermark; - const uint16_t rts_high_watermark; - const uint8_t xbar_out_lpuartX_trig_input; } hardware_t; public: constexpr HardwareSerialIMXRT(uintptr_t myport, const hardware_t *myhardware, @@ -240,7 +245,12 @@ class HardwareSerialIMXRT : public HardwareSerial // receive more data, or HIGH when the serial device should pause transmission. // All digital pins are supported. bool attachRts(uint8_t pin); - // Configure CTS flow control. Teensy will transmit when this pin is LOw + // Same as attachRts except the signal levels are reversed. + // Configure RTS flow control. The pin will be HIGH when Teensy is able to + // receive more data, or LOW when the serial device should pause transmission. + // All digital pins are supported. + bool attachRtsInverted(uint8_t pin); + // Configure CTS flow control. Teensy will transmit when this pin is LOW // and will pause transmission when the pin is HIGH. Only specific pins are // supported. See https://www.pjrc.com/teensy/td_uart.html bool attachCts(uint8_t pin); @@ -327,6 +337,7 @@ class HardwareSerialIMXRT : public HardwareSerial volatile uint32_t *rts_pin_baseReg_ = 0; uint32_t rts_pin_bitmask_ = 0; + bool rts_pin_invert_ = false; inline void rts_assert(); inline void rts_deassert(); diff --git a/teensy4/HardwareSerial1.cpp b/teensy4/HardwareSerial1.cpp index 549e2245..ea247d8a 100644 --- a/teensy4/HardwareSerial1.cpp +++ b/teensy4/HardwareSerial1.cpp @@ -45,28 +45,35 @@ void IRQHandler_Serial1() Serial1.IRQHandler(); } +// Should we allow each one to be overwritten or all of a Port... +#ifndef SERIAL1_RX_PINS +#define SERIAL1_UART_ADDR IMXRT_LPUART6_ADDRESS +#define SERIAL1_LPUART IRQ_LPUART6, CCM_CCGR3, CCM_CCGR3_LPUART6(CCM_CCGR_ON), XBARA1_OUT_LPUART6_TRG_INPUT +#define SERIAL1_CTS_PIN 0xff, 0 +#if defined(ARDUINO_TEENSY41) +#define SERIAL1_RX_PINS {{0,2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 1}, {52, 2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 0}} +#define SERIAL1_TX_PINS {{1,2, &IOMUXC_LPUART6_TX_SELECT_INPUT, 1}, {53, 2, &IOMUXC_LPUART6_TX_SELECT_INPUT, 0}} +#else +#define SERIAL1_RX_PINS {{0,2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}} +#define SERIAL1_TX_PINS {{1,2, &IOMUXC_LPUART6_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}} +#endif +#endif + + // Serial1 static BUFTYPE tx_buffer1[SERIAL1_TX_BUFFER_SIZE]; static BUFTYPE rx_buffer1[SERIAL1_RX_BUFFER_SIZE]; -const HardwareSerialIMXRT::hardware_t UART6_Hardware = { - 0, IRQ_LPUART6, &IRQHandler_Serial1, +const HardwareSerialIMXRT::hardware_t Serial1_Hardware = { + 0, + &IRQHandler_Serial1, &serialEvent1, - CCM_CCGR3, CCM_CCGR3_LPUART6(CCM_CCGR_ON), - #if defined(ARDUINO_TEENSY41) - {{0,2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 1}, {52, 2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 0}}, - {{1,2, &IOMUXC_LPUART6_TX_SELECT_INPUT, 1}, {53, 2, &IOMUXC_LPUART6_TX_SELECT_INPUT, 0}}, - #else - {{0,2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, - {{1,2, &IOMUXC_LPUART6_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, - #endif - 0xff, // No CTS pin - 0, // No CTS IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark - XBARA1_OUT_LPUART6_TRG_INPUT // XBar Tigger + // Stuff that can be overwritten easily by variant + SERIAL1_LPUART, SERIAL1_RX_PINS, SERIAL1_TX_PINS, SERIAL1_CTS_PIN }; -HardwareSerialIMXRT Serial1(IMXRT_LPUART6_ADDRESS, &UART6_Hardware, tx_buffer1, +HardwareSerialIMXRT Serial1(SERIAL1_UART_ADDR, &Serial1_Hardware, tx_buffer1, SERIAL1_TX_BUFFER_SIZE, rx_buffer1, SERIAL1_RX_BUFFER_SIZE); //void serialEvent1() __attribute__((weak)); diff --git a/teensy4/HardwareSerial2.cpp b/teensy4/HardwareSerial2.cpp index 049091b8..51d38eb7 100644 --- a/teensy4/HardwareSerial2.cpp +++ b/teensy4/HardwareSerial2.cpp @@ -45,38 +45,34 @@ void IRQHandler_Serial2() Serial2.IRQHandler(); } +#ifndef SERIAL2_RX_PINS +#define SERIAL2_CTS_PIN 0xff, 0 +#if !defined(ARDUINO_TEENSY_MICROMOD) +#define SERIAL2_UART_ADDR IMXRT_LPUART4_ADDRESS +#define SERIAL2_LPUART IRQ_LPUART4, CCM_CCGR1, CCM_CCGR1_LPUART4(CCM_CCGR_ON), XBARA1_OUT_LPUART4_TRG_INPUT +#define SERIAL2_RX_PINS {{7,2, &IOMUXC_LPUART4_RX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}} +#define SERIAL2_TX_PINS {{8,2, &IOMUXC_LPUART4_TX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}} + +#else +#define SERIAL2_UART_ADDR IMXRT_LPUART3_ADDRESS +#define SERIAL2_LPUART IRQ_LPUART3, CCM_CCGR0, CCM_CCGR0_LPUART3(CCM_CCGR_ON), XBARA1_OUT_LPUART3_TRG_INPUT +#define SERIAL2_RX_PINS {{16,2, &IOMUXC_LPUART3_RX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}} +#define SERIAL2_TX_PINS {{17,2, &IOMUXC_LPUART3_TX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}} +#endif +#endif + // Serial2 static BUFTYPE tx_buffer2[SERIAL2_TX_BUFFER_SIZE]; static BUFTYPE rx_buffer2[SERIAL2_RX_BUFFER_SIZE]; -#ifndef ARDUINO_TEENSY_MICROMOD -static HardwareSerialIMXRT::hardware_t UART4_Hardware = { - 1, IRQ_LPUART4, &IRQHandler_Serial2, +static HardwareSerialIMXRT::hardware_t Serial2_Hardware = { + 1, + &IRQHandler_Serial2, &serialEvent2, - CCM_CCGR1, CCM_CCGR1_LPUART4(CCM_CCGR_ON), - {{7,2, &IOMUXC_LPUART4_RX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}}, - {{8,2, &IOMUXC_LPUART4_TX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}}, - 0xff, // No CTS pin - 0, // No CTS IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark - XBARA1_OUT_LPUART4_TRG_INPUT + // Stuff that can be overwritten easily by variant + SERIAL2_LPUART, SERIAL2_RX_PINS, SERIAL2_TX_PINS, SERIAL2_CTS_PIN }; -HardwareSerialIMXRT Serial2(IMXRT_LPUART4_ADDRESS, &UART4_Hardware, tx_buffer2, +HardwareSerialIMXRT Serial2(SERIAL2_UART_ADDR, &Serial2_Hardware, tx_buffer2, SERIAL2_TX_BUFFER_SIZE, rx_buffer2, SERIAL2_RX_BUFFER_SIZE); - -#else // Teensy Micromod -static HardwareSerialIMXRT::hardware_t UART3_Hardware = { - 3, IRQ_LPUART3, &IRQHandler_Serial2, - &serialEvent2, - CCM_CCGR0, CCM_CCGR0_LPUART3(CCM_CCGR_ON), - {{16,2, &IOMUXC_LPUART3_RX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}}, - {{17,2, &IOMUXC_LPUART3_TX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}}, - 0xff, // No CTS pin - 0, // No CTS - IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark - XBARA1_OUT_LPUART3_TRG_INPUT -}; -HardwareSerialIMXRT Serial2(IMXRT_LPUART3_ADDRESS, &UART3_Hardware, tx_buffer2, - SERIAL2_TX_BUFFER_SIZE, rx_buffer2, SERIAL2_RX_BUFFER_SIZE); -#endif diff --git a/teensy4/HardwareSerial3.cpp b/teensy4/HardwareSerial3.cpp index 3c99725b..ab57a47a 100644 --- a/teensy4/HardwareSerial3.cpp +++ b/teensy4/HardwareSerial3.cpp @@ -44,21 +44,29 @@ void IRQHandler_Serial3() Serial3.IRQHandler(); } +#ifndef SERIAL3_RX_PINS +#define SERIAL3_UART_ADDR IMXRT_LPUART2_ADDRESS +#define SERIAL3_LPUART IRQ_LPUART2, CCM_CCGR0, CCM_CCGR0_LPUART2(CCM_CCGR_ON), XBARA1_OUT_LPUART2_TRG_INPUT +#define SERIAL3_CTS_PIN 19, 2 +#define SERIAL3_RX_PINS {{15,2, &IOMUXC_LPUART2_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}} +#define SERIAL3_TX_PINS {{14,2, &IOMUXC_LPUART2_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}} +#endif + + + + // Serial3 static BUFTYPE tx_buffer3[SERIAL3_TX_BUFFER_SIZE]; static BUFTYPE rx_buffer3[SERIAL3_RX_BUFFER_SIZE]; -static HardwareSerialIMXRT::hardware_t UART2_Hardware = { - 2, IRQ_LPUART2, &IRQHandler_Serial3, +const HardwareSerialIMXRT::hardware_t SERIAL3_Hardware = { + 2, + &IRQHandler_Serial3, &serialEvent3, - CCM_CCGR0, CCM_CCGR0_LPUART2(CCM_CCGR_ON), - {{15,2, &IOMUXC_LPUART2_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, - {{14,2, &IOMUXC_LPUART2_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, - 19, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00, // 19 - 2, // page 473 IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark - XBARA1_OUT_LPUART2_TRG_INPUT + // Stuff that can be overwritten easily by variant + SERIAL3_LPUART, SERIAL3_RX_PINS, SERIAL3_TX_PINS, SERIAL3_CTS_PIN }; -HardwareSerialIMXRT Serial3(IMXRT_LPUART2_ADDRESS, &UART2_Hardware, tx_buffer3, +HardwareSerialIMXRT Serial3(SERIAL3_UART_ADDR, &SERIAL3_Hardware, tx_buffer3, SERIAL3_TX_BUFFER_SIZE, rx_buffer3, SERIAL3_RX_BUFFER_SIZE); diff --git a/teensy4/HardwareSerial4.cpp b/teensy4/HardwareSerial4.cpp index cf92808c..f3eb300c 100644 --- a/teensy4/HardwareSerial4.cpp +++ b/teensy4/HardwareSerial4.cpp @@ -46,36 +46,34 @@ void IRQHandler_Serial4() } // Serial4 + +#ifndef SERIAL4_RX_PINS +#define SERIAL4_CTS_PIN 0xff, 0 +#if !defined(ARDUINO_TEENSY_MICROMOD) +#define SERIAL4_UART_ADDR IMXRT_LPUART3_ADDRESS +#define SERIAL4_LPUART IRQ_LPUART3, CCM_CCGR0, CCM_CCGR0_LPUART3(CCM_CCGR_ON), XBARA1_OUT_LPUART3_TRG_INPUT +#define SERIAL4_RX_PINS {{16,2, &IOMUXC_LPUART3_RX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}} +#define SERIAL4_TX_PINS {{17,2, &IOMUXC_LPUART3_TX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}} + +#else +#define SERIAL4_UART_ADDR IMXRT_LPUART4_ADDRESS +#define SERIAL4_LPUART IRQ_LPUART4, CCM_CCGR1, CCM_CCGR1_LPUART4(CCM_CCGR_ON), XBARA1_OUT_LPUART4_TRG_INPUT +#define SERIAL4_RX_PINS {{7,2, &IOMUXC_LPUART4_RX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}} +#define SERIAL4_TX_PINS {{8,2, &IOMUXC_LPUART4_TX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}} +#endif +#endif + static BUFTYPE tx_buffer4[SERIAL4_TX_BUFFER_SIZE]; static BUFTYPE rx_buffer4[SERIAL4_RX_BUFFER_SIZE]; -#ifndef ARDUINO_TEENSY_MICROMOD -static HardwareSerialIMXRT::hardware_t UART3_Hardware = { - 3, IRQ_LPUART3, &IRQHandler_Serial4, +static HardwareSerialIMXRT::hardware_t SERIAL4_Hardware = { + 3, + &IRQHandler_Serial4, &serialEvent4, - CCM_CCGR0, CCM_CCGR0_LPUART3(CCM_CCGR_ON), - {{16,2, &IOMUXC_LPUART3_RX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}}, - {{17,2, &IOMUXC_LPUART3_TX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}}, - 0xff, // No CTS pin - 0, // No CTS IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark - XBARA1_OUT_LPUART3_TRG_INPUT + // Stuff that can be overwritten easily by variant + SERIAL4_LPUART, SERIAL4_RX_PINS, SERIAL4_TX_PINS, SERIAL4_CTS_PIN }; -HardwareSerialIMXRT Serial4(IMXRT_LPUART3_ADDRESS, &UART3_Hardware, tx_buffer4, +HardwareSerialIMXRT Serial4(SERIAL4_UART_ADDR, &SERIAL4_Hardware, tx_buffer4, SERIAL4_TX_BUFFER_SIZE, rx_buffer4, SERIAL4_RX_BUFFER_SIZE); -#else -static HardwareSerialIMXRT::hardware_t UART4_Hardware = { - 1, IRQ_LPUART4, &IRQHandler_Serial4, - &serialEvent4, /*&_serialEvent4_default,*/ - CCM_CCGR1, CCM_CCGR1_LPUART4(CCM_CCGR_ON), - {{7,2, &IOMUXC_LPUART4_RX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}}, - {{8,2, &IOMUXC_LPUART4_TX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}}, - 0xff, // No CTS pin - 0, // No CTS - IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark - XBARA1_OUT_LPUART4_TRG_INPUT -}; -HardwareSerialIMXRT Serial4(IMXRT_LPUART4_ADDRESS, &UART4_Hardware, tx_buffer4, - SERIAL4_TX_BUFFER_SIZE, rx_buffer4, SERIAL4_RX_BUFFER_SIZE); -#endif diff --git a/teensy4/HardwareSerial5.cpp b/teensy4/HardwareSerial5.cpp index fce9672d..c980999f 100644 --- a/teensy4/HardwareSerial5.cpp +++ b/teensy4/HardwareSerial5.cpp @@ -44,32 +44,40 @@ void IRQHandler_Serial5() { Serial5.IRQHandler(); } + +#ifndef SERIAL5_RX_PINS +#define SERIAL5_UART_ADDR IMXRT_LPUART8_ADDRESS +#define SERIAL5_LPUART IRQ_LPUART8, CCM_CCGR6, CCM_CCGR6_LPUART8(CCM_CCGR_ON), XBARA1_OUT_LPUART8_TRG_INPUT + +#if defined(ARDUINO_TEENSY41) +#define SERIAL5_RX_PINS {{21,2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 1}, {46, 2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 0}} +#define SERIAL5_TX_PINS {{20,2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 1}, {47, 2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 0}} +#define SERIAL5_CTS_PIN 43, 2 + +#elif defined(ARDUINO_TEENSY40) +#define SERIAL5_RX_PINS {{21,2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 1}, {38, 2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 0}} +#define SERIAL5_TX_PINS {{20,2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 1}, {39, 2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 0}} +#define SERIAL5_CTS_PIN 35, 2 + +#else // ARDUINO_TEENSY_MICROMOD +#define SERIAL5_RX_PINS {{21,2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 1}, {39, 2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 0}} +#define SERIAL5_TX_PINS {{20,2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 1}, {38, 2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 0}} +#define SERIAL5_CTS_PIN 35, 2 +#endif + +#endif + + // Serial5 static BUFTYPE tx_buffer5[SERIAL5_TX_BUFFER_SIZE]; static BUFTYPE rx_buffer5[SERIAL5_RX_BUFFER_SIZE]; -static HardwareSerialIMXRT::hardware_t UART8_Hardware = { - 4, IRQ_LPUART8, &IRQHandler_Serial5, +static HardwareSerialIMXRT::hardware_t Serial5_Hardware = { + 4, + &IRQHandler_Serial5, &serialEvent5, - CCM_CCGR6, CCM_CCGR6_LPUART8(CCM_CCGR_ON), - #if defined(ARDUINO_TEENSY41) - {{21,2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 1}, {46, 2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 0}}, - {{20,2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 1}, {47, 2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 0}}, - 43, // CTS pin - 2, // CTS - #elif defined(ARDUINO_TEENSY40) - {{21,2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 1}, {38, 2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 0}}, - {{20,2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 1}, {39, 2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 0}}, - 35, // CTS pin - 2, // CTS - #else // ARDUINO_TEENSY_MICROMOD - {{21,2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 1}, {39, 2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 0}}, - {{20,2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 1}, {38, 2, &IOMUXC_LPUART8_TX_SELECT_INPUT, 0}}, - 35, // CTS pin - 2, // CTS - #endif IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark - XBARA1_OUT_LPUART8_TRG_INPUT + SERIAL5_LPUART, SERIAL5_RX_PINS, SERIAL5_TX_PINS, SERIAL5_CTS_PIN }; -HardwareSerialIMXRT Serial5(IMXRT_LPUART8_ADDRESS, &UART8_Hardware, tx_buffer5, +HardwareSerialIMXRT Serial5(SERIAL5_UART_ADDR, &Serial5_Hardware, tx_buffer5, SERIAL5_TX_BUFFER_SIZE, rx_buffer5, SERIAL5_RX_BUFFER_SIZE); diff --git a/teensy4/HardwareSerial6.cpp b/teensy4/HardwareSerial6.cpp index 2ea31543..54ffb3d6 100644 --- a/teensy4/HardwareSerial6.cpp +++ b/teensy4/HardwareSerial6.cpp @@ -44,22 +44,26 @@ void IRQHandler_Serial6() Serial6.IRQHandler(); } +#ifndef SERIAL6_RX_PINS +#define SERIAL6_UART_ADDR IMXRT_LPUART1_ADDRESS +#define SERIAL6_LPUART IRQ_LPUART1, CCM_CCGR5, CCM_CCGR5_LPUART1(CCM_CCGR_ON), XBARA1_OUT_LPUART1_TRG_INPUT +#define SERIAL6_CTS_PIN 0xff, 0 +#define SERIAL6_RX_PINS {{25,2, nullptr, 0}, {0xff, 0xff, nullptr, 0}} +#define SERIAL6_TX_PINS {{24,2, nullptr, 0}, {0xff, 0xff, nullptr, 0}} +#endif + // Serial6 static BUFTYPE tx_buffer6[SERIAL6_TX_BUFFER_SIZE]; static BUFTYPE rx_buffer6[SERIAL6_RX_BUFFER_SIZE]; -static HardwareSerialIMXRT::hardware_t UART1_Hardware = { - 5, IRQ_LPUART1, &IRQHandler_Serial6, +static HardwareSerialIMXRT::hardware_t Serial6_Hardware = { + 5, + &IRQHandler_Serial6, &serialEvent6, - CCM_CCGR5, CCM_CCGR5_LPUART1(CCM_CCGR_ON), - {{25,2, nullptr, 0}, {0xff, 0xff, nullptr, 0}}, - {{24,2, nullptr, 0}, {0xff, 0xff, nullptr, 0}}, - 0xff, // No CTS pin - 0, // No CTS IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark - XBARA1_OUT_LPUART1_TRG_INPUT + SERIAL6_LPUART, SERIAL6_RX_PINS, SERIAL6_TX_PINS, SERIAL6_CTS_PIN }; -HardwareSerialIMXRT Serial6(IMXRT_LPUART1_ADDRESS, &UART1_Hardware, tx_buffer6, +HardwareSerialIMXRT Serial6(SERIAL6_UART_ADDR, &Serial6_Hardware, tx_buffer6, SERIAL6_TX_BUFFER_SIZE, rx_buffer6, SERIAL6_RX_BUFFER_SIZE); diff --git a/teensy4/HardwareSerial7.cpp b/teensy4/HardwareSerial7.cpp index d0b7b4b1..08fefa4f 100644 --- a/teensy4/HardwareSerial7.cpp +++ b/teensy4/HardwareSerial7.cpp @@ -48,16 +48,20 @@ void IRQHandler_Serial7() static BUFTYPE tx_buffer7[SERIAL7_TX_BUFFER_SIZE]; static BUFTYPE rx_buffer7[SERIAL7_RX_BUFFER_SIZE]; -static HardwareSerialIMXRT::hardware_t UART7_Hardware = { - 6, IRQ_LPUART7, &IRQHandler_Serial7, +#ifndef SERIAL7_RX_PINS +#define SERIAL7_UART_ADDR IMXRT_LPUART7_ADDRESS +#define SERIAL7_LPUART IRQ_LPUART7, CCM_CCGR5, CCM_CCGR5_LPUART7(CCM_CCGR_ON), XBARA1_OUT_LPUART7_TRG_INPUT +#define SERIAL7_CTS_PIN 0xff, 0 +#define SERIAL7_RX_PINS {{28,2, &IOMUXC_LPUART7_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}} +#define SERIAL7_TX_PINS {{29,2, &IOMUXC_LPUART7_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}} +#endif + +static HardwareSerialIMXRT::hardware_t Serial7_Hardware = { + 6, + &IRQHandler_Serial7, &serialEvent7, - CCM_CCGR5, CCM_CCGR5_LPUART7(CCM_CCGR_ON), - {{28,2, &IOMUXC_LPUART7_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, - {{29,2, &IOMUXC_LPUART7_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, - 0xff, // No CTS pin - 0, // No CTS IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark - XBARA1_OUT_LPUART7_TRG_INPUT + SERIAL7_LPUART, SERIAL7_RX_PINS, SERIAL7_TX_PINS, SERIAL7_CTS_PIN }; -HardwareSerialIMXRT Serial7(IMXRT_LPUART7_ADDRESS, &UART7_Hardware, tx_buffer7, +HardwareSerialIMXRT Serial7(SERIAL7_UART_ADDR, &Serial7_Hardware, tx_buffer7, SERIAL7_TX_BUFFER_SIZE, rx_buffer7, SERIAL7_RX_BUFFER_SIZE); diff --git a/teensy4/HardwareSerial8.cpp b/teensy4/HardwareSerial8.cpp index 24883dc2..9c430cdd 100644 --- a/teensy4/HardwareSerial8.cpp +++ b/teensy4/HardwareSerial8.cpp @@ -30,7 +30,7 @@ #include #include "HardwareSerial.h" -#if defined(__IMXRT1062__) && defined(ARDUINO_TEENSY41) +#if defined(__IMXRT1062__) && (defined(ARDUINO_TEENSY41) || defined(SERIAL8_RX_PINS)) #ifndef SERIAL8_TX_BUFFER_SIZE #define SERIAL8_TX_BUFFER_SIZE 40 // number of outgoing bytes to buffer @@ -45,22 +45,27 @@ void IRQHandler_Serial8() Serial8.IRQHandler(); } +#ifndef SERIAL8_RX_PINS +#define SERIAL8_UART_ADDR IMXRT_LPUART5_ADDRESS +#define SERIAL8_LPUART IRQ_LPUART5, CCM_CCGR3, CCM_CCGR3_LPUART5(CCM_CCGR_ON), XBARA1_OUT_LPUART5_TRG_INPUT +#define SERIAL8_CTS_PIN 50, 2 +#define SERIAL8_RX_PINS {{34,1, &IOMUXC_LPUART5_RX_SELECT_INPUT, 1}, {48, 2, &IOMUXC_LPUART5_RX_SELECT_INPUT, 0}} +#define SERIAL8_TX_PINS {{35,1, &IOMUXC_LPUART5_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}} +#endif + // Serial8 static BUFTYPE tx_buffer8[SERIAL8_TX_BUFFER_SIZE]; static BUFTYPE rx_buffer8[SERIAL8_RX_BUFFER_SIZE]; -static HardwareSerialIMXRT::hardware_t UART5_Hardware = { - 7, IRQ_LPUART5, &IRQHandler_Serial8, +static HardwareSerialIMXRT::hardware_t Serial8_Hardware = { + 7, + &IRQHandler_Serial8, &serialEvent8, - CCM_CCGR3, CCM_CCGR3_LPUART5(CCM_CCGR_ON), - {{34,1, &IOMUXC_LPUART5_RX_SELECT_INPUT, 1}, {48, 2, &IOMUXC_LPUART5_RX_SELECT_INPUT, 0}}, - {{35,1, &IOMUXC_LPUART5_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, - 50, // CTS pin - 2, // CTS IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark - XBARA1_OUT_LPUART5_TRG_INPUT + SERIAL8_LPUART, SERIAL8_RX_PINS, SERIAL8_TX_PINS, SERIAL8_CTS_PIN }; -HardwareSerialIMXRT Serial8(IMXRT_LPUART5_ADDRESS, &UART5_Hardware, tx_buffer8, +HardwareSerialIMXRT Serial8(IMXRT_LPUART5_ADDRESS, &Serial8_Hardware, tx_buffer8, SERIAL8_TX_BUFFER_SIZE, rx_buffer8, SERIAL8_RX_BUFFER_SIZE); #endif + diff --git a/teensy4/Time.cpp b/teensy4/Time.cpp index 13c097e6..bc8fc90e 100644 --- a/teensy4/Time.cpp +++ b/teensy4/Time.cpp @@ -103,16 +103,17 @@ uint32_t makeTime(const DateTimeFields &tm) uint32_t seconds; // seconds from 1970 till 1 jan 00:00:00 of the given year - seconds = (tm.year - 70) * (SECS_PER_DAY * 365); - for (i = 70; i < tm.year; i++) { - if (LEAP_YEAR(i - 70)) { + int year = tm.year - 70; + seconds = year * (SECS_PER_DAY * 365); + for (i = 0; i < year; i++) { + if (LEAP_YEAR(i)) { seconds += SECS_PER_DAY; // add extra days for leap years } } // add days for this year, months start from 1 for (i = 0; i < tm.mon; i++) { - if ( (i == 1) && LEAP_YEAR(tm.year)) { + if ( (i == 1) && LEAP_YEAR(year)) { seconds += SECS_PER_DAY * 29; } else { seconds += SECS_PER_DAY * monthDays[i]; diff --git a/teensy4/analog.c b/teensy4/analog.c index f9110b59..65f9cefe 100644 --- a/teensy4/analog.c +++ b/teensy4/analog.c @@ -8,7 +8,7 @@ static uint8_t analog_config_bits = 10; static uint8_t analog_num_average = 4; -const uint8_t pin_to_channel[] = { // pg 482 +const uint8_t pin_to_channel[] __attribute__((weak)) = { // pg 482 7, // 0/A0 AD_B1_02 8, // 1/A1 AD_B1_03 12, // 2/A2 AD_B1_07 diff --git a/teensy4/clockspeed.c b/teensy4/clockspeed.c index be2e1acb..323e974e 100644 --- a/teensy4/clockspeed.c +++ b/teensy4/clockspeed.c @@ -16,6 +16,8 @@ volatile uint32_t F_BUS_ACTUAL = 132000000; #define OVERCLOCK_STEPSIZE 28000000 #define OVERCLOCK_MAX_VOLT 1575 +// Industrial temperature chips may require different parameters +// https://forum.pjrc.com/index.php?threads/75798/#post-349215 uint32_t set_arm_clock(uint32_t frequency); @@ -176,3 +178,37 @@ uint32_t set_arm_clock(uint32_t frequency) return frequency; } +#ifdef ARDUINO_TEENSY41 +void set_psram_clock(int speed_mhz) { + // What clocks exist: + static const int flexspio2_clock_speeds[] = { 396, 720, 665, 528 }; + + // See what the closest setting might be: + uint8_t clk_save = 0; + uint8_t divider_save =0; + int min_delta = speed_mhz; + for (uint8_t clk = 0; clk < 4; clk++) { + uint8_t divider = (flexspio2_clock_speeds[clk] + (speed_mhz / 2)) / speed_mhz; + int delta = abs(speed_mhz - flexspio2_clock_speeds[clk] / divider); + if ((delta < min_delta) && (divider < 8)) { + min_delta = delta; + clk_save = clk; + divider_save = divider; + } + } + + // first turn off FLEXSPI2 + CCM_CCGR7 &= ~CCM_CCGR7_FLEXSPI2(CCM_CCGR_ON); + + divider_save--; // 0 biased. + //Serial.printf("Update FLEXSPI2 speed: %u clk:%u div:%u Actual:%u\n", speed_mhz, clk_save, divider_save, + // flexspio2_clock_speeds[clk_save]/ (divider_save + 1)); + + // Set the clock settings. + CCM_CBCMR = (CCM_CBCMR & ~(CCM_CBCMR_FLEXSPI2_PODF_MASK | CCM_CBCMR_FLEXSPI2_CLK_SEL_MASK)) + | CCM_CBCMR_FLEXSPI2_PODF(divider_save) | CCM_CBCMR_FLEXSPI2_CLK_SEL(clk_save); + + // Turn FlexSPI2 clock back on + CCM_CCGR7 |= CCM_CCGR7_FLEXSPI2(CCM_CCGR_ON); +} +#endif \ No newline at end of file diff --git a/teensy4/core_cmInstr.h b/teensy4/core_cmInstr.h index 971ae7e9..bfdfcacd 100644 --- a/teensy4/core_cmInstr.h +++ b/teensy4/core_cmInstr.h @@ -316,7 +316,7 @@ __attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) */ #define __SSAT(ARG1,ARG2) \ ({ \ - uint32_t __RES, __ARG1 = (ARG1); \ + int32_t __RES, __ARG1 = (ARG1); \ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ __RES; \ }) diff --git a/teensy4/core_pin_names.h b/teensy4/core_pin_names.h new file mode 100644 index 00000000..c4c522c7 --- /dev/null +++ b/teensy4/core_pin_names.h @@ -0,0 +1,87 @@ + #pragma once + +// PinName values: 32 bit top 16 - offset in EMC table, low 8 bits 0-4 GPIO PIN 5-7 On Port # +typedef enum { + AD_B0_00 = 0x0BC0000, AD_B0_01 = 0x0C00001, AD_B0_02 = 0x0C40002, AD_B0_03 = 0x0C80003, AD_B0_04 = 0x0CC0004, AD_B0_05 = 0x0D00005, AD_B0_06 = 0x0D40006, AD_B0_07 = 0x0D80007, + AD_B0_08 = 0x0DC0008, AD_B0_09 = 0x0E00009, AD_B0_10 = 0x0E4000A, AD_B0_11 = 0x0E8000B, AD_B0_12 = 0x0EC000C, AD_B0_13 = 0x0F0000D, AD_B0_14 = 0x0F4000E, AD_B0_15 = 0x0F8000F, + AD_B1_00 = 0x0FC0010, AD_B1_01 = 0x1000011, AD_B1_02 = 0x1040012, AD_B1_03 = 0x1080013, AD_B1_04 = 0x10C0014, AD_B1_05 = 0x1100015, AD_B1_06 = 0x1140016, AD_B1_07 = 0x1180017, + AD_B1_08 = 0x11C0018, AD_B1_09 = 0x1200019, AD_B1_10 = 0x124001A, AD_B1_11 = 0x128001B, AD_B1_12 = 0x12C001C, AD_B1_13 = 0x130001D, AD_B1_14 = 0x134001D, AD_B1_15 = 0x138001F, + B0_00 = 0x13C0020, B0_01 = 0x1400021, B0_02 = 0x1440022, B0_03 = 0x1480023, B0_04 = 0x14C0024, B0_05 = 0x1500025, B0_06 = 0x1540026, B0_07 = 0x1580027, + B0_08 = 0x15C0028, B0_09 = 0x1600029, B0_10 = 0x164002A, B0_11 = 0x168002B, B0_12 = 0x16C002C, B0_13 = 0x170002D, B0_14 = 0x174002E, B0_15 = 0x178002F, + B1_00 = 0x17C0030, B1_01 = 0x1800031, B1_02 = 0x1840032, B1_03 = 0x1880033, B1_04 = 0x18C0034, B1_05 = 0x1900035, B1_06 = 0x1940036, B1_07 = 0x1980037, + B1_08 = 0x19C0038, B1_09 = 0x1A00039, B1_10 = 0x1A4003A, B1_11 = 0x1A8003B, B1_12 = 0x1AC003C, B1_13 = 0x1B0003D, B1_14 = 0x1B4003D, B1_15 = 0x1B8003F, + EMC_00 = 0x0140060, EMC_01 = 0x0180061, EMC_02 = 0x01C0062, EMC_03 = 0x0200063, EMC_04 = 0x0240064, EMC_05 = 0x0280065, EMC_06 = 0x02C0066, EMC_07 = 0x0300067, + EMC_08 = 0x0340068, EMC_09 = 0x0380069, EMC_10 = 0x03C006A, EMC_11 = 0x040006B, EMC_12 = 0x044006C, EMC_13 = 0x048006D, EMC_14 = 0x04C006E, EMC_15 = 0x050006F, + EMC_16 = 0x0540070, EMC_17 = 0x0580071, EMC_18 = 0x05C0072, EMC_19 = 0x0600073, EMC_20 = 0x0640074, EMC_21 = 0x0680075, EMC_22 = 0x06C0076, EMC_23 = 0x0700077, + EMC_24 = 0x0740078, EMC_25 = 0x0780079, EMC_26 = 0x07C007A, EMC_27 = 0x080007B, EMC_28 = 0x084007C, EMC_29 = 0x088007D, EMC_30 = 0x08C007D, EMC_31 = 0x090007F, + EMC_32 = 0x0940052, EMC_33 = 0x0980053, EMC_34 = 0x09C0054, EMC_35 = 0x0A00055, EMC_36 = 0x0A40056, EMC_37 = 0x0A80057, EMC_38 = 0x0AC0058, EMC_39 = 0x0B00059, + EMC_40 = 0x0B4005A, EMC_41 = 0x0B8005B, SD_B0_00 = 0x1BC004C, SD_B0_01 = 0x1C0004D, SD_B0_02 = 0x1C4004E, SD_B0_03 = 0x1C8004F, SD_B0_04 = 0x1CC0050, SD_B0_05 = 0x1D00051, + SD_B1_00 = 0x1D40040, SD_B1_01 = 0x1D80041, SD_B1_02 = 0x1DC0042, SD_B1_03 = 0x1E00043, SD_B1_04 = 0x1E40044, SD_B1_05 = 0x1E80045, SD_B1_06 = 0x1EC0046, SD_B1_07 = 0x1F00047, + SD_B1_08 = 0x1F40048, SD_B1_09 = 0x1F80049, SD_B1_10 = 0x1FC004A, SD_B1_11 = 0x200004B +} IMXRT_PIN_t; + +//#define digitalPinToPort(pin) (pin) +inline uint32_t digitalPinNameToBitMask(IMXRT_PIN_t pin_name) {return 1 << (pin_name & 0x1f);} +inline uint32_t digitalPinNameToBit(IMXRT_PIN_t pin_name) {return (pin_name & 0x1f); } +//inline volatile uint32_t * pinNamePortOutputRegister(IMXRT_PIN_t pin_name) { return } +inline volatile uint32_t * pinNamePortSetRegister(IMXRT_PIN_t pin_name) { return (volatile uint32_t*)((uint8_t *)&GPIO6_DR_SET + 0x4000 * ((pin_name >> 5) & 0x7));} +inline volatile uint32_t * pinNamePortClearRegister(IMXRT_PIN_t pin_name) { return (volatile uint32_t*)((uint8_t *)&GPIO6_DR_CLEAR + 0x4000 * ((pin_name >> 5) & 0x7));} +inline volatile uint32_t * pinNamePortToggleRegister(IMXRT_PIN_t pin_name) { return (volatile uint32_t*)((uint8_t *)&GPIO6_DR_TOGGLE + 0x4000 * ((pin_name >> 5) & 0x7));} +inline volatile uint32_t * pinNamePortInputRegister(IMXRT_PIN_t pin_name) { return (volatile uint32_t*)((uint8_t *)&GPIO6_PSR + 0x4000 * ((pin_name >> 5) & 0x7));} +inline volatile uint32_t * pinNamePortModeRegister(IMXRT_PIN_t pin_name) { return (volatile uint32_t *)(IMXRT_IOMUXC_ADDRESS + (pin_name >> 16));} +inline volatile uint32_t * pinNamePortConfigRegister(IMXRT_PIN_t pin_name) { return (volatile uint32_t *)(IMXRT_IOMUXC_ADDRESS + (pin_name >> 16) + 0x1f0);} +//inline volatile uint32_t * pinNamePortControlRegister(IMXRT_PIN_t pin_name) { return } +//#define digitalPinToPortReg(pin) (portOutputRegister(pin)) + +inline void digitalWrite(IMXRT_PIN_t pin_name, uint8_t val) { + uint32_t mask = 1 << (pin_name & 0x1f); + if (val) { + volatile uint32_t *reg = (volatile uint32_t*)((uint8_t *)&GPIO6_DR_SET + 0x4000 * ((pin_name >> 5) & 0x7)); + *reg = mask; + } else { + volatile uint32_t *reg = (volatile uint32_t*)((uint8_t *)&GPIO6_DR_CLEAR + 0x4000 * ((pin_name >> 5) & 0x7)); + *reg = mask; + } +} +inline void digitalToggle(IMXRT_PIN_t pin_name) { + uint32_t mask = 1 << (pin_name & 0x1f); + volatile uint32_t *reg = (volatile uint32_t*)((uint8_t *)&GPIO6_DR_TOGGLE + 0x4000 * ((pin_name >> 5) & 0x7)); + //Serial.printf("Toggle %x Reg:%x mask:%x\n", pin_name, reg, mask); + *reg = mask; +} + +inline uint8_t digitalRead(IMXRT_PIN_t pin_name) { + return (*pinNamePortInputRegister(pin_name) & digitalPinNameToBitMask(pin_name))? 1 : 0; +} + +void pinMode(IMXRT_PIN_t pin_name, uint8_t mode) +{ + // generate PAD and MUX register from name... + volatile uint32_t *mux = (volatile uint32_t *)(IMXRT_IOMUXC_ADDRESS + (pin_name >> 16)); + volatile uint32_t *pad = (volatile uint32_t *)(IMXRT_IOMUXC_ADDRESS + (pin_name >> 16) + 0x1f0); + volatile uint32_t *gdir = (volatile uint32_t*)((uint8_t *)&GPIO6_GDIR + 0x4000 * ((pin_name >> 5) & 0x7)); + uint32_t mask = 1 << (pin_name & 0x1f); + + Serial.printf("pinMode %x mux:%p pad:%p gdir:%p mask:%x\n", pin_name, mux, pad, gdir, mask); + + if (mode == OUTPUT || mode == OUTPUT_OPENDRAIN) { + *gdir |= mask; // TODO: atomic + if (mode == OUTPUT) { + *pad = IOMUXC_PAD_DSE(7); + } else { // OUTPUT_OPENDRAIN + *pad = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_ODE; + } + } else { + *gdir &= ~(mask); // TODO: atomic + if (mode == INPUT) { + *pad = IOMUXC_PAD_DSE(7); + } else if (mode == INPUT_PULLUP) { + *pad = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS; + } else if (mode == INPUT_PULLDOWN) { + *pad = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(0) | IOMUXC_PAD_HYS; + } else { // INPUT_DISABLE + *pad = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_HYS; + } + } + *mux = (uint8_t)(5 | 0x10); +} diff --git a/teensy4/core_pins.h b/teensy4/core_pins.h index 15b4f6bc..c6fcb615 100644 --- a/teensy4/core_pins.h +++ b/teensy4/core_pins.h @@ -47,8 +47,11 @@ #define FALLING 2 #define RISING 3 - -#if defined(__IMXRT1062__) && defined(ARDUINO_TEENSY40) +#if __has_include("variant.h") +# include "variant.h" +//#pragma message "core_pins.h" - included variant.h +// Default no override file +#elif defined(__IMXRT1062__) && defined(ARDUINO_TEENSY40) #define CORE_NUM_TOTAL_PINS 40 #define CORE_NUM_DIGITAL 40 @@ -1911,6 +1914,8 @@ static inline void digitalWriteFast(uint8_t pin, uint8_t val) } else if (pin == 54) { CORE_PIN54_PORTSET = CORE_PIN54_BITMASK; #endif + } else if (pin < CORE_NUM_DIGITAL) { + *portSetRegister(pin) = digitalPinToBitMask(pin); } } else { if (pin == 0) { @@ -2027,9 +2032,12 @@ static inline void digitalWriteFast(uint8_t pin, uint8_t val) } else if (pin == 54) { CORE_PIN54_PORTCLEAR = CORE_PIN54_BITMASK; #endif + } else if (pin < CORE_NUM_DIGITAL) { + *portClearRegister(pin) = digitalPinToBitMask(pin); } + } - } else { + } else if (pin < CORE_NUM_DIGITAL) { if(val) *portSetRegister(pin) = digitalPinToBitMask(pin); else *portClearRegister(pin) = digitalPinToBitMask(pin); } @@ -2161,11 +2169,15 @@ static inline uint8_t digitalReadFast(uint8_t pin) } else if (pin == 54) { return (CORE_PIN54_PINREG & CORE_PIN54_BITMASK) ? 1 : 0; #endif + } else if (pin < CORE_NUM_DIGITAL) { + return (*portInputRegister(pin) & digitalPinToBitMask(pin)) ? 1 : 0; } else { return 0; } - } else { + } else if (pin < CORE_NUM_DIGITAL) { return (*portInputRegister(pin) & digitalPinToBitMask(pin)) ? 1 : 0; + } else { + return 0; } } @@ -2295,9 +2307,11 @@ static inline void digitalToggleFast(uint8_t pin) } else if (pin == 54) { CORE_PIN54_PORTTOGGLE = CORE_PIN54_BITMASK; #endif + } else { + digitalToggle(pin); } - } else { - digitalToggle(pin); + } else if (pin < CORE_NUM_DIGITAL) { + *portToggleRegister(pin) = digitalPinToBitMask(pin); } } diff --git a/teensy4/digital.c b/teensy4/digital.c index 587effd4..3129a6d6 100644 --- a/teensy4/digital.c +++ b/teensy4/digital.c @@ -21,7 +21,7 @@ extern const struct digital_pin_bitband_and_config_table_struct digital_pin_to_i #define digitalPinToPortReg(pin) (portOutputRegister(pin)) */ -const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = { +const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] __attribute__((weak)) = { {&CORE_PIN0_PORTREG, &CORE_PIN0_CONFIG, &CORE_PIN0_PADCONFIG, CORE_PIN0_BITMASK}, {&CORE_PIN1_PORTREG, &CORE_PIN1_CONFIG, &CORE_PIN1_PADCONFIG, CORE_PIN1_BITMASK}, {&CORE_PIN2_PORTREG, &CORE_PIN2_CONFIG, &CORE_PIN2_PADCONFIG, CORE_PIN2_BITMASK}, diff --git a/teensy4/extmem.c b/teensy4/extmem.c index 1000b1b8..27db8423 100644 --- a/teensy4/extmem.c +++ b/teensy4/extmem.c @@ -45,7 +45,7 @@ void *extmem_calloc(size_t nmemb, size_t size) void *extmem_realloc(void *ptr, size_t size) { #ifdef HAS_EXTRAM - if (IS_EXTMEM(ptr)) { + if (IS_EXTMEM(ptr) || ptr == NULL) { return sm_realloc_pool(&extmem_smalloc_pool, ptr, size); } #endif diff --git a/teensy4/new.cpp b/teensy4/new.cpp index 51ce141e..606cfc58 100644 --- a/teensy4/new.cpp +++ b/teensy4/new.cpp @@ -23,7 +23,8 @@ * SOFTWARE. */ -#include +#include +#include void * operator new(size_t size) { @@ -55,3 +56,32 @@ void operator delete[](void * ptr, size_t size __attribute__((unused))) free(ptr); } +void * operator new(size_t size, std::align_val_t align) +{ + return aligned_alloc((size_t)align, size); +} + +void * operator new[](size_t size, std::align_val_t align) +{ + return aligned_alloc((size_t)align, size); +} + +void operator delete(void * ptr, std::align_val_t align __attribute__((unused))) +{ + free(ptr); +} + +void operator delete[](void * ptr, std::align_val_t align __attribute__((unused))) +{ + free(ptr); +} + +void operator delete(void * ptr, size_t size __attribute__((unused)), std::align_val_t align __attribute__((unused))) +{ + free(ptr); +} + +void operator delete[](void * ptr, size_t size __attribute__((unused)), std::align_val_t align __attribute__((unused))) +{ + free(ptr); +} diff --git a/teensy4/pwm.c b/teensy4/pwm.c index 9800f4d7..b023ce87 100644 --- a/teensy4/pwm.c +++ b/teensy4/pwm.c @@ -16,7 +16,7 @@ uint8_t analog_write_res = 8; #if defined(__IMXRT1062__) -const struct pwm_pin_info_struct pwm_pin_info[] = { +const struct pwm_pin_info_struct pwm_pin_info[] __attribute__((weak)) = { {1, M(1, 1), 0, 4}, // FlexPWM1_1_X 0 // AD_B0_03 {1, M(1, 0), 0, 4}, // FlexPWM1_0_X 1 // AD_B0_02 {1, M(4, 2), 1, 1}, // FlexPWM4_2_A 2 // EMC_04 diff --git a/teensy4/startup.c b/teensy4/startup.c index 2375f26c..4bb3bd40 100644 --- a/teensy4/startup.c +++ b/teensy4/startup.c @@ -318,6 +318,9 @@ FLASHMEM void configure_cache(void) SCB_MPU_RBAR = 0x70000000 | REGION(i++); // FlexSPI2 SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_16M; + // We default RAM meant for data to NOEXEC as a proactive security measure. + // If you wish to dynamically load code into RAM and execute it, start here: + // https://forum.pjrc.com/index.php?threads/75610/#post-347791 SCB_MPU_RBAR = 0x80000000 | REGION(i++); // SEMC: SDRAM, NAND, SRAM, etc SCB_MPU_RASR = MEM_CACHE_WBWA | READWRITE | NOEXEC | SIZE_1G;