Teensy 4.1 core updated for C++20
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
4.0KB

  1. /* EventResponder - Simple event-based programming for Arduino
  2. * Copyright 2017 Paul Stoffregen
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining
  5. * a copy of this software and associated documentation files (the
  6. * "Software"), to deal in the Software without restriction, including
  7. * without limitation the rights to use, copy, modify, merge, publish,
  8. * distribute, sublicense, and/or sell copies of the Software, and to
  9. * permit persons to whom the Software is furnished to do so, subject to
  10. * the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be
  13. * included in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  16. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  18. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  19. * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  20. * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. * SOFTWARE.
  23. */
  24. /* EventResponder is an experimental API, almost certain to
  25. * incompatibly change as it develops. Please understand any
  26. * programs you write now using EventResponder may need to be
  27. * updated as EventResponder develops.
  28. *
  29. * Please post EventResponder post your feedback here:
  30. * https://forum.pjrc.com/threads/44723-Arduino-Events
  31. */
  32. #if !defined(EventResponder_h) && defined(__cplusplus)
  33. #define EventResponder_h
  34. #include <Arduino.h>
  35. class EventResponder;
  36. typedef EventResponder& EventResponderRef;
  37. typedef void (*EventResponderFunction)(EventResponderRef);
  38. class EventResponder
  39. {
  40. public:
  41. constexpr EventResponder() {
  42. }
  43. ~EventResponder() {
  44. detach();
  45. }
  46. enum EventType {
  47. EventTypeDetached = 0, // no function is called
  48. EventTypeYield, // function is called from yield()
  49. EventTypeImmediate, // function is called immediately
  50. EventTypeInterrupt, // function is called from interrupt
  51. EventTypeThread // function is run as a new thread
  52. };
  53. void attach(EventResponderFunction function) {
  54. detach();
  55. _function = function;
  56. _type = EventTypeYield;
  57. }
  58. void attachImmediate(EventResponderFunction function) {
  59. detach();
  60. _function = function;
  61. _type = EventTypeImmediate;
  62. }
  63. void attachInterrupt(EventResponderFunction function) {
  64. detach();
  65. _function = function;
  66. _type = EventTypeInterrupt;
  67. // TODO: configure PendSV
  68. }
  69. void attachThread(EventResponderFunction function, void *param=nullptr) {
  70. attach(function); // for non-RTOS usage, compile as default attach
  71. }
  72. void detach();
  73. virtual void triggerEvent(int status=0, void *data=nullptr) {
  74. _status = status;
  75. _data = data;
  76. if (_type == EventTypeImmediate) {
  77. (*_function)(*this);
  78. } else {
  79. triggerEventNotImmediate();
  80. }
  81. }
  82. bool clearEvent();
  83. int getStatus() { return _status; }
  84. void setContext(void *context) { _context = context; }
  85. void * getContext() { return _context; }
  86. void * getData() { return _data; }
  87. bool waitForEvent(EventResponderRef event, int timeout);
  88. EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout);
  89. static void runFromYield() {
  90. EventResponder *first = firstYield;
  91. if (first && !runningFromYield) {
  92. runningFromYield = true;
  93. firstYield = first->_next;
  94. if (firstYield) firstYield->_prev = nullptr;
  95. first->_pending = false;
  96. (*(first->_function))(*first);
  97. runningFromYield = false;
  98. }
  99. }
  100. static void runFromInterrupt();
  101. operator bool() { return _pending; }
  102. protected:
  103. void triggerEventNotImmediate();
  104. int _status = 0;
  105. EventResponderFunction _function = nullptr;
  106. void *_data = nullptr;
  107. void *_context = nullptr;
  108. EventResponder *_next = nullptr;
  109. EventResponder *_prev = nullptr;
  110. EventType _type = EventTypeDetached;
  111. bool _pending = false;
  112. static EventResponder *firstYield;
  113. static EventResponder *lastYield;
  114. static EventResponder *firstInterrupt;
  115. static EventResponder *lastInterrupt;
  116. static bool runningFromYield;
  117. };
  118. #endif