Browse Source

Merge pull request #474 from KurtE/eventResponder_reduce_overhead

T4.x Reduce EventResponder overhead on systic and yield
teensy4-core
Paul Stoffregen 4 years ago
parent
commit
b1f56c7d54
No account linked to committer's email address
44 changed files with 482 additions and 181 deletions
  1. +11
    -0
      teensy3/EventResponder.cpp
  2. +5
    -0
      teensy3/EventResponder.h
  3. +45
    -0
      teensy3/HardwareSerial.cpp
  4. +33
    -13
      teensy3/HardwareSerial.h
  5. +9
    -3
      teensy3/HardwareSerial1.cpp
  6. +7
    -4
      teensy3/HardwareSerial2.cpp
  7. +7
    -3
      teensy3/HardwareSerial3.cpp
  8. +7
    -3
      teensy3/HardwareSerial4.cpp
  9. +7
    -3
      teensy3/HardwareSerial5.cpp
  10. +11
    -3
      teensy3/HardwareSerial6.cpp
  11. +8
    -0
      teensy3/core_pins.h
  12. +6
    -0
      teensy3/serialEvent.cpp
  13. +6
    -0
      teensy3/serialEvent1.cpp
  14. +6
    -0
      teensy3/serialEvent2.cpp
  15. +6
    -0
      teensy3/serialEvent3.cpp
  16. +8
    -0
      teensy3/serialEvent4.cpp
  17. +8
    -0
      teensy3/serialEvent5.cpp
  18. +8
    -0
      teensy3/serialEvent6.cpp
  19. +2
    -2
      teensy3/usb_inst.cpp
  20. +32
    -17
      teensy3/yield.cpp
  21. +8
    -1
      teensy4/EventResponder.cpp
  22. +5
    -2
      teensy4/EventResponder.h
  23. +99
    -32
      teensy4/HardwareSerial.cpp
  24. +32
    -7
      teensy4/HardwareSerial.h
  25. +7
    -7
      teensy4/HardwareSerial1.cpp
  26. +5
    -10
      teensy4/HardwareSerial2.cpp
  27. +5
    -10
      teensy4/HardwareSerial3.cpp
  28. +4
    -10
      teensy4/HardwareSerial4.cpp
  29. +4
    -12
      teensy4/HardwareSerial5.cpp
  30. +4
    -10
      teensy4/HardwareSerial6.cpp
  31. +4
    -11
      teensy4/HardwareSerial7.cpp
  32. +4
    -10
      teensy4/HardwareSerial8.cpp
  33. +5
    -0
      teensy4/core_pins.h
  34. +6
    -0
      teensy4/serialEvent.cpp
  35. +6
    -0
      teensy4/serialEvent1.cpp
  36. +6
    -0
      teensy4/serialEvent2.cpp
  37. +6
    -0
      teensy4/serialEvent3.cpp
  38. +6
    -0
      teensy4/serialEvent4.cpp
  39. +6
    -0
      teensy4/serialEvent5.cpp
  40. +6
    -0
      teensy4/serialEvent6.cpp
  41. +6
    -0
      teensy4/serialEvent7.cpp
  42. +6
    -0
      teensy4/serialEvent8.cpp
  43. +1
    -3
      teensy4/usb_inst.cpp
  44. +9
    -5
      teensy4/yield.cpp

+ 11
- 0
teensy3/EventResponder.cpp View File

@@ -41,6 +41,10 @@ EventResponder * EventResponder::lastInterrupt = nullptr;
bool EventResponder::runningFromYield = false;

// 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()
{
@@ -335,10 +339,17 @@ void MillisTimer::runFromTimer()
// with libraries using mid-to-high priority interrupts.

extern "C" volatile uint32_t systick_millis_count;

void systick_isr(void)
{
systick_millis_count++;
}

extern "C" void systick_isr_with_timer_events(void)
{
systick_millis_count++;
MillisTimer::runFromTimer();
}




+ 5
- 0
teensy3/EventResponder.h View File

@@ -59,6 +59,7 @@
* your function is called only one time, based on the last trigger
* event.
*/
extern "C" void systick_isr_with_timer_events(void);

class EventResponder;
typedef EventResponder& EventResponderRef;
@@ -87,6 +88,7 @@ public:
detachNoInterrupts();
_function = function;
_type = EventTypeYield;
yield_active_check_flags |= YIELD_CHECK_EVENT_RESPONDER; // user setup a yield type...
enableInterrupts(irq);
}

