|
-
-
-
-
- #include "EventResponder.h"
-
- EventResponder * EventResponder::firstYield = nullptr;
- EventResponder * EventResponder::lastYield = nullptr;
- EventResponder * EventResponder::firstInterrupt = nullptr;
- EventResponder * EventResponder::lastInterrupt = nullptr;
- bool EventResponder::runningFromYield = false;
-
-
-
- void EventResponder::triggerEventNotImmediate()
- {
- if (_pending) {
-
- return;
- }
- if (_type == EventTypeYield) {
-
- if (firstYield == nullptr) {
- _next = nullptr;
- _prev = nullptr;
- firstYield = this;
- lastYield = this;
- } else {
- _next = nullptr;
- _prev = lastYield;
- _prev->_next = this;
- lastYield = this;
- }
- } else if (_type == EventTypeInterrupt) {
-
- if (firstInterrupt == nullptr) {
- _next = nullptr;
- _prev = nullptr;
- firstInterrupt = this;
- lastInterrupt = this;
- } else {
- _next = nullptr;
- _prev = lastInterrupt;
- _prev->_next = this;
- lastInterrupt = this;
- }
-
- } else {
-
- }
- _pending = true;
- }
-
- void pendablesrvreq_isr(void)
- {
- EventResponder::runFromInterrupt();
- }
-
- void EventResponder::runFromInterrupt()
- {
-
-
-
- for (EventResponder *first=firstInterrupt; first; first = first->_next) {
- first->_pending = false;
- (*(first->_function))(*first);
- }
- firstInterrupt = nullptr;
- lastInterrupt = nullptr;
- }
-
- bool EventResponder::clearEvent()
- {
- if (_pending) {
- if (_type == EventTypeYield) {
- if (_prev) {
- _prev->_next = _next;
- } else {
- firstYield = _next;
- }
- if (_next) {
- _next->_prev = _prev;
- } else {
- lastYield = _prev;
- }
- } else if (_type == EventTypeInterrupt) {
- if (_prev) {
- _prev->_next = _next;
- } else {
- firstInterrupt = _next;
- }
- if (_next) {
- _next->_prev = _prev;
- } else {
- lastInterrupt = _prev;
- }
- }
- _pending = false;
- return true;
- }
- return false;
- }
-
- void EventResponder::detach()
- {
- if (_type == EventTypeYield) {
- if (_pending) {
- if (_prev) {
- _prev->_next = _next;
- } else {
- firstYield = _next;
- }
- if (_next) {
- _next->_prev = _prev;
- } else {
- lastYield = _prev;
- }
- }
- _type = EventTypeDetached;
- } else if (_type == EventTypeInterrupt) {
- if (_pending) {
- if (_prev) {
- _prev->_next = _next;
- } else {
- firstInterrupt = _next;
- }
- if (_next) {
- _next->_prev = _prev;
- } else {
- lastInterrupt = _prev;
- }
- }
- _type = EventTypeDetached;
- }
- }
-
-
-
-
-
- MillisTimer * MillisTimer::list = nullptr;
-
- void MillisTimer::begin(unsigned long milliseconds, EventResponderRef event)
- {
- end();
- if (!milliseconds) return;
- _event = &event;
- _ms = milliseconds;
- _reload = 0;
- addToList();
- }
-
- void MillisTimer::beginRepeat(unsigned long milliseconds, EventResponderRef event)
- {
- end();
- if (!milliseconds) return;
- _event = &event;
- _ms = milliseconds;
- _reload = milliseconds;
- addToList();
- }
-
- void MillisTimer::addToList()
- {
- if (list == nullptr) {
-
- _next = nullptr;
- _prev = nullptr;
- list = this;
- } else if (_ms < list->_ms) {
-
- _next = list;
- _prev = nullptr;
- list->_prev = this;
- list = this;
- } else {
-
- MillisTimer *timer = list;
- while (timer->_next) {
- _ms -= timer->_ms;
- timer = timer->_next;
- if (_ms < timer->_ms) {
-
- _next = timer;
- _prev = timer->_prev;
- timer->_prev = this;
- _prev->_next = this;
- isQueued = true;
- return;
- }
- }
-
- _ms -= timer->_ms;
- _next = nullptr;
- _prev = timer;
- timer->_next = this;
- }
- isQueued = true;
- }
-
- void MillisTimer::end()
- {
- if (isQueued) {
- if (_next) {
- _next->_prev = _prev;
- }
- if (_prev) {
- _prev->_next = _next;
- } else {
- list = _next;
- }
- isQueued = false;
- }
- }
-
- void MillisTimer::runFromTimer()
- {
- MillisTimer *timer = list;
- while (timer) {
- if (timer->_ms > 0) {
- timer->_ms--;
- break;
- } else {
- MillisTimer *next = timer->_next;
- if (next) next->_prev = nullptr;
- list = next;
- timer->isQueued = false;
- EventResponderRef event = *(timer->_event);
- event.triggerEvent(0, timer);
- if (timer->_reload) {
- timer->_ms = timer->_reload;
- timer->addToList();
- }
- timer = list;
- }
- }
- }
-
- extern "C" volatile uint32_t systick_millis_count;
- void systick_isr(void)
- {
- systick_millis_count++;
- MillisTimer::runFromTimer();
- }
-
|