-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathEventFuse.cpp
133 lines (113 loc) · 4.13 KB
/
EventFuse.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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
* EventFuse.cpp - A simple fuse-based event callback library
* v0.1 - 2009-June-16
* v0.2 - 2009-June-16 Added fsBlocked state to handle callback reentrance.
* v0.3 - 2012-April-27
* - Minor update to burn() to out or range issue in repeatCount.
* This caused problems with INF_REPEAT fuses.
* v0.4 - 2013-Dec-20
* - Converted to namespace.
* - added burn() to burn by one.
* - changed callback user data to int&
* - added cancel(FuseID)
* Derived from:
* Timer.cpp - A Real-time Timer Library for Arduino & Wiring
* Copyright (c) 2009 Daniel Bradberry. All right reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "EventFuse.h"
namespace EventFuse {
eventFuse_t fuses[MAX_FUSES];
void init() {
for(unsigned char i=0; i<MAX_FUSES; i++) {
// init fuses to unallocated state
fuses[i].fuseState = fsUnallocated;
}
}
void resetFuse(FuseID fuse, int userData, int fuseLen, unsigned int repeatCount, eventFuseCallback_t fuseCallback)
{
fuses[fuse].fuseState = fsEnabled;
fuses[fuse].fuseInit = fuseLen;
fuses[fuse].fuseLen = fuseLen;
fuses[fuse].repeatCount = repeatCount;
fuses[fuse].userData = userData;
fuses[fuse].callback = fuseCallback;
}
void resetFuse(FuseID fuse, int fuseLen, unsigned int repeatCount, eventFuseCallback_t fuseCallback)
{
resetFuse( fuse, 0, fuseLen, repeatCount, fuseCallback );
}
FuseID newFuse(int fuseLen, unsigned int repeatCount, eventFuseCallback_t fuseCallback)
{
return newFuse( 0, fuseLen, repeatCount, fuseCallback );
}
FuseID newFuse(int userData, int fuseLen, unsigned int repeatCount, eventFuseCallback_t fuseCallback)
{
// Repeat count must be at least one or INF_REPEAT
if (repeatCount<1)
return NULL_FUSE;
// search for the first unallocated fuse
unsigned char i;
for(i=0; i<MAX_FUSES; i++) {
if(fuses[i].fuseState == fsUnallocated)
break;
}
// no fuses available
if(i == MAX_FUSES)
return NULL_FUSE;
resetFuse( i, userData, fuseLen, repeatCount, fuseCallback );
return i;
}
void burn(){
burn(1);
}
void burn(int len) {
for(unsigned char i=0; i<MAX_FUSES; i++) {
if(fuses[i].fuseState == fsEnabled) {
// burn the fuse the specified length
fuses[i].fuseLen -= len;
// if the fuse has burned down to (or past) zero
if(fuses[i].fuseLen <= 0) {
// Disable the fuse during the callback. This prevents
// reentering the callback if burn() is called again
// such as by an interrupt.
FuseState tState = fuses[i].fuseState;
fuses[i].fuseState = fsBlocked;
// Exec the callback and pass the relevant fuse.
// The user may check the fuseLen if necessary
// to compensate for overshoot.
// The user may also reset the fuse length for
// the next burn, adjust the repeat count, etc.
int tLen = fuses[i].fuseLen;
fuses[i].callback(i,fuses[i].userData);
// restore the fuse state if it hasn't been updated
if (fuses[i].fuseState == fsBlocked)
fuses[i].fuseState = tState;
// if fuseLen wasn't changed in the callback
// reset it to fuseInit. If it was changed then
// that value will be the new fuse length, overriding
// the value specified in fuseInit.
if(tLen == fuses[i].fuseLen)
fuses[i].fuseLen = fuses[i].fuseInit;
if((fuses[i].repeatCount != INF_REPEAT))
fuses[i].repeatCount--;
if(fuses[i].repeatCount == 0)
fuses[i].fuseState = fsUnallocated;
}
}
}
}
}