@@ -112,6 +114,8 @@ public:
_function = function;
_type = EventTypeInterrupt;
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);
}

@@ -170,6 +174,7 @@ public:
EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout);

static void runFromYield() {
if (!firstYield) return;
// First, check if yield was called from an interrupt
// never call normal handler functions from any interrupt context
uint32_t ipsr;

+ 45
- 0
teensy3/HardwareSerial.cpp View File

@@ -0,0 +1,45 @@
/* 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;
}


+ 33
- 13
teensy3/HardwareSerial.h View File

@@ -253,8 +253,13 @@ void serial6_clear(void);
class HardwareSerial : public Stream
{
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) {
serial_begin(BAUD2DIV(baud));
serial_format(format); }
@@ -283,6 +288,21 @@ public:
return len; }
virtual size_t write9bit(uint32_t c) { serial_putchar(c); return 1; }
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 void serialEvent1(void);
@@ -290,8 +310,8 @@ extern void serialEvent1(void);
class HardwareSerial2 : public HardwareSerial
{
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) {
serial2_begin(BAUD2DIV2(baud));
serial2_format(format); }
@@ -327,8 +347,8 @@ extern void serialEvent2(void);
class HardwareSerial3 : public HardwareSerial
{
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) {
serial3_begin(BAUD2DIV3(baud));
serial3_format(format); }
@@ -364,8 +384,8 @@ extern void serialEvent3(void);
class HardwareSerial4 : public HardwareSerial
{
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) {
serial4_begin(BAUD2DIV3(baud));
serial4_format(format); }
@@ -401,8 +421,8 @@ extern void serialEvent4(void);
class HardwareSerial5 : public HardwareSerial
{
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) {
serial5_begin(BAUD2DIV3(baud));
serial5_format(format); }
@@ -438,14 +458,14 @@ extern void serialEvent5(void);
class HardwareSerial6 : public HardwareSerial
{
public:
constexpr HardwareSerial6() {}
constexpr HardwareSerial6(void (* const se)()) : HardwareSerial(se) {}
#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) {
serial6_begin(baud);
serial6_format(format); }
#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) {
serial6_begin(BAUD2DIV3(baud));
serial6_format(format); }

+ 9
- 3
teensy3/HardwareSerial1.cpp View File

@@ -31,7 +31,13 @@
#include <Arduino.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();
}


+ 7
- 4
teensy3/HardwareSerial2.cpp View File

@@ -27,11 +27,14 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#include <Arduino.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();
}

+ 7
- 3
teensy3/HardwareSerial3.cpp View File

@@ -31,7 +31,11 @@
#include <Arduino.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();
}

+ 7
- 3
teensy3/HardwareSerial4.cpp View File

@@ -33,9 +33,13 @@

#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

+ 7
- 3
teensy3/HardwareSerial5.cpp View File

@@ -33,9 +33,13 @@

#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

+ 11
- 3
teensy3/HardwareSerial6.cpp View File

@@ -33,9 +33,17 @@

#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

+ 8
- 0
teensy3/core_pins.h View File

@@ -1996,6 +1996,14 @@ static inline uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrde
void _reboot_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 delay(uint32_t msec);

+ 6
- 0
teensy3/serialEvent.cpp View File

@@ -0,0 +1,6 @@

#include <Arduino.h>
void serialEvent() __attribute__((weak));
void serialEvent() {
}
uint8_t _serialEvent_default PROGMEM = 1;

+ 6
- 0
teensy3/serialEvent1.cpp View File

@@ -0,0 +1,6 @@

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

+ 6
- 0
teensy3/serialEvent2.cpp View File

@@ -0,0 +1,6 @@

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

+ 6
- 0
teensy3/serialEvent3.cpp View File

@@ -0,0 +1,6 @@

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

+ 8
- 0
teensy3/serialEvent4.cpp View File

@@ -0,0 +1,8 @@

#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

+ 8
- 0
teensy3/serialEvent5.cpp View File

@@ -0,0 +1,8 @@

#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

+ 8
- 0
teensy3/serialEvent6.cpp View File

@@ -0,0 +1,8 @@

#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

+ 2
- 2
teensy3/usb_inst.cpp View File

@@ -98,8 +98,8 @@ usb_seremu_class Serial;

#endif // F_CPU

void serialEvent() __attribute__((weak));
void serialEvent() {}
//void serialEvent() __attribute__((weak));
//void serialEvent() {}
void serialEventUSB1() __attribute__((weak));
void serialEventUSB1() {}
void serialEventUSB2() __attribute__((weak));

+ 32
- 17
teensy3/yield.cpp View File

@@ -31,32 +31,47 @@
#include <Arduino.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)
{
static uint8_t running=0;

if (!yield_active_check_flags) return; // nothing to do
if (running) return; // TODO: does this need to be atomic?
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 (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
#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
if (yield_active_check_flags & YIELD_CHECK_HARDWARE_SERIAL) {
HardwareSerial::processSerialEventsList();
}
running = 0;
EventResponder::runFromYield();
if (yield_active_check_flags & YIELD_CHECK_EVENT_RESPONDER) EventResponder::runFromYield();
};

+ 8
- 1
teensy4/EventResponder.cpp View File

@@ -41,6 +41,8 @@ EventResponder * EventResponder::lastInterrupt = nullptr;
bool EventResponder::runningFromYield = false;

// 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()
{
@@ -342,7 +344,12 @@ extern "C" void systick_isr(void)
{
systick_cycle_count = ARM_DWT_CYCCNT;
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();
}


+ 5
- 2
teensy4/EventResponder.h View File

@@ -59,6 +59,7 @@
* your function is called only one time, based on the last trigger
* event.
*/
extern "C" void systick_isr_with_timer_events(void);

class EventResponder;
typedef EventResponder& EventResponderRef;
@@ -87,6 +88,7 @@ public:
detachNoInterrupts();
_function = function;
_type = EventTypeYield;
yield_active_check_flags |= YIELD_CHECK_EVENT_RESPONDER; // user setup a yield type...
enableInterrupts(irq);
}

