forked from pa-pa/AskSinPP
-
Notifications
You must be signed in to change notification settings - Fork 0
/
AlarmClock.cpp
116 lines (105 loc) · 2.49 KB
/
AlarmClock.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
//- -----------------------------------------------------------------------------------------------------------------------
// AskSin++
// 2016-10-31 papa Creative Commons - https://creativecommons.org/licenses/by-nc-sa/3.0/de/
//- -----------------------------------------------------------------------------------------------------------------------
#include "AlarmClock.h"
namespace as {
SysClock sysclock;
RTC rtc;
Link pwm(0);
void callback(void) {
--sysclock;
SoftPWM* p = (SoftPWM*)pwm.select();
while( p != 0 ) {
p->count();
p = (SoftPWM*)p->select();
}
}
#if ARDUINO_ARCH_AVR or ARDUINO_ARCH_ATMEGA32
ISR(TIMER1_OVF_vect) {
callback();
}
ISR(TIMER2_OVF_vect) {
rtc.overflow();
--rtc;
}
#endif
void AlarmClock::cancel(Alarm& item) {
ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
{
Alarm *tmp = (Alarm*) select();
Link *vor = this;
// search for the alarm to cancel
while (tmp != 0) {
if (tmp == &item) {
vor->unlink();
// raise next alarm about item ticks
tmp = (Alarm*) item.select();
if (tmp != 0) {
tmp->tick += item.tick;
}
return;
}
vor = tmp;
tmp = (Alarm*) tmp->select();
}
// cancel also in ready queue
ready.remove(item);
}
}
AlarmClock& AlarmClock::operator --() {
ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
{
Alarm* alarm = (Alarm*) select();
if (alarm != 0) {
--alarm->tick;
while ((alarm != 0) && (alarm->tick == 0)) {
unlink(); // remove expired alarm
// run in interrupt
if (alarm->async() == true) {
alarm->trigger(*this);
}
// run in application
else {
ready.append(*alarm);
}
alarm = (Alarm*) select();
}
}
}
return *this;
}
void AlarmClock::add(Alarm& item) {
if (item.tick > 0) {
ATOMIC_BLOCK( ATOMIC_RESTORESTATE )
{
Link* prev = this;
Alarm* temp = (Alarm*) select();
while ((temp != 0) && (temp->tick < item.tick)) {
item.tick -= temp->tick;
prev = temp;
temp = (Alarm*) temp->select();
}
item.select(temp);
prev->select(&item);
if (temp != 0) {
temp->tick -= item.tick;
}
}
} else {
ready.append(item);
}
}
uint32_t AlarmClock::get(const Alarm& item) const {
uint32_t aux = 0;
Alarm* tmp = (Alarm*) select();
while (tmp != 0) {
aux += tmp->tick;
if (tmp == &item) {
return aux;
}
tmp = (Alarm*) tmp->select();
}
return 0;
}
}