-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathLedPattern.cpp
More file actions
134 lines (123 loc) · 3.54 KB
/
LedPattern.cpp
File metadata and controls
134 lines (123 loc) · 3.54 KB
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
134
#include "LedPattern.h"
#include <Arduino.h> // Only for debugging with Serial
#include <assert.h>
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define NODEBUG
#ifndef NODEBUG
#define debug(x) Serial.print(x)
#define debugln(x) Serial.println(x); Serial.flush();
#else
#define debug(x)
#define debugln(x)
#endif
LedPattern::LedPattern(void)
{
stop();
}
LedPattern::~LedPattern(void)
{
}
void LedPattern::start(const pattern p)
{
LED_PATTERN_CRITICAL_SECTION_START
m_pattern = p;
m_repeatStackIdx = -1;
LED_PATTERN_CRITICAL_SECTION_END
}
void LedPattern::intStop(void)
{
// Internal stop method, which doesn't use critical section.
m_pattern = 0;
m_repeatStackIdx = -1;
}
void LedPattern::stop(void)
{
LED_PATTERN_CRITICAL_SECTION_START
intStop();
LED_PATTERN_CRITICAL_SECTION_END
}
void LedPattern::off(void)
{
LED_PATTERN_CRITICAL_SECTION_START
intStop();
ledOff();
LED_PATTERN_CRITICAL_SECTION_END
}
bool LedPattern::finished(void)
{
LED_PATTERN_CRITICAL_SECTION_START
bool finished = !m_pattern;
LED_PATTERN_CRITICAL_SECTION_END
return finished;
}
void LedPattern::update( void )
{
LED_PATTERN_CRITICAL_SECTION_START
for(;;)
{
// Update the led state.
if (!m_pattern)
{
break;
}
if (m_wait > 1)
{
#ifndef LED_PATTERN_FADE_UNSUPPORTED
ledUpdate();
#endif
--m_wait;
break;
}
for (;;)
{
CMD cmd = CMD(*m_pattern++);
if (CMD_SET == cmd)
{
ledSet(m_pattern);
debugln("SET");
#ifndef LED_PATTERN_FADE_UNSUPPORTED
} else if (CMD_FADETO == cmd) {
m_wait = *m_pattern++;
assert(m_wait != 0);
ledFadeTo(m_pattern, m_wait);
debug("FADETO:"); debugln(m_wait);
break;
#endif
} else if (CMD_WAIT == cmd) {
m_wait = *m_pattern++;
debug("WAIT:"); debugln(m_wait);
#ifndef LED_PATTERN_FADE_UNSUPPORTED
ledFadeStop();
#endif
break;
} else if (CMD_REPEAT == cmd) {
++m_repeatStackIdx;
assert(size_t(m_repeatStackIdx) < ARRAY_SIZE(m_repeatStack));
m_repeatStack[m_repeatStackIdx].m_repeat = *m_pattern++;
m_repeatStack[m_repeatStackIdx].m_pc = m_pattern;
debug("REPEAT:"); debugln(m_repeatStack[m_repeatStackIdx].m_repeat);
} else if (CMD_ENDREPEAT == cmd) {
assert(m_repeatStackIdx >= 0);
if (m_repeatStack[m_repeatStackIdx].m_repeat <= 1)
{
// Finished repeating
--m_repeatStackIdx;
debugln("END_REPEAT:DONE");
} else {
// Repeat once more
if (m_repeatStack[m_repeatStackIdx].m_repeat != repeatForever) {
--m_repeatStack[m_repeatStackIdx].m_repeat;
}
m_pattern = m_repeatStack[m_repeatStackIdx].m_pc;
debug("END_REPEAT:"); debugln(m_repeatStack[m_repeatStackIdx].m_repeat);
}
} else if (CMD_FINISHED == cmd) {
stop();
debugln("FINISHED");
break;
}
}
break;
}
LED_PATTERN_CRITICAL_SECTION_END
}