@@ -112,6 +114,8 @@ public:
_function = function;
_type = EventTypeInterrupt;
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);
}

@@ -168,9 +172,8 @@ public:
// used with a scheduler or RTOS.
bool waitForEvent(EventResponderRef event, int timeout);
EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout);

static void runFromYield() {
if (!firstYield) return;
if (!firstYield) return;
// First, check if yield was called from an interrupt
// never call normal handler functions from any interrupt context
uint32_t ipsr;

+ 99
- 32
teensy4/HardwareSerial.cpp View File

@@ -62,12 +62,19 @@

#define UART_CLOCK 24000000

extern "C" {
extern void xbar_connect(unsigned int input, unsigned int output);
}

#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
SerialEventCheckingFunctionPointer HardwareSerial::serial_event_handler_checks[7] = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
HardwareSerial *HardwareSerial::s_serials_with_serial_events[7];
#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)
@@ -193,7 +200,8 @@ void HardwareSerial::begin(uint32_t baud, uint16_t format)
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 );
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()
@@ -223,7 +231,6 @@ void HardwareSerial::end(void)
rx_buffer_tail_ = 0;
if (rts_pin_baseReg_) rts_deassert();
//
disableSerialEvents(); // disable the processing of serialEvent for this object
}

void HardwareSerial::transmitterEnable(uint8_t pin)
@@ -243,9 +250,9 @@ void HardwareSerial::setRX(uint8_t pin)
// 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.
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;;
*(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) {
@@ -253,7 +260,29 @@ void HardwareSerial::setRX(uint8_t pin)
}
}
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;
}
}
}
@@ -315,6 +344,30 @@ bool HardwareSerial::attachCts(uint8_t pin)
port->MODIR |= LPUART_MODIR_TXCTSE;
return true;
} 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;
return false;
}
@@ -551,30 +604,44 @@ void HardwareSerial::IRQHandler()
}


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]);


