T4.x Reduce EventResponder overhead on systic and yieldteensy4-core
| bool EventResponder::runningFromYield = false; | bool EventResponder::runningFromYield = false; | ||||
| // TODO: interrupt disable/enable needed in many places!!! | // TODO: interrupt disable/enable needed in many places!!! | ||||
| // BUGBUG: See if file name order makes difference? | |||||
| uint8_t _serialEvent_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| uint8_t _serialEventUSB1_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| uint8_t _serialEventUSB2_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| void EventResponder::triggerEventNotImmediate() | void EventResponder::triggerEventNotImmediate() | ||||
| { | { | ||||
| // with libraries using mid-to-high priority interrupts. | // with libraries using mid-to-high priority interrupts. | ||||
| extern "C" volatile uint32_t systick_millis_count; | extern "C" volatile uint32_t systick_millis_count; | ||||
| void systick_isr(void) | void systick_isr(void) | ||||
| { | |||||
| systick_millis_count++; | |||||
| } | |||||
| extern "C" void systick_isr_with_timer_events(void) | |||||
| { | { | ||||
| systick_millis_count++; | systick_millis_count++; | ||||
| MillisTimer::runFromTimer(); | MillisTimer::runFromTimer(); | ||||
| } | } | ||||
| * your function is called only one time, based on the last trigger | * your function is called only one time, based on the last trigger | ||||
| * event. | * event. | ||||
| */ | */ | ||||
| extern "C" void systick_isr_with_timer_events(void); | |||||
| class EventResponder; | class EventResponder; | ||||
| typedef EventResponder& EventResponderRef; | typedef EventResponder& EventResponderRef; | ||||
| detachNoInterrupts(); | detachNoInterrupts(); | ||||
| _function = function; | _function = function; | ||||
| _type = EventTypeYield; | _type = EventTypeYield; | ||||
| yield_active_check_flags |= YIELD_CHECK_EVENT_RESPONDER; // user setup a yield type... | |||||
| enableInterrupts(irq); | enableInterrupts(irq); | ||||
| } | } | ||||
| _function = function; | _function = function; | ||||
| _type = EventTypeInterrupt; | _type = EventTypeInterrupt; | ||||
| SCB_SHPR3 |= 0x00FF0000; // configure PendSV, lowest priority | SCB_SHPR3 |= 0x00FF0000; // configure PendSV, lowest priority | ||||
| // Make sure we are using the systic ISR that process this | |||||
| _VectorsRam[15] = systick_isr_with_timer_events; | |||||
| enableInterrupts(irq); | enableInterrupts(irq); | ||||
| } | } | ||||
| EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout); | EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout); | ||||
| static void runFromYield() { | static void runFromYield() { | ||||
| if (!firstYield) return; | |||||
| // First, check if yield was called from an interrupt | // First, check if yield was called from an interrupt | ||||
| // never call normal handler functions from any interrupt context | // never call normal handler functions from any interrupt context | ||||
| uint32_t ipsr; | uint32_t ipsr; |
| /* Teensyduino Core Library | |||||
| * http://www.pjrc.com/teensy/ | |||||
| * Copyright (c) 2019 PJRC.COM, LLC. | |||||
| * | |||||
| * Permission is hereby granted, free of charge, to any person obtaining | |||||
| * a copy of this software and associated documentation files (the | |||||
| * "Software"), to deal in the Software without restriction, including | |||||
| * without limitation the rights to use, copy, modify, merge, publish, | |||||
| * distribute, sublicense, and/or sell copies of the Software, and to | |||||
| * permit persons to whom the Software is furnished to do so, subject to | |||||
| * the following conditions: | |||||
| * | |||||
| * 1. The above copyright notice and this permission notice shall be | |||||
| * included in all copies or substantial portions of the Software. | |||||
| * | |||||
| * 2. If the Software is incorporated into a build system that allows | |||||
| * selection among a list of target devices, then similar target | |||||
| * devices manufactured by PJRC.COM must be included in the list of | |||||
| * target devices and selectable in the same manner. | |||||
| * | |||||
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||||
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |||||
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||||
| * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | |||||
| * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | |||||
| * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||||
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||||
| * SOFTWARE. | |||||
| */ | |||||
| #include "HardwareSerial.h" | |||||
| #include "core_pins.h" | |||||
| #include "Arduino.h" | |||||
| // define our static objects | |||||
| HardwareSerial *HardwareSerial::s_serials_with_serial_events[CNT_HARDWARE_SERIAL]; | |||||
| uint8_t HardwareSerial::s_count_serials_with_serial_events = 0; | |||||
| // simple helper function that add us to the list of Serial ports that have | |||||
| // their own serialEvent code defined that needs to be called at yield. | |||||
| void HardwareSerial::addToSerialEventsList() { | |||||
| s_serials_with_serial_events[s_count_serials_with_serial_events++] = this; | |||||
| yield_active_check_flags |= YIELD_CHECK_HARDWARE_SERIAL; | |||||
| } | |||||
| class HardwareSerial : public Stream | class HardwareSerial : public Stream | ||||
| { | { | ||||
| public: | public: | ||||
| constexpr HardwareSerial() {} | |||||
| virtual void begin(uint32_t baud) { serial_begin(BAUD2DIV(baud)); } | |||||
| constexpr HardwareSerial(void (* const se)()) : _serialEvent(se) {} | |||||
| #if defined(__MK64FX512__) || defined(__MK66FX1M0__) | |||||
| enum {CNT_HARDWARE_SERIAL = 6}; | |||||
| #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) { | virtual void begin(uint32_t baud, uint32_t format) { | ||||
| serial_begin(BAUD2DIV(baud)); | serial_begin(BAUD2DIV(baud)); | ||||
| serial_format(format); } | serial_format(format); } | ||||
| return len; } | return len; } | ||||
| virtual size_t write9bit(uint32_t c) { serial_putchar(c); return 1; } | virtual size_t write9bit(uint32_t c) { serial_putchar(c); return 1; } | ||||
| operator bool() { return true; } | operator bool() { return true; } | ||||
| static inline void processSerialEventsList() { | |||||
| for (uint8_t i = 0; i < s_count_serials_with_serial_events; i++) { | |||||
| s_serials_with_serial_events[i]->doYieldCode(); | |||||
| } | |||||
| } | |||||
| protected: | |||||
| static HardwareSerial *s_serials_with_serial_events[CNT_HARDWARE_SERIAL]; | |||||
| static uint8_t s_count_serials_with_serial_events; | |||||
| void (* const _serialEvent)(); | |||||
| void addToSerialEventsList(); | |||||
| inline void doYieldCode() { | |||||
| if (available()) (*_serialEvent)(); | |||||
| } | |||||
| }; | }; | ||||
| extern HardwareSerial Serial1; | extern HardwareSerial Serial1; | ||||
| extern void serialEvent1(void); | extern void serialEvent1(void); | ||||
| class HardwareSerial2 : public HardwareSerial | class HardwareSerial2 : public HardwareSerial | ||||
| { | { | ||||
| public: | public: | ||||
| constexpr HardwareSerial2() {} | |||||
| virtual void begin(uint32_t baud) { serial2_begin(BAUD2DIV2(baud)); } | |||||
| constexpr HardwareSerial2(void (* const se)()) : HardwareSerial(se) {} | |||||
| virtual void begin(uint32_t baud); | |||||
| virtual void begin(uint32_t baud, uint32_t format) { | virtual void begin(uint32_t baud, uint32_t format) { | ||||
| serial2_begin(BAUD2DIV2(baud)); | serial2_begin(BAUD2DIV2(baud)); | ||||
| serial2_format(format); } | serial2_format(format); } | ||||
| class HardwareSerial3 : public HardwareSerial | class HardwareSerial3 : public HardwareSerial | ||||
| { | { | ||||
| public: | public: | ||||
| constexpr HardwareSerial3() {} | |||||
| virtual void begin(uint32_t baud) { serial3_begin(BAUD2DIV3(baud)); } | |||||
| constexpr HardwareSerial3(void (* const se)()) : HardwareSerial(se) {} | |||||
| virtual void begin(uint32_t baud); | |||||
| virtual void begin(uint32_t baud, uint32_t format) { | virtual void begin(uint32_t baud, uint32_t format) { | ||||
| serial3_begin(BAUD2DIV3(baud)); | serial3_begin(BAUD2DIV3(baud)); | ||||
| serial3_format(format); } | serial3_format(format); } | ||||
| class HardwareSerial4 : public HardwareSerial | class HardwareSerial4 : public HardwareSerial | ||||
| { | { | ||||
| public: | public: | ||||
| constexpr HardwareSerial4() {} | |||||
| virtual void begin(uint32_t baud) { serial4_begin(BAUD2DIV3(baud)); } | |||||
| constexpr HardwareSerial4(void (* const se)()) : HardwareSerial(se) {} | |||||
| virtual void begin(uint32_t baud); | |||||
| virtual void begin(uint32_t baud, uint32_t format) { | virtual void begin(uint32_t baud, uint32_t format) { | ||||
| serial4_begin(BAUD2DIV3(baud)); | serial4_begin(BAUD2DIV3(baud)); | ||||
| serial4_format(format); } | serial4_format(format); } | ||||
| class HardwareSerial5 : public HardwareSerial | class HardwareSerial5 : public HardwareSerial | ||||
| { | { | ||||
| public: | public: | ||||
| constexpr HardwareSerial5() {} | |||||
| virtual void begin(uint32_t baud) { serial5_begin(BAUD2DIV3(baud)); } | |||||
| constexpr HardwareSerial5(void (* const se)()) : HardwareSerial(se) {} | |||||
| virtual void begin(uint32_t baud); | |||||
| virtual void begin(uint32_t baud, uint32_t format) { | virtual void begin(uint32_t baud, uint32_t format) { | ||||
| serial5_begin(BAUD2DIV3(baud)); | serial5_begin(BAUD2DIV3(baud)); | ||||
| serial5_format(format); } | serial5_format(format); } | ||||
| class HardwareSerial6 : public HardwareSerial | class HardwareSerial6 : public HardwareSerial | ||||
| { | { | ||||
| public: | public: | ||||
| constexpr HardwareSerial6() {} | |||||
| constexpr HardwareSerial6(void (* const se)()) : HardwareSerial(se) {} | |||||
| #if defined(__MK66FX1M0__) // For LPUART just pass baud straight in. | #if defined(__MK66FX1M0__) // For LPUART just pass baud straight in. | ||||
| virtual void begin(uint32_t baud) { serial6_begin(baud); } | |||||
| virtual void begin(uint32_t baud); | |||||
| virtual void begin(uint32_t baud, uint32_t format) { | virtual void begin(uint32_t baud, uint32_t format) { | ||||
| serial6_begin(baud); | serial6_begin(baud); | ||||
| serial6_format(format); } | serial6_format(format); } | ||||
| #else | #else | ||||
| virtual void begin(uint32_t baud) { serial6_begin(BAUD2DIV3(baud)); } | |||||
| virtual void begin(uint32_t baud); | |||||
| virtual void begin(uint32_t baud, uint32_t format) { | virtual void begin(uint32_t baud, uint32_t format) { | ||||
| serial6_begin(BAUD2DIV3(baud)); | serial6_begin(BAUD2DIV3(baud)); | ||||
| serial6_format(format); } | serial6_format(format); } |
| #include <Arduino.h> | #include <Arduino.h> | ||||
| #include "HardwareSerial.h" | #include "HardwareSerial.h" | ||||
| HardwareSerial Serial1; | |||||
| void serialEvent1() __attribute__((weak)); | |||||
| void serialEvent1() {} | |||||
| uint8_t _serialEvent1_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| HardwareSerial Serial1(&serialEvent1); | |||||
| void HardwareSerial::begin(uint32_t baud) { | |||||
| serial_begin(BAUD2DIV(baud)); | |||||
| if (!_serialEvent1_default) addToSerialEventsList(); | |||||
| } | |||||
| * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
| * SOFTWARE. | * SOFTWARE. | ||||
| */ | */ | ||||
| #include <Arduino.h> | #include <Arduino.h> | ||||
| #include "HardwareSerial.h" | #include "HardwareSerial.h" | ||||
| HardwareSerial2 Serial2; | |||||
| HardwareSerial2 Serial2(&serialEvent2); | |||||
| uint8_t _serialEvent2_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| void serialEvent2() __attribute__((weak)); | |||||
| void serialEvent2() {} | |||||
| void HardwareSerial2::begin(uint32_t baud) { | |||||
| serial2_begin(BAUD2DIV2(baud)); | |||||
| if (!_serialEvent2_default) addToSerialEventsList(); | |||||
| } |
| #include <Arduino.h> | #include <Arduino.h> | ||||
| #include "HardwareSerial.h" | #include "HardwareSerial.h" | ||||
| HardwareSerial3 Serial3; | |||||
| HardwareSerial3 Serial3(&serialEvent3); | |||||
| void serialEvent3() __attribute__((weak)); | |||||
| void serialEvent3() {} | |||||
| uint8_t _serialEvent3_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| void HardwareSerial3::begin(uint32_t baud) { | |||||
| serial3_begin(BAUD2DIV3(baud)); | |||||
| if (!_serialEvent3_default) addToSerialEventsList(); | |||||
| } |
| #ifdef HAS_KINETISK_UART3 | #ifdef HAS_KINETISK_UART3 | ||||
| HardwareSerial4 Serial4; | |||||
| HardwareSerial4 Serial4(&serialEvent4); | |||||
| void serialEvent4() __attribute__((weak)); | |||||
| void serialEvent4() {} | |||||
| uint8_t _serialEvent4_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| void HardwareSerial4::begin(uint32_t baud) { | |||||
| serial4_begin(BAUD2DIV3(baud)); | |||||
| if (!_serialEvent4_default) addToSerialEventsList(); | |||||
| } | |||||
| #endif | #endif |
| #ifdef HAS_KINETISK_UART4 | #ifdef HAS_KINETISK_UART4 | ||||
| HardwareSerial5 Serial5; | |||||
| HardwareSerial5 Serial5(&serialEvent5); | |||||
| void serialEvent5() __attribute__((weak)); | |||||
| void serialEvent5() {} | |||||
| uint8_t _serialEvent5_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| void HardwareSerial5::begin(uint32_t baud) { | |||||
| serial5_begin(BAUD2DIV3(baud)); | |||||
| if (!_serialEvent5_default) addToSerialEventsList(); | |||||
| } | |||||
| #endif | #endif |
| #if defined(HAS_KINETISK_UART5) || defined (HAS_KINETISK_LPUART0) | #if defined(HAS_KINETISK_UART5) || defined (HAS_KINETISK_LPUART0) | ||||
| HardwareSerial6 Serial6; | |||||
| HardwareSerial6 Serial6(&serialEvent6); | |||||
| void serialEvent6() __attribute__((weak)); | |||||
| void serialEvent6() {} | |||||
| uint8_t _serialEvent6_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| void HardwareSerial6::begin(uint32_t baud) { | |||||
| #if defined(__MK66FX1M0__) // For LPUART just pass baud straight in. | |||||
| serial6_begin(baud); | |||||
| #else | |||||
| serial6_begin(BAUD2DIV3(baud)); | |||||
| #endif | |||||
| if (!_serialEvent6_default) addToSerialEventsList(); | |||||
| } | |||||
| #endif | #endif |
| void _reboot_Teensyduino_(void) __attribute__((noreturn)); | void _reboot_Teensyduino_(void) __attribute__((noreturn)); | ||||
| void _restart_Teensyduino_(void) __attribute__((noreturn)); | void _restart_Teensyduino_(void) __attribute__((noreturn)); | ||||
| // Define a set of flags to know which things yield should check when called. | |||||
| // Probably should be in a better spot. | |||||
| extern uint8_t yield_active_check_flags; | |||||
| #define YIELD_CHECK_USB_SERIAL 0x1 // check the USB for Serial.available() | |||||
| #define YIELD_CHECK_HARDWARE_SERIAL 0x2 // check Hardware Serial ports available | |||||
| #define YIELD_CHECK_EVENT_RESPONDER 0x4 // User has created eventResponders that use yield | |||||
| void yield(void); | void yield(void); | ||||
| void delay(uint32_t msec); | void delay(uint32_t msec); |
| #include <Arduino.h> | |||||
| void serialEvent() __attribute__((weak)); | |||||
| void serialEvent() { | |||||
| } | |||||
| uint8_t _serialEvent_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent1() __attribute__((weak)); | |||||
| void serialEvent1() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent1_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent2() __attribute__((weak)); | |||||
| void serialEvent2() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent2_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent3() __attribute__((weak)); | |||||
| void serialEvent3() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent3_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| #ifdef HAS_KINETISK_UART3 | |||||
| void serialEvent4() __attribute__((weak)); | |||||
| void serialEvent4() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent4_default PROGMEM = 1; | |||||
| #endif |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| #ifdef HAS_KINETISK_UART4 | |||||
| void serialEvent5() __attribute__((weak)); | |||||
| void serialEvent5() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent5_default PROGMEM = 1; | |||||
| #endif |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| #if defined(HAS_KINETISK_UART5) || defined (HAS_KINETISK_LPUART0) | |||||
| void serialEvent6() __attribute__((weak)); | |||||
| void serialEvent6() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent6_default PROGMEM = 1; | |||||
| #endif |
| #endif // F_CPU | #endif // F_CPU | ||||
| void serialEvent() __attribute__((weak)); | |||||
| void serialEvent() {} | |||||
| //void serialEvent() __attribute__((weak)); | |||||
| //void serialEvent() {} | |||||
| void serialEventUSB1() __attribute__((weak)); | void serialEventUSB1() __attribute__((weak)); | ||||
| void serialEventUSB1() {} | void serialEventUSB1() {} | ||||
| void serialEventUSB2() __attribute__((weak)); | void serialEventUSB2() __attribute__((weak)); |
| #include <Arduino.h> | #include <Arduino.h> | ||||
| #include "EventResponder.h" | #include "EventResponder.h" | ||||
| #ifdef USB_TRIPLE_SERIAL | |||||
| uint8_t yield_active_check_flags = YIELD_CHECK_USB_SERIAL | YIELD_CHECK_USB_SERIALUSB1 | YIELD_CHECK_USB_SERIALUSB2; // default to check USB. | |||||
| #elif defined(USB_DUAL_SERIAL) | |||||
| uint8_t yield_active_check_flags = YIELD_CHECK_USB_SERIAL | YIELD_CHECK_USB_SERIALUSB1; // default to check USB. | |||||
| #else | |||||
| uint8_t yield_active_check_flags = YIELD_CHECK_USB_SERIAL; // default to check USB. | |||||
| #endif | |||||
| extern const uint8_t _serialEvent_default; | |||||
| void yield(void) __attribute__ ((weak)); | void yield(void) __attribute__ ((weak)); | ||||
| void yield(void) | void yield(void) | ||||
| { | { | ||||
| static uint8_t running=0; | static uint8_t running=0; | ||||
| if (!yield_active_check_flags) return; // nothing to do | |||||
| if (running) return; // TODO: does this need to be atomic? | if (running) return; // TODO: does this need to be atomic? | ||||
| running = 1; | running = 1; | ||||
| if (Serial.available()) serialEvent(); | |||||
| // USB Serail - Add hack to minimize impact... | |||||
| if (yield_active_check_flags & YIELD_CHECK_USB_SERIAL) { | |||||
| if (Serial.available()) serialEvent(); | |||||
| if (_serialEvent_default) yield_active_check_flags &= ~YIELD_CHECK_USB_SERIAL; | |||||
| } | |||||
| // Current workaround until integrate with EventResponder. | |||||
| #if defined(USB_DUAL_SERIAL) || defined(USB_TRIPLE_SERIAL) | #if defined(USB_DUAL_SERIAL) || defined(USB_TRIPLE_SERIAL) | ||||
| if (SerialUSB1.available()) serialEventUSB1(); | |||||
| if (yield_active_check_flags & YIELD_CHECK_USB_SERIALUSB1) { | |||||
| if (SerialUSB1.available()) serialEventUSB1(); | |||||
| if (_serialEventUSB1_default) yield_active_check_flags &= ~YIELD_CHECK_USB_SERIALUSB1; | |||||
| } | |||||
| #endif | #endif | ||||
| #ifdef USB_TRIPLE_SERIAL | #ifdef USB_TRIPLE_SERIAL | ||||
| if (SerialUSB2.available()) serialEventUSB2(); | |||||
| #endif | |||||
| if (Serial1.available()) serialEvent1(); | |||||
| if (Serial2.available()) serialEvent2(); | |||||
| if (Serial3.available()) serialEvent3(); | |||||
| #ifdef HAS_KINETISK_UART3 | |||||
| if (Serial4.available()) serialEvent4(); | |||||
| #endif | |||||
| #ifdef HAS_KINETISK_UART4 | |||||
| if (Serial5.available()) serialEvent5(); | |||||
| #endif | |||||
| #if defined(HAS_KINETISK_UART5) || defined (HAS_KINETISK_LPUART0) | |||||
| if (Serial6.available()) serialEvent6(); | |||||
| if (yield_active_check_flags & YIELD_CHECK_USB_SERIALUSB2) { | |||||
| if (SerialUSB1.available()) serialEventUSB1(); | |||||
| if (_serialEventUSB2_default) yield_active_check_flags &= ~YIELD_CHECK_USB_SERIALUSB2; | |||||
| } | |||||
| #endif | #endif | ||||
| if (yield_active_check_flags & YIELD_CHECK_HARDWARE_SERIAL) { | |||||
| HardwareSerial::processSerialEventsList(); | |||||
| } | |||||
| running = 0; | running = 0; | ||||
| EventResponder::runFromYield(); | |||||
| if (yield_active_check_flags & YIELD_CHECK_EVENT_RESPONDER) EventResponder::runFromYield(); | |||||
| }; | }; |
| bool EventResponder::runningFromYield = false; | bool EventResponder::runningFromYield = false; | ||||
| // TODO: interrupt disable/enable needed in many places!!! | // TODO: interrupt disable/enable needed in many places!!! | ||||
| // BUGBUG: See if file name order makes difference? | |||||
| uint8_t _serialEvent_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| void EventResponder::triggerEventNotImmediate() | void EventResponder::triggerEventNotImmediate() | ||||
| { | { | ||||
| { | { | ||||
| systick_cycle_count = ARM_DWT_CYCCNT; | systick_cycle_count = ARM_DWT_CYCCNT; | ||||
| systick_millis_count++; | systick_millis_count++; | ||||
| MillisTimer::runFromTimer(); | |||||
| } | } | ||||
| extern "C" void systick_isr_with_timer_events(void) | |||||
| { | |||||
| systick_cycle_count = ARM_DWT_CYCCNT; | |||||
| systick_millis_count++; | |||||
| MillisTimer::runFromTimer(); | |||||
| } | |||||
| * your function is called only one time, based on the last trigger | * your function is called only one time, based on the last trigger | ||||
| * event. | * event. | ||||
| */ | */ | ||||
| extern "C" void systick_isr_with_timer_events(void); | |||||
| class EventResponder; | class EventResponder; | ||||
| typedef EventResponder& EventResponderRef; | typedef EventResponder& EventResponderRef; | ||||
| detachNoInterrupts(); | detachNoInterrupts(); | ||||
| _function = function; | _function = function; | ||||
| _type = EventTypeYield; | _type = EventTypeYield; | ||||
| yield_active_check_flags |= YIELD_CHECK_EVENT_RESPONDER; // user setup a yield type... | |||||
| enableInterrupts(irq); | enableInterrupts(irq); | ||||
| } | } | ||||
| _function = function; | _function = function; | ||||
| _type = EventTypeInterrupt; | _type = EventTypeInterrupt; | ||||
| SCB_SHPR3 |= 0x00FF0000; // configure PendSV, lowest priority | SCB_SHPR3 |= 0x00FF0000; // configure PendSV, lowest priority | ||||
| // Make sure we are using the systic ISR that process this | |||||
| _VectorsRam[15] = systick_isr_with_timer_events; | |||||
| enableInterrupts(irq); | enableInterrupts(irq); | ||||
| } | } | ||||
| // used with a scheduler or RTOS. | // used with a scheduler or RTOS. | ||||
| bool waitForEvent(EventResponderRef event, int timeout); | bool waitForEvent(EventResponderRef event, int timeout); | ||||
| EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout); | EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout); | ||||
| static void runFromYield() { | static void runFromYield() { | ||||
| if (!firstYield) return; | |||||
| if (!firstYield) return; | |||||
| // First, check if yield was called from an interrupt | // First, check if yield was called from an interrupt | ||||
| // never call normal handler functions from any interrupt context | // never call normal handler functions from any interrupt context | ||||
| uint32_t ipsr; | uint32_t ipsr; |
| #define UART_CLOCK 24000000 | #define UART_CLOCK 24000000 | ||||
| extern "C" { | |||||
| extern void xbar_connect(unsigned int input, unsigned int output); | |||||
| } | |||||
| #if defined(ARDUINO_TEENSY41) | #if defined(ARDUINO_TEENSY41) | ||||
| SerialEventCheckingFunctionPointer HardwareSerial::serial_event_handler_checks[8] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; | |||||
| HardwareSerial *HardwareSerial::s_serials_with_serial_events[8]; | |||||
| #else | #else | ||||
| SerialEventCheckingFunctionPointer HardwareSerial::serial_event_handler_checks[7] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr}; | |||||
| HardwareSerial *HardwareSerial::s_serials_with_serial_events[7]; | |||||
| #endif | #endif | ||||
| uint8_t HardwareSerial::serial_event_handlers_active = 0; | |||||
| // define our static objects | |||||
| uint8_t HardwareSerial::s_count_serials_with_serial_events = 0; | |||||
| #define CTRL_ENABLE (LPUART_CTRL_TE | LPUART_CTRL_RE | LPUART_CTRL_RIE | LPUART_CTRL_ILIE) | #define CTRL_ENABLE (LPUART_CTRL_TE | LPUART_CTRL_RE | LPUART_CTRL_RIE | LPUART_CTRL_ILIE) | ||||
| if ( format & 0x100) port->BAUD |= LPUART_BAUD_SBNS; | if ( format & 0x100) port->BAUD |= LPUART_BAUD_SBNS; | ||||
| //Serial.printf(" stat:%x ctrl:%x fifo:%x water:%x\n", port->STAT, port->CTRL, port->FIFO, port->WATER ); | //Serial.printf(" stat:%x ctrl:%x fifo:%x water:%x\n", port->STAT, port->CTRL, port->FIFO, port->WATER ); | ||||
| enableSerialEvents(); // Enable the processing of serialEvent for this object | |||||
| // Only if the user implemented their own... | |||||
| if (!(*hardware->serial_event_handler_default)) addToSerialEventsList(); // Enable the processing of serialEvent for this object | |||||
| }; | }; | ||||
| inline void HardwareSerial::rts_assert() | inline void HardwareSerial::rts_assert() | ||||
| rx_buffer_tail_ = 0; | rx_buffer_tail_ = 0; | ||||
| if (rts_pin_baseReg_) rts_deassert(); | if (rts_pin_baseReg_) rts_deassert(); | ||||
| // | // | ||||
| disableSerialEvents(); // disable the processing of serialEvent for this object | |||||
| } | } | ||||
| void HardwareSerial::transmitterEnable(uint8_t pin) | void HardwareSerial::transmitterEnable(uint8_t pin) | ||||
| // new pin - so lets maybe reset the old pin to INPUT? and then set new pin parameters | // new pin - so lets maybe reset the old pin to INPUT? and then set new pin parameters | ||||
| // only change IO pins if done after begin has been called. | // only change IO pins if done after begin has been called. | ||||
| if ((hardware->ccm_register & hardware->ccm_value)) { | if ((hardware->ccm_register & hardware->ccm_value)) { | ||||
| *(portConfigRegister(hardware->rx_pins[rx_pin_index_].pin)) = 5; | |||||
| *(portConfigRegister(hardware->rx_pins[rx_pin_index_].pin)) = 5; | |||||
| // now set new pin info. | |||||
| // now set new pin info. | |||||
| *(portControlRegister(hardware->rx_pins[rx_pin_new_index].pin)) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS;; | *(portControlRegister(hardware->rx_pins[rx_pin_new_index].pin)) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(3) | IOMUXC_PAD_HYS;; | ||||
| *(portConfigRegister(hardware->rx_pins[rx_pin_new_index].pin)) = hardware->rx_pins[rx_pin_new_index].mux_val; | *(portConfigRegister(hardware->rx_pins[rx_pin_new_index].pin)) = hardware->rx_pins[rx_pin_new_index].mux_val; | ||||
| if (hardware->rx_pins[rx_pin_new_index].select_input_register) { | if (hardware->rx_pins[rx_pin_new_index].select_input_register) { | ||||
| } | } | ||||
| } | } | ||||
| rx_pin_index_ = rx_pin_new_index; | rx_pin_index_ = rx_pin_new_index; | ||||
| break; | |||||
| return; // done. | |||||
| } | |||||
| } | |||||
| // If we got to here and did not find a valid pin there. Maybe see if it is an XBar pin... | |||||
| for (uint8_t i = 0; i < count_pin_to_xbar_info; i++) { | |||||
| if (pin_to_xbar_info[i].pin == pin) { | |||||
| // So it is an XBAR pin set the XBAR.. | |||||
| //Serial.printf("ACTS XB(%d), X(%u %u), MUX:%x\n", i, pin_to_xbar_info[i].xbar_in_index, | |||||
| // hardware->xbar_out_lpuartX_trig_input, pin_to_xbar_info[i].mux_val); | |||||
| CCM_CCGR2 |= CCM_CCGR2_XBAR1(CCM_CCGR_ON); | |||||
| xbar_connect(pin_to_xbar_info[i].xbar_in_index, hardware->xbar_out_lpuartX_trig_input); | |||||
| // We need to update port register to use this as the trigger | |||||
| port->PINCFG = LPUART_PINCFG_TRGSEL(1); // Trigger select as alternate RX | |||||
| // 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); | |||||
| return; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| port->MODIR |= LPUART_MODIR_TXCTSE; | port->MODIR |= LPUART_MODIR_TXCTSE; | ||||
| return true; | return true; | ||||
| } else { | } else { | ||||
| // See maybe this a pin we can use XBAR for. | |||||
| for (uint8_t i = 0; i < count_pin_to_xbar_info; i++) { | |||||
| if (pin_to_xbar_info[i].pin == pin) { | |||||
| // So it is an XBAR pin set the XBAR.. | |||||
| //Serial.printf("ACTS XB(%d), X(%u %u), MUX:%x\n", i, pin_to_xbar_info[i].xbar_in_index, | |||||
| // hardware->xbar_out_lpuartX_trig_input, pin_to_xbar_info[i].mux_val); | |||||
| CCM_CCGR2 |= CCM_CCGR2_XBAR1(CCM_CCGR_ON); | |||||
| xbar_connect(pin_to_xbar_info[i].xbar_in_index, hardware->xbar_out_lpuartX_trig_input); | |||||
| // We need to update port register to use this as the trigger | |||||
| port->PINCFG = LPUART_PINCFG_TRGSEL(2); // Trigger select as alternate CTS pin | |||||
| // configure the pin. | |||||
| *(portControlRegister(pin)) = IOMUXC_PAD_DSE(7) | IOMUXC_PAD_PKE | IOMUXC_PAD_PUE | IOMUXC_PAD_PUS(0) | IOMUXC_PAD_HYS; | |||||
| *(portConfigRegister(pin)) = pin_to_xbar_info[i].mux_val; | |||||
| if (pin_to_xbar_info[i].select_input_register) *(pin_to_xbar_info[i].select_input_register) = pin_to_xbar_info[i].select_val; | |||||
| port->MODIR |= LPUART_MODIR_TXCTSE; | |||||
| //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); | |||||
| return true; | |||||
| } | |||||
| } | |||||
| // Fell through so not valid pin for this. | |||||
| port->MODIR &= ~LPUART_MODIR_TXCTSE; | port->MODIR &= ~LPUART_MODIR_TXCTSE; | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| void HardwareSerial::processSerialEvents() | |||||
| { | |||||
| if (!serial_event_handlers_active) return; // bail quick if no one processing SerialEvents. | |||||
| uint8_t handlers_still_to_process = serial_event_handlers_active; | |||||
| for (uint8_t i = 0; i < 8; i++) { | |||||
| if (serial_event_handler_checks[i]) { | |||||
| (*serial_event_handler_checks[i])(); | |||||
| if (--handlers_still_to_process == 0) return; | |||||
| } | |||||
| } | |||||
| void HardwareSerial::addToSerialEventsList() { | |||||
| s_serials_with_serial_events[s_count_serials_with_serial_events++] = this; | |||||
| yield_active_check_flags |= YIELD_CHECK_HARDWARE_SERIAL; | |||||
| } | } | ||||
| void HardwareSerial::enableSerialEvents() | |||||
| { | |||||
| if (!serial_event_handler_checks[hardware->serial_index]) { | |||||
| serial_event_handler_checks[hardware->serial_index] = hardware->serial_event_handler_check; // clear it out | |||||
| serial_event_handlers_active++; | |||||
| } | |||||
| } | |||||
| void HardwareSerial::disableSerialEvents() | |||||
| { | |||||
| if (serial_event_handler_checks[hardware->serial_index]) { | |||||
| serial_event_handler_checks[hardware->serial_index] = nullptr; // clear it out | |||||
| serial_event_handlers_active--; | |||||
| } | |||||
| } | |||||
| const pin_to_xbar_info_t PROGMEM pin_to_xbar_info[] = { | |||||
| {0, 17, 1, &IOMUXC_XBAR1_IN17_SELECT_INPUT, 0x1}, | |||||
| {1, 16, 1, nullptr, 0}, | |||||
| {2, 6, 3, &IOMUXC_XBAR1_IN06_SELECT_INPUT, 0x0}, | |||||
| {3, 7, 3, &IOMUXC_XBAR1_IN07_SELECT_INPUT, 0x0}, | |||||
| {4, 8, 3, &IOMUXC_XBAR1_IN08_SELECT_INPUT, 0x0}, | |||||
| {5, 17, 3, &IOMUXC_XBAR1_IN17_SELECT_INPUT, 0x0}, | |||||
| {7, 15, 1, nullptr, 0 }, | |||||
| {8, 14, 1, nullptr, 0}, | |||||
| {30, 23, 1, &IOMUXC_XBAR1_IN23_SELECT_INPUT, 0x0}, | |||||
| {31, 22, 1, &IOMUXC_XBAR1_IN22_SELECT_INPUT, 0x0}, | |||||
| {32, 10, 1, nullptr, 0}, | |||||
| {33, 9, 3, &IOMUXC_XBAR1_IN09_SELECT_INPUT, 0x0}, | |||||
| #ifdef ARDUINO_TEENSY41 | |||||
| {36, 16, 1, nullptr, 0}, | |||||
| {37, 17, 1, &IOMUXC_XBAR1_IN17_SELECT_INPUT, 0x3}, | |||||
| {42, 7, 3, &IOMUXC_XBAR1_IN07_SELECT_INPUT, 0x1}, | |||||
| {43, 6, 3, &IOMUXC_XBAR1_IN06_SELECT_INPUT, 0x1}, | |||||
| {44, 5, 3, &IOMUXC_XBAR1_IN05_SELECT_INPUT, 0x1}, | |||||
| {45, 4, 3, &IOMUXC_XBAR1_IN04_SELECT_INPUT, 0x1}, | |||||
| {46, 9, 3, &IOMUXC_XBAR1_IN09_SELECT_INPUT, 0x1}, | |||||
| {47, 8, 3, &IOMUXC_XBAR1_IN08_SELECT_INPUT, 0x1} | |||||
| #else | |||||
| {34, 7, 3, &IOMUXC_XBAR1_IN07_SELECT_INPUT, 0x1}, | |||||
| {35, 6, 3, &IOMUXC_XBAR1_IN06_SELECT_INPUT, 0x1}, | |||||
| {36, 5, 3, &IOMUXC_XBAR1_IN05_SELECT_INPUT, 0x1}, | |||||
| {37, 4, 3, &IOMUXC_XBAR1_IN04_SELECT_INPUT, 0x1}, | |||||
| {38, 9, 3, &IOMUXC_XBAR1_IN09_SELECT_INPUT, 0x1}, | |||||
| {39, 8, 3, &IOMUXC_XBAR1_IN08_SELECT_INPUT, 0x1} | |||||
| #endif | |||||
| }; | |||||
| const uint8_t PROGMEM count_pin_to_xbar_info = sizeof(pin_to_xbar_info)/sizeof(pin_to_xbar_info[0]); | |||||
| #endif | #endif | ||||
| } | } | ||||
| typedef void(*SerialEventCheckingFunctionPointer)(); | |||||
| //=================================================================== | |||||
| // Should find a good home for this | |||||
| // Map IO pin to XBar pin... | |||||
| //=================================================================== | |||||
| // BUGBUG - find a good home | |||||
| typedef struct _pin_to_xbar_info{ | |||||
| const uint8_t pin; // The pin number | |||||
| const uint8_t xbar_in_index; // What XBar input index. | |||||
| const uint32_t mux_val; // Value to set for mux; | |||||
| volatile uint32_t *select_input_register; // Which register controls the selection | |||||
| const uint32_t select_val; // Value for that selection | |||||
| } pin_to_xbar_info_t; | |||||
| extern const pin_to_xbar_info_t pin_to_xbar_info[]; | |||||
| extern const uint8_t count_pin_to_xbar_info; | |||||
| class HardwareSerial : public Stream | class HardwareSerial : public Stream | ||||
| { | { | ||||
| uint8_t serial_index; // which object are we? 0 based | uint8_t serial_index; // which object are we? 0 based | ||||
| IRQ_NUMBER_t irq; | IRQ_NUMBER_t irq; | ||||
| void (*irq_handler)(void); | void (*irq_handler)(void); | ||||
| void (*serial_event_handler_check)(void); | |||||
| void (* _serialEvent)(void); | |||||
| const uint8_t *serial_event_handler_default; | |||||
| volatile uint32_t &ccm_register; | volatile uint32_t &ccm_register; | ||||
| const uint32_t ccm_value; | const uint32_t ccm_value; | ||||
| pin_info_t rx_pins[cnt_rx_pins]; | pin_info_t rx_pins[cnt_rx_pins]; | ||||
| const uint16_t irq_priority; | const uint16_t irq_priority; | ||||
| const uint16_t rts_low_watermark; | const uint16_t rts_low_watermark; | ||||
| const uint16_t rts_high_watermark; | const uint16_t rts_high_watermark; | ||||
| const uint8_t xbar_out_lpuartX_trig_input; | |||||
| } hardware_t; | } hardware_t; | ||||
| public: | public: | ||||
| constexpr HardwareSerial(IMXRT_LPUART_t *myport, const hardware_t *myhardware, | constexpr HardwareSerial(IMXRT_LPUART_t *myport, const hardware_t *myhardware, | ||||
| size_t write9bit(uint32_t c); | size_t write9bit(uint32_t c); | ||||
| // Event Handler functions and data | // Event Handler functions and data | ||||
| void enableSerialEvents(); | |||||
| void disableSerialEvents(); | |||||
| static void processSerialEvents(); | |||||
| static uint8_t serial_event_handlers_active; | static uint8_t serial_event_handlers_active; | ||||
| using Print::write; | using Print::write; | ||||
| */ | */ | ||||
| operator bool() { return true; } | operator bool() { return true; } | ||||
| static inline void processSerialEventsList() { | |||||
| for (uint8_t i = 0; i < s_count_serials_with_serial_events; i++) { | |||||
| s_serials_with_serial_events[i]->doYieldCode(); | |||||
| } | |||||
| } | |||||
| private: | private: | ||||
| IMXRT_LPUART_t * const port; | IMXRT_LPUART_t * const port; | ||||
| const hardware_t * const hardware; | const hardware_t * const hardware; | ||||
| friend void IRQHandler_Serial7(); | friend void IRQHandler_Serial7(); | ||||
| #if defined(ARDUINO_TEENSY41) | #if defined(ARDUINO_TEENSY41) | ||||
| friend void IRQHandler_Serial8(); | friend void IRQHandler_Serial8(); | ||||
| static SerialEventCheckingFunctionPointer serial_event_handler_checks[8]; | |||||
| static HardwareSerial *s_serials_with_serial_events[8]; | |||||
| #else | #else | ||||
| static SerialEventCheckingFunctionPointer serial_event_handler_checks[7]; | |||||
| static HardwareSerial *s_serials_with_serial_events[7]; | |||||
| #endif | #endif | ||||
| static uint8_t s_count_serials_with_serial_events; | |||||
| void addToSerialEventsList(); | |||||
| inline void doYieldCode() { | |||||
| if (available()) (*hardware->_serialEvent)(); | |||||
| } | |||||
| /* Teensyduino Core Library | /* Teensyduino Core Library | ||||
| * http://www.pjrc.com/teensy/ | * http://www.pjrc.com/teensy/ | ||||
| * Copyright (c) 2019 PJRC.COM, LLC. | * Copyright (c) 2019 PJRC.COM, LLC. | ||||
| Serial1.IRQHandler(); | Serial1.IRQHandler(); | ||||
| } | } | ||||
| void serial_event_check_serial1() | |||||
| { | |||||
| if (Serial1.available()) serialEvent1(); | |||||
| } | |||||
| // Serial1 | // Serial1 | ||||
| static BUFTYPE tx_buffer1[SERIAL1_TX_BUFFER_SIZE]; | static BUFTYPE tx_buffer1[SERIAL1_TX_BUFFER_SIZE]; | ||||
| static BUFTYPE rx_buffer1[SERIAL1_RX_BUFFER_SIZE]; | static BUFTYPE rx_buffer1[SERIAL1_RX_BUFFER_SIZE]; | ||||
| uint8_t _serialEvent1_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| const HardwareSerial::hardware_t UART6_Hardware = { | const HardwareSerial::hardware_t UART6_Hardware = { | ||||
| 0, IRQ_LPUART6, &IRQHandler_Serial1, &serial_event_check_serial1, | |||||
| 0, IRQ_LPUART6, &IRQHandler_Serial1, | |||||
| &serialEvent1, &_serialEvent1_default, | |||||
| CCM_CCGR3, CCM_CCGR3_LPUART6(CCM_CCGR_ON), | CCM_CCGR3, CCM_CCGR3_LPUART6(CCM_CCGR_ON), | ||||
| #if defined(ARDUINO_TEENSY41) | #if defined(ARDUINO_TEENSY41) | ||||
| {{0,2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 1}, {52, 2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 0}}, | {{0,2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 1}, {52, 2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 0}}, | ||||
| 0xff, // No CTS pin | 0xff, // No CTS pin | ||||
| 0, // No CTS | 0, // No CTS | ||||
| IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | ||||
| XBARA1_OUT_LPUART6_TRG_INPUT // XBar Tigger | |||||
| }; | }; | ||||
| HardwareSerial Serial1(&IMXRT_LPUART6, &UART6_Hardware, tx_buffer1, SERIAL1_TX_BUFFER_SIZE, | HardwareSerial Serial1(&IMXRT_LPUART6, &UART6_Hardware, tx_buffer1, SERIAL1_TX_BUFFER_SIZE, | ||||
| rx_buffer1, SERIAL1_RX_BUFFER_SIZE); | rx_buffer1, SERIAL1_RX_BUFFER_SIZE); | ||||
| void serialEvent1() __attribute__((weak)); | |||||
| void serialEvent1() {Serial1.disableSerialEvents(); } // No use calling this so disable if called... | |||||
| //void serialEvent1() __attribute__((weak)); | |||||
| //void serialEvent1() {Serial1.disableSerialEvents(); } // No use calling this so disable if called... | |||||
| // C wrapper functions to help take care of places that used to call these from standard C | // C wrapper functions to help take care of places that used to call these from standard C | ||||
| void serial_print(const char *p) | void serial_print(const char *p) |
| Serial2.IRQHandler(); | Serial2.IRQHandler(); | ||||
| } | } | ||||
| void serial_event_check_serial2() | |||||
| { | |||||
| if (Serial2.available()) serialEvent2(); | |||||
| } | |||||
| // Serial2 | // Serial2 | ||||
| static BUFTYPE tx_buffer2[SERIAL2_TX_BUFFER_SIZE]; | static BUFTYPE tx_buffer2[SERIAL2_TX_BUFFER_SIZE]; | ||||
| static BUFTYPE rx_buffer2[SERIAL2_RX_BUFFER_SIZE]; | static BUFTYPE rx_buffer2[SERIAL2_RX_BUFFER_SIZE]; | ||||
| uint8_t _serialEvent2_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| static HardwareSerial::hardware_t UART4_Hardware = { | static HardwareSerial::hardware_t UART4_Hardware = { | ||||
| 1, IRQ_LPUART4, &IRQHandler_Serial2, &serial_event_check_serial2, | |||||
| 1, IRQ_LPUART4, &IRQHandler_Serial2, | |||||
| &serialEvent2, &_serialEvent2_default, | |||||
| CCM_CCGR1, CCM_CCGR1_LPUART4(CCM_CCGR_ON), | CCM_CCGR1, CCM_CCGR1_LPUART4(CCM_CCGR_ON), | ||||
| #if defined(__IMXRT1052__) | #if defined(__IMXRT1052__) | ||||
| {{6,2, &IOMUXC_LPUART4_RX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}}, | {{6,2, &IOMUXC_LPUART4_RX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}}, | ||||
| 0xff, // No CTS pin | 0xff, // No CTS pin | ||||
| 0, // No CTS | 0, // No CTS | ||||
| IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | ||||
| XBARA1_OUT_LPUART4_TRG_INPUT | |||||
| }; | }; | ||||
| HardwareSerial Serial2(&IMXRT_LPUART4, &UART4_Hardware, tx_buffer2, SERIAL2_TX_BUFFER_SIZE, | HardwareSerial Serial2(&IMXRT_LPUART4, &UART4_Hardware, tx_buffer2, SERIAL2_TX_BUFFER_SIZE, | ||||
| rx_buffer2, SERIAL2_RX_BUFFER_SIZE); | rx_buffer2, SERIAL2_RX_BUFFER_SIZE); | ||||
| void serialEvent2() __attribute__((weak)); | |||||
| void serialEvent2() {Serial2.disableSerialEvents(); } // No use calling this so disable if called... |
| Serial3.IRQHandler(); | Serial3.IRQHandler(); | ||||
| } | } | ||||
| void serial_event_check_serial3() | |||||
| { | |||||
| if (Serial3.available()) serialEvent3(); | |||||
| } | |||||
| // Serial3 | // Serial3 | ||||
| static BUFTYPE tx_buffer3[SERIAL3_TX_BUFFER_SIZE]; | static BUFTYPE tx_buffer3[SERIAL3_TX_BUFFER_SIZE]; | ||||
| static BUFTYPE rx_buffer3[SERIAL3_RX_BUFFER_SIZE]; | static BUFTYPE rx_buffer3[SERIAL3_RX_BUFFER_SIZE]; | ||||
| uint8_t _serialEvent3_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| static HardwareSerial::hardware_t UART2_Hardware = { | static HardwareSerial::hardware_t UART2_Hardware = { | ||||
| 2, IRQ_LPUART2, &IRQHandler_Serial3, &serial_event_check_serial3, | |||||
| CCM_CCGR0, CCM_CCGR0_LPUART2(CCM_CCGR_ON), | |||||
| 2, IRQ_LPUART2, &IRQHandler_Serial3, | |||||
| &serialEvent3, &_serialEvent3_default, | |||||
| CCM_CCGR0, CCM_CCGR0_LPUART2(CCM_CCGR_ON), | |||||
| {{15,2, &IOMUXC_LPUART2_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, | {{15,2, &IOMUXC_LPUART2_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, | ||||
| {{14,2, &IOMUXC_LPUART2_TX_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 | 19, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_00, // 19 | ||||
| 2, // page 473 | 2, // page 473 | ||||
| IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | ||||
| XBARA1_OUT_LPUART2_TRG_INPUT | |||||
| }; | }; | ||||
| HardwareSerial Serial3(&IMXRT_LPUART2, &UART2_Hardware,tx_buffer3, SERIAL3_TX_BUFFER_SIZE, | HardwareSerial Serial3(&IMXRT_LPUART2, &UART2_Hardware,tx_buffer3, SERIAL3_TX_BUFFER_SIZE, | ||||
| rx_buffer3, SERIAL3_RX_BUFFER_SIZE); | rx_buffer3, SERIAL3_RX_BUFFER_SIZE); | ||||
| void serialEvent3() __attribute__((weak)); | |||||
| void serialEvent3() {Serial3.disableSerialEvents(); } // No use calling this so disable if called... | |||||
| Serial4.IRQHandler(); | Serial4.IRQHandler(); | ||||
| } | } | ||||
| void serial_event_check_serial4() | |||||
| { | |||||
| if (Serial4.available()) serialEvent4(); | |||||
| } | |||||
| // Serial4 | // Serial4 | ||||
| static BUFTYPE tx_buffer4[SERIAL4_TX_BUFFER_SIZE]; | static BUFTYPE tx_buffer4[SERIAL4_TX_BUFFER_SIZE]; | ||||
| static BUFTYPE rx_buffer4[SERIAL4_RX_BUFFER_SIZE]; | static BUFTYPE rx_buffer4[SERIAL4_RX_BUFFER_SIZE]; | ||||
| uint8_t _serialEvent4_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| static HardwareSerial::hardware_t UART3_Hardware = { | static HardwareSerial::hardware_t UART3_Hardware = { | ||||
| 3, IRQ_LPUART3, &IRQHandler_Serial4, &serial_event_check_serial4, | |||||
| 3, IRQ_LPUART3, &IRQHandler_Serial4, | |||||
| &serialEvent4, &_serialEvent4_default, | |||||
| CCM_CCGR0, CCM_CCGR0_LPUART3(CCM_CCGR_ON), | CCM_CCGR0, CCM_CCGR0_LPUART3(CCM_CCGR_ON), | ||||
| {{16,2, &IOMUXC_LPUART3_RX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}}, | {{16,2, &IOMUXC_LPUART3_RX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}}, | ||||
| {{17,2, &IOMUXC_LPUART3_TX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}}, | {{17,2, &IOMUXC_LPUART3_TX_SELECT_INPUT, 0}, {0xff, 0xff, nullptr, 0}}, | ||||
| 0xff, // No CTS pin | 0xff, // No CTS pin | ||||
| 0, // No CTS | 0, // No CTS | ||||
| IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | ||||
| XBARA1_OUT_LPUART3_TRG_INPUT | |||||
| }; | }; | ||||
| HardwareSerial Serial4(&IMXRT_LPUART3, &UART3_Hardware, tx_buffer4, SERIAL4_TX_BUFFER_SIZE, | HardwareSerial Serial4(&IMXRT_LPUART3, &UART3_Hardware, tx_buffer4, SERIAL4_TX_BUFFER_SIZE, | ||||
| rx_buffer4, SERIAL4_RX_BUFFER_SIZE); | rx_buffer4, SERIAL4_RX_BUFFER_SIZE); | ||||
| void serialEvent4() __attribute__((weak)); | |||||
| void serialEvent4() {Serial4.disableSerialEvents(); } // No use calling this so disable if called... |
| { | { | ||||
| Serial5.IRQHandler(); | Serial5.IRQHandler(); | ||||
| } | } | ||||
| void serial_event_check_serial5() | |||||
| { | |||||
| if (Serial5.available()) serialEvent5(); | |||||
| } | |||||
| // Serial5 | // Serial5 | ||||
| static BUFTYPE tx_buffer5[SERIAL5_TX_BUFFER_SIZE]; | static BUFTYPE tx_buffer5[SERIAL5_TX_BUFFER_SIZE]; | ||||
| static BUFTYPE rx_buffer5[SERIAL5_RX_BUFFER_SIZE]; | static BUFTYPE rx_buffer5[SERIAL5_RX_BUFFER_SIZE]; | ||||
| uint8_t _serialEvent5_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| static HardwareSerial::hardware_t UART8_Hardware = { | static HardwareSerial::hardware_t UART8_Hardware = { | ||||
| 4, IRQ_LPUART8, &IRQHandler_Serial5, &serial_event_check_serial5, | |||||
| 4, IRQ_LPUART8, &IRQHandler_Serial5, | |||||
| &serialEvent5, &_serialEvent5_default, | |||||
| CCM_CCGR6, CCM_CCGR6_LPUART8(CCM_CCGR_ON), | CCM_CCGR6, CCM_CCGR6_LPUART8(CCM_CCGR_ON), | ||||
| #if defined(ARDUINO_TEENSY41) | #if defined(ARDUINO_TEENSY41) | ||||
| {{21,2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 1}, {46, 2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 0}}, | {{21,2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 1}, {46, 2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 0}}, | ||||
| 2, // CTS | 2, // CTS | ||||
| #endif | #endif | ||||
| IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | ||||
| XBARA1_OUT_LPUART8_TRG_INPUT | |||||
| }; | }; | ||||
| HardwareSerial Serial5(&IMXRT_LPUART8, &UART8_Hardware, tx_buffer5, SERIAL5_TX_BUFFER_SIZE, | HardwareSerial Serial5(&IMXRT_LPUART8, &UART8_Hardware, tx_buffer5, SERIAL5_TX_BUFFER_SIZE, | ||||
| rx_buffer5, SERIAL5_RX_BUFFER_SIZE); | rx_buffer5, SERIAL5_RX_BUFFER_SIZE); | ||||
| void serialEvent5() __attribute__((weak)); | |||||
| void serialEvent5() {Serial5.disableSerialEvents(); } // No use calling this so disable if called... |
| Serial6.IRQHandler(); | Serial6.IRQHandler(); | ||||
| } | } | ||||
| void serial_event_check_serial6() | |||||
| { | |||||
| if (Serial6.available()) serialEvent6(); | |||||
| } | |||||
| // Serial6 | // Serial6 | ||||
| static BUFTYPE tx_buffer6[SERIAL6_TX_BUFFER_SIZE]; | static BUFTYPE tx_buffer6[SERIAL6_TX_BUFFER_SIZE]; | ||||
| static BUFTYPE rx_buffer6[SERIAL6_RX_BUFFER_SIZE]; | static BUFTYPE rx_buffer6[SERIAL6_RX_BUFFER_SIZE]; | ||||
| uint8_t _serialEvent6_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| static HardwareSerial::hardware_t UART1_Hardware = { | static HardwareSerial::hardware_t UART1_Hardware = { | ||||
| 5, IRQ_LPUART1, &IRQHandler_Serial6, &serial_event_check_serial6, | |||||
| 5, IRQ_LPUART1, &IRQHandler_Serial6, | |||||
| &serialEvent6, &_serialEvent6_default, | |||||
| CCM_CCGR5, CCM_CCGR5_LPUART1(CCM_CCGR_ON), | CCM_CCGR5, CCM_CCGR5_LPUART1(CCM_CCGR_ON), | ||||
| {{25,2, nullptr, 0}, {0xff, 0xff, nullptr, 0}}, | {{25,2, nullptr, 0}, {0xff, 0xff, nullptr, 0}}, | ||||
| {{24,2, nullptr, 0}, {0xff, 0xff, nullptr, 0}}, | {{24,2, nullptr, 0}, {0xff, 0xff, nullptr, 0}}, | ||||
| 0xff, // No CTS pin | 0xff, // No CTS pin | ||||
| 0, // No CTS | 0, // No CTS | ||||
| IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | ||||
| XBARA1_OUT_LPUART1_TRG_INPUT | |||||
| }; | }; | ||||
| HardwareSerial Serial6(&IMXRT_LPUART1, &UART1_Hardware, tx_buffer6, SERIAL6_TX_BUFFER_SIZE, | HardwareSerial Serial6(&IMXRT_LPUART1, &UART1_Hardware, tx_buffer6, SERIAL6_TX_BUFFER_SIZE, | ||||
| rx_buffer6, SERIAL6_RX_BUFFER_SIZE); | rx_buffer6, SERIAL6_RX_BUFFER_SIZE); | ||||
| void serialEvent6() __attribute__((weak)); | |||||
| void serialEvent6() {Serial6.disableSerialEvents(); } // No use calling this so disable if called... |
| Serial7.IRQHandler(); | Serial7.IRQHandler(); | ||||
| } | } | ||||
| void serial_event_check_serial7() | |||||
| { | |||||
| if (Serial7.available()) serialEvent7(); | |||||
| } | |||||
| // Serial7 | // Serial7 | ||||
| static BUFTYPE tx_buffer7[SERIAL7_TX_BUFFER_SIZE]; | static BUFTYPE tx_buffer7[SERIAL7_TX_BUFFER_SIZE]; | ||||
| static BUFTYPE rx_buffer7[SERIAL7_RX_BUFFER_SIZE]; | static BUFTYPE rx_buffer7[SERIAL7_RX_BUFFER_SIZE]; | ||||
| uint8_t _serialEvent7_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| static HardwareSerial::hardware_t UART7_Hardware = { | static HardwareSerial::hardware_t UART7_Hardware = { | ||||
| 6, IRQ_LPUART7, &IRQHandler_Serial7, &serial_event_check_serial7, | |||||
| 6, IRQ_LPUART7, &IRQHandler_Serial7, | |||||
| &serialEvent7, &_serialEvent7_default, | |||||
| CCM_CCGR5, CCM_CCGR5_LPUART7(CCM_CCGR_ON), | CCM_CCGR5, CCM_CCGR5_LPUART7(CCM_CCGR_ON), | ||||
| {{28,2, &IOMUXC_LPUART7_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, | {{28,2, &IOMUXC_LPUART7_RX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, | ||||
| {{29,2, &IOMUXC_LPUART7_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, | {{29,2, &IOMUXC_LPUART7_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, | ||||
| 0xff, // No CTS pin | 0xff, // No CTS pin | ||||
| 0, // No CTS | 0, // No CTS | ||||
| IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | ||||
| XBARA1_OUT_LPUART7_TRG_INPUT | |||||
| }; | }; | ||||
| HardwareSerial Serial7(&IMXRT_LPUART7, &UART7_Hardware, tx_buffer7, SERIAL7_TX_BUFFER_SIZE, | HardwareSerial Serial7(&IMXRT_LPUART7, &UART7_Hardware, tx_buffer7, SERIAL7_TX_BUFFER_SIZE, | ||||
| rx_buffer7, SERIAL7_RX_BUFFER_SIZE); | rx_buffer7, SERIAL7_RX_BUFFER_SIZE); | ||||
| void serialEvent7() __attribute__((weak)); | |||||
| void serialEvent7() {Serial7.disableSerialEvents(); } // No use calling this so disable if called... |
| Serial8.IRQHandler(); | Serial8.IRQHandler(); | ||||
| } | } | ||||
| void serial_event_check_serial8() | |||||
| { | |||||
| if (Serial8.available()) serialEvent8(); | |||||
| } | |||||
| // Serial8 | // Serial8 | ||||
| static BUFTYPE tx_buffer8[SERIAL8_TX_BUFFER_SIZE]; | static BUFTYPE tx_buffer8[SERIAL8_TX_BUFFER_SIZE]; | ||||
| static BUFTYPE rx_buffer8[SERIAL8_RX_BUFFER_SIZE]; | static BUFTYPE rx_buffer8[SERIAL8_RX_BUFFER_SIZE]; | ||||
| uint8_t _serialEvent8_default __attribute__((weak)) PROGMEM = 0 ; | |||||
| static HardwareSerial::hardware_t UART5_Hardware = { | static HardwareSerial::hardware_t UART5_Hardware = { | ||||
| 7, IRQ_LPUART5, &IRQHandler_Serial8, &serial_event_check_serial8, | |||||
| 7, IRQ_LPUART5, &IRQHandler_Serial8, | |||||
| &serialEvent8, &_serialEvent8_default, | |||||
| CCM_CCGR3, CCM_CCGR3_LPUART5(CCM_CCGR_ON), | CCM_CCGR3, CCM_CCGR3_LPUART5(CCM_CCGR_ON), | ||||
| {{34,1, &IOMUXC_LPUART5_RX_SELECT_INPUT, 1}, {48, 2, &IOMUXC_LPUART5_RX_SELECT_INPUT, 0}}, | {{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}}, | {{35,1, &IOMUXC_LPUART5_TX_SELECT_INPUT, 1}, {0xff, 0xff, nullptr, 0}}, | ||||
| 50, // CTS pin | 50, // CTS pin | ||||
| 2, // CTS | 2, // CTS | ||||
| IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | IRQ_PRIORITY, 38, 24, // IRQ, rts_low_watermark, rts_high_watermark | ||||
| XBARA1_OUT_LPUART5_TRG_INPUT | |||||
| }; | }; | ||||
| HardwareSerial Serial8(&IMXRT_LPUART5, &UART5_Hardware, tx_buffer8, SERIAL8_TX_BUFFER_SIZE, | HardwareSerial Serial8(&IMXRT_LPUART5, &UART5_Hardware, tx_buffer8, SERIAL8_TX_BUFFER_SIZE, | ||||
| rx_buffer8, SERIAL8_RX_BUFFER_SIZE); | rx_buffer8, SERIAL8_RX_BUFFER_SIZE); | ||||
| void serialEvent8() __attribute__((weak)); | |||||
| void serialEvent8() {Serial8.disableSerialEvents(); } // No use calling this so disable if called... | |||||
| #endif | #endif |
| void _reboot_Teensyduino_(void) __attribute__((noreturn)); | void _reboot_Teensyduino_(void) __attribute__((noreturn)); | ||||
| void _restart_Teensyduino_(void) __attribute__((noreturn)); | void _restart_Teensyduino_(void) __attribute__((noreturn)); | ||||
| // Define a set of flags to know which things yield should check when called. | |||||
| extern uint8_t yield_active_check_flags; | |||||
| #define YIELD_CHECK_USB_SERIAL 0x1 // check the USB for Serial.available() | |||||
| #define YIELD_CHECK_HARDWARE_SERIAL 0x2 // check Hardware Serial ports available | |||||
| #define YIELD_CHECK_EVENT_RESPONDER 0x4 // User has created eventResponders that use yield | |||||
| void yield(void); | void yield(void); | ||||
| void delay(uint32_t msec); | void delay(uint32_t msec); |
| #include <Arduino.h> | |||||
| void serialEvent() __attribute__((weak)); | |||||
| void serialEvent() { | |||||
| } | |||||
| uint8_t _serialEvent_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent1() __attribute__((weak)); | |||||
| void serialEvent1() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent1_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent2() __attribute__((weak)); | |||||
| void serialEvent2() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent2_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent3() __attribute__((weak)); | |||||
| void serialEvent3() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent3_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent4() __attribute__((weak)); | |||||
| void serialEvent4() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent4_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent5() __attribute__((weak)); | |||||
| void serialEvent5() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent5_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent6() __attribute__((weak)); | |||||
| void serialEvent6() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent6_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent7() __attribute__((weak)); | |||||
| void serialEvent7() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent7_default PROGMEM = 1; |
| #include <Arduino.h> | |||||
| #include "HardwareSerial.h" | |||||
| void serialEvent8() __attribute__((weak)); | |||||
| void serialEvent8() {} // No use calling this so disable if called... | |||||
| uint8_t _serialEvent8_default PROGMEM = 1; |
| #endif | #endif | ||||
| #endif // F_CPU | #endif // F_CPU | ||||
| uint8_t usb_enable_serial_event_processing = 1; | |||||
| void serialEvent() __attribute__((weak)); | |||||
| void serialEvent() {usb_enable_serial_event_processing = 0;} | |||||
| #include <Arduino.h> | #include <Arduino.h> | ||||
| #include "EventResponder.h" | #include "EventResponder.h" | ||||
| extern uint8_t usb_enable_serial_event_processing; // from usb_inst.cpp | |||||
| uint8_t yield_active_check_flags = YIELD_CHECK_USB_SERIAL; // default to check USB. | |||||
| extern const uint8_t _serialEvent_default; | |||||
| void yield(void) __attribute__ ((weak)); | void yield(void) __attribute__ ((weak)); | ||||
| void yield(void) | void yield(void) | ||||
| { | { | ||||
| static uint8_t running=0; | static uint8_t running=0; | ||||
| if (!yield_active_check_flags) return; // nothing to do | |||||
| if (running) return; // TODO: does this need to be atomic? | if (running) return; // TODO: does this need to be atomic? | ||||
| running = 1; | running = 1; | ||||
| // USB Serail - Add hack to minimize impact... | // USB Serail - Add hack to minimize impact... | ||||
| if (usb_enable_serial_event_processing && Serial.available()) serialEvent(); | |||||
| if (yield_active_check_flags & YIELD_CHECK_USB_SERIAL) { | |||||
| if (Serial.available()) serialEvent(); | |||||
| if (_serialEvent_default) yield_active_check_flags &= ~YIELD_CHECK_USB_SERIAL; | |||||
| } | |||||
| // Current workaround until integrate with EventResponder. | // Current workaround until integrate with EventResponder. | ||||
| if (HardwareSerial::serial_event_handlers_active) HardwareSerial::processSerialEvents(); | |||||
| if (yield_active_check_flags & YIELD_CHECK_HARDWARE_SERIAL) HardwareSerial::processSerialEventsList(); | |||||
| running = 0; | running = 0; | ||||
| EventResponder::runFromYield(); | |||||
| if (yield_active_check_flags & YIELD_CHECK_EVENT_RESPONDER) EventResponder::runFromYield(); | |||||
| }; | }; |