+ 32
- 7
teensy4/HardwareSerial.h View File

@@ -125,7 +125,22 @@ extern "C" {
#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
{
@@ -143,7 +158,8 @@ public:
uint8_t serial_index; // which object are we? 0 based
IRQ_NUMBER_t irq;
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;
const uint32_t ccm_value;
pin_info_t rx_pins[cnt_rx_pins];
@@ -153,6 +169,7 @@ public:
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 HardwareSerial(IMXRT_LPUART_t *myport, const hardware_t *myhardware,
@@ -183,9 +200,6 @@ public:
size_t write9bit(uint32_t c);
// Event Handler functions and data
void enableSerialEvents();
void disableSerialEvents();
static void processSerialEvents();
static uint8_t serial_event_handlers_active;

using Print::write;
@@ -204,6 +218,12 @@ public:
*/

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:
IMXRT_LPUART_t * const port;
const hardware_t * const hardware;
@@ -245,10 +265,15 @@ private:
friend void IRQHandler_Serial7();
#if defined(ARDUINO_TEENSY41)
friend void IRQHandler_Serial8();
static SerialEventCheckingFunctionPointer serial_event_handler_checks[8];
static HardwareSerial *s_serials_with_serial_events[8];
#else
static SerialEventCheckingFunctionPointer serial_event_handler_checks[7];
static HardwareSerial *s_serials_with_serial_events[7];
#endif
static uint8_t s_count_serials_with_serial_events;
void addToSerialEventsList();
inline void doYieldCode() {
if (available()) (*hardware->_serialEvent)();
}




+ 7
- 7
teensy4/HardwareSerial1.cpp View File

@@ -1,3 +1,4 @@

/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2019 PJRC.COM, LLC.
@@ -44,17 +45,15 @@ void IRQHandler_Serial1()
Serial1.IRQHandler();
}

void serial_event_check_serial1()
{
if (Serial1.available()) serialEvent1();
}

// Serial1
static BUFTYPE tx_buffer1[SERIAL1_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer1[SERIAL1_RX_BUFFER_SIZE];
uint8_t _serialEvent1_default __attribute__((weak)) PROGMEM = 0 ;

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),
#if defined(ARDUINO_TEENSY41)
{{0,2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 1}, {52, 2, &IOMUXC_LPUART6_RX_SELECT_INPUT, 0}},
@@ -66,12 +65,13 @@ const HardwareSerial::hardware_t UART6_Hardware = {
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
};
HardwareSerial Serial1(&IMXRT_LPUART6, &UART6_Hardware, tx_buffer1, SERIAL1_TX_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
void serial_print(const char *p)

+ 5
- 10
teensy4/HardwareSerial2.cpp View File

@@ -45,18 +45,16 @@ void IRQHandler_Serial2()
Serial2.IRQHandler();
}

void serial_event_check_serial2()
{
if (Serial2.available()) serialEvent2();
}


// Serial2
static BUFTYPE tx_buffer2[SERIAL2_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer2[SERIAL2_RX_BUFFER_SIZE];

uint8_t _serialEvent2_default __attribute__((weak)) PROGMEM = 0 ;

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),
#if defined(__IMXRT1052__)
{{6,2, &IOMUXC_LPUART4_RX_SELECT_INPUT, 2}, {0xff, 0xff, nullptr, 0}},
@@ -68,10 +66,7 @@ static HardwareSerial::hardware_t UART4_Hardware = {
0xff, // No CTS pin
0, // No CTS
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,
rx_buffer2, SERIAL2_RX_BUFFER_SIZE);


void serialEvent2() __attribute__((weak));
void serialEvent2() {Serial2.disableSerialEvents(); } // No use calling this so disable if called...

+ 5
- 10
teensy4/HardwareSerial3.cpp View File

@@ -44,27 +44,22 @@ void IRQHandler_Serial3()
Serial3.IRQHandler();
}

void serial_event_check_serial3()
{
if (Serial3.available()) serialEvent3();
}

// Serial3
static BUFTYPE tx_buffer3[SERIAL3_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer3[SERIAL3_RX_BUFFER_SIZE];
uint8_t _serialEvent3_default __attribute__((weak)) PROGMEM = 0 ;

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}},
{{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
};
HardwareSerial Serial3(&IMXRT_LPUART2, &UART2_Hardware,tx_buffer3, SERIAL3_TX_BUFFER_SIZE,
rx_buffer3, SERIAL3_RX_BUFFER_SIZE);

void serialEvent3() __attribute__((weak));
void serialEvent3() {Serial3.disableSerialEvents(); } // No use calling this so disable if called...


+ 4
- 10
teensy4/HardwareSerial4.cpp View File

@@ -45,27 +45,21 @@ void IRQHandler_Serial4()
Serial4.IRQHandler();
}

void serial_event_check_serial4()
{
if (Serial4.available()) serialEvent4();
}

// Serial4
static BUFTYPE tx_buffer4[SERIAL4_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer4[SERIAL4_RX_BUFFER_SIZE];
uint8_t _serialEvent4_default __attribute__((weak)) PROGMEM = 0 ;

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),
{{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
};
HardwareSerial Serial4(&IMXRT_LPUART3, &UART3_Hardware, tx_buffer4, SERIAL4_TX_BUFFER_SIZE,
rx_buffer4, SERIAL4_RX_BUFFER_SIZE);


void serialEvent4() __attribute__((weak));
void serialEvent4() {Serial4.disableSerialEvents(); } // No use calling this so disable if called...

+ 4
- 12
teensy4/HardwareSerial5.cpp View File

@@ -44,18 +44,14 @@ void IRQHandler_Serial5()
{
Serial5.IRQHandler();
}

void serial_event_check_serial5()
{
if (Serial5.available()) serialEvent5();
}

// Serial5
static BUFTYPE tx_buffer5[SERIAL5_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer5[SERIAL5_RX_BUFFER_SIZE];
uint8_t _serialEvent5_default __attribute__((weak)) PROGMEM = 0 ;

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),
#if defined(ARDUINO_TEENSY41)
{{21,2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 1}, {46, 2, &IOMUXC_LPUART8_RX_SELECT_INPUT, 0}},
@@ -69,11 +65,7 @@ static HardwareSerial::hardware_t UART8_Hardware = {
2, // CTS
#endif
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,
rx_buffer5, SERIAL5_RX_BUFFER_SIZE);



void serialEvent5() __attribute__((weak));
void serialEvent5() {Serial5.disableSerialEvents(); } // No use calling this so disable if called...

+ 4
- 10
teensy4/HardwareSerial6.cpp View File

@@ -44,29 +44,23 @@ void IRQHandler_Serial6()
Serial6.IRQHandler();
}

void serial_event_check_serial6()
{
if (Serial6.available()) serialEvent6();
}


// Serial6
static BUFTYPE tx_buffer6[SERIAL6_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer6[SERIAL6_RX_BUFFER_SIZE];
uint8_t _serialEvent6_default __attribute__((weak)) PROGMEM = 0 ;

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),
{{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
};

HardwareSerial Serial6(&IMXRT_LPUART1, &UART1_Hardware, tx_buffer6, SERIAL6_TX_BUFFER_SIZE,
rx_buffer6, SERIAL6_RX_BUFFER_SIZE);

void serialEvent6() __attribute__((weak));
void serialEvent6() {Serial6.disableSerialEvents(); } // No use calling this so disable if called...

+ 4
- 11
teensy4/HardwareSerial7.cpp View File

@@ -44,28 +44,21 @@ void IRQHandler_Serial7()
Serial7.IRQHandler();
}

void serial_event_check_serial7()
{
if (Serial7.available()) serialEvent7();
}


// Serial7
static BUFTYPE tx_buffer7[SERIAL7_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer7[SERIAL7_RX_BUFFER_SIZE];
uint8_t _serialEvent7_default __attribute__((weak)) PROGMEM = 0 ;

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),
{{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
};
HardwareSerial Serial7(&IMXRT_LPUART7, &UART7_Hardware, tx_buffer7, SERIAL7_TX_BUFFER_SIZE,
rx_buffer7, SERIAL7_RX_BUFFER_SIZE);


void serialEvent7() __attribute__((weak));
void serialEvent7() {Serial7.disableSerialEvents(); } // No use calling this so disable if called...

+ 4
- 10
teensy4/HardwareSerial8.cpp View File

@@ -45,19 +45,15 @@ void IRQHandler_Serial8()
Serial8.IRQHandler();
}

void serial_event_check_serial8()
{
if (Serial8.available()) serialEvent8();
}



// Serial8
static BUFTYPE tx_buffer8[SERIAL8_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer8[SERIAL8_RX_BUFFER_SIZE];
uint8_t _serialEvent8_default __attribute__((weak)) PROGMEM = 0 ;

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),
{{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}},
@@ -65,10 +61,8 @@ static HardwareSerial::hardware_t UART5_Hardware = {
50, // CTS pin
2, // CTS
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,
rx_buffer8, SERIAL8_RX_BUFFER_SIZE);

void serialEvent8() __attribute__((weak));
void serialEvent8() {Serial8.disableSerialEvents(); } // No use calling this so disable if called...
#endif

+ 5
- 0
teensy4/core_pins.h View File

@@ -1546,6 +1546,11 @@ static inline uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrde
void _reboot_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 delay(uint32_t msec);

+ 6
- 0
teensy4/serialEvent.cpp View File

@@ -0,0 +1,6 @@

#include <Arduino.h>
void serialEvent() __attribute__((weak));
void serialEvent() {
}
uint8_t _serialEvent_default PROGMEM = 1;

+ 6
- 0
teensy4/serialEvent1.cpp View File

@@ -0,0 +1,6 @@

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

+ 6
- 0
teensy4/serialEvent2.cpp View File

@@ -0,0 +1,6 @@

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

+ 6
- 0
teensy4/serialEvent3.cpp View File

@@ -0,0 +1,6 @@

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

+ 6
- 0
teensy4/serialEvent4.cpp View File

@@ -0,0 +1,6 @@

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

+ 6
- 0
teensy4/serialEvent5.cpp View File

@@ -0,0 +1,6 @@

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

+ 6
- 0
teensy4/serialEvent6.cpp View File

@@ -0,0 +1,6 @@

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

+ 6
- 0
teensy4/serialEvent7.cpp View File

@@ -0,0 +1,6 @@

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

+ 6
- 0
teensy4/serialEvent8.cpp View File

@@ -0,0 +1,6 @@

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

+ 1
- 3
teensy4/usb_inst.cpp View File

@@ -96,6 +96,4 @@ usb_seremu_class Serial;
#endif

#endif // F_CPU
uint8_t usb_enable_serial_event_processing = 1;
void serialEvent() __attribute__((weak));
void serialEvent() {usb_enable_serial_event_processing = 0;}


+ 9
- 5
teensy4/yield.cpp View File

@@ -31,24 +31,28 @@
#include <Arduino.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)
{
static uint8_t running=0;
if (!yield_active_check_flags) return; // nothing to do
if (running) return; // TODO: does this need to be atomic?
running = 1;


// 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.
if (HardwareSerial::serial_event_handlers_active) HardwareSerial::processSerialEvents();
if (yield_active_check_flags & YIELD_CHECK_HARDWARE_SERIAL) HardwareSerial::processSerialEventsList();

running = 0;
EventResponder::runFromYield();
if (yield_active_check_flags & YIELD_CHECK_EVENT_RESPONDER) EventResponder::runFromYield();
};

Loading…
Cancel
Save