]>
Commit | Line | Data |
---|---|---|
ec1bef8e | 1 | /* vim:ts=4 sts=4 et tw=80 |
2 | * | |
3 | * fnordlicht firmware | |
4 | * | |
5 | * for additional information please | |
6 | * see http://lochraster.org/fnordlichtmini | |
7 | * | |
8 | * (c) by Alexander Neumann <alexander@bumpern.de> | |
9 | * | |
10 | * This program is free software: you can redistribute it and/or modify it | |
11 | * under the terms of the GNU General Public License version 3 as published by | |
12 | * the Free Software Foundation. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
15 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
17 | * more details. | |
18 | * | |
19 | * You should have received a copy of the GNU General Public License along with | |
20 | * this program. If not, see <http://www.gnu.org/licenses/>. | |
21 | */ | |
22 | ||
23 | #include <stdlib.h> | |
24 | #include <avr/pgmspace.h> | |
25 | #include "static_programs.h" | |
26 | #include "color.h" | |
27 | #include "pwm.h" | |
28 | #include "timer.h" | |
29 | #include "remote.h" | |
30 | #include "../common/common.h" | |
31 | #include "storage.h" | |
83bcec4b | 32 | #include "script.h" |
ec1bef8e | 33 | |
34 | #if CONFIG_SCRIPT | |
35 | ||
36 | /* global list of programs */ | |
37 | PROGMEM program_handler static_programs[] = { | |
38 | program_colorwheel, | |
39 | program_random, | |
40 | program_replay, | |
0c9ba54a | 41 | program_showcfg, |
ec1bef8e | 42 | }; |
43 | ||
3ae23878 | 44 | #define DEBUG_COLORLEVEL 32u |
45 | ||
0c9ba54a | 46 | PT_THREAD(program_showcfg(struct process_t *process)) |
47 | { | |
48 | static uint16_t sleep; | |
3ae23878 | 49 | static struct rgb_color_t c, d; |
50 | static uint8_t i; | |
0c9ba54a | 51 | |
52 | PT_BEGIN(&process->pt); | |
53 | ||
3ae23878 | 54 | c.red = (remote_address() & 0x01u) ? DEBUG_COLORLEVEL : 0; |
55 | c.green = (remote_address() & 0x02u) ? DEBUG_COLORLEVEL : 0; | |
56 | c.blue = (remote_address() & 0x04u) ? DEBUG_COLORLEVEL : 0; | |
0c9ba54a | 57 | |
83bcec4b | 58 | d.red = d.green = d.blue = 0; |
0c9ba54a | 59 | |
3ae23878 | 60 | global_pwm.target.rgb = c; |
0c9ba54a | 61 | |
3ae23878 | 62 | for (i = 0; i < 3u; i++) |
63 | { | |
64 | /* sleep 1s (remember: we are called every 100ms) */ | |
65 | sleep = 10; | |
66 | while (sleep--) | |
937531b6 | 67 | PT_YIELD(&process->pt); |
0c9ba54a | 68 | |
83bcec4b | 69 | global_pwm.target.rgb = c; |
0c9ba54a | 70 | |
3ae23878 | 71 | sleep = 5; |
72 | while (sleep--) | |
73 | PT_YIELD(&process->pt); | |
0c9ba54a | 74 | |
83bcec4b | 75 | global_pwm.target.rgb = d; |
3ae23878 | 76 | } |
0c9ba54a | 77 | |
83bcec4b | 78 | script_stop(); |
79 | ||
0c9ba54a | 80 | /* now start default script */ |
81 | if (storage_valid_config() && (startup_config.params.mode == STARTUP_PROGRAM)) { | |
82 | script_start(0, startup_config.params.program, (union program_params_t *)startup_config.params.program_parameters); | |
83 | } else { | |
84 | script_start_default(); | |
85 | } | |
86 | ||
83bcec4b | 87 | /* hack: script_start() stuff above will reinitialize PT structures, so we |
88 | can't call any PT stuff any more and quit directly */ | |
89 | return 0; | |
90 | ||
0c9ba54a | 91 | PT_END(&process->pt); |
92 | } | |
93 | ||
ec1bef8e | 94 | PT_THREAD(program_colorwheel(struct process_t *process)) |
95 | { | |
96 | static uint16_t sleep; | |
97 | static struct hsv_color_t c; | |
98 | ||
99 | PT_BEGIN(&process->pt); | |
100 | ||
101 | c.hue = process->params.colorwheel.hue_start; | |
102 | c.value = process->params.colorwheel.value; | |
103 | c.saturation = process->params.colorwheel.saturation; | |
104 | ||
105 | int8_t add = process->params.colorwheel.add_addr; | |
106 | c.hue += remote_address() * add * process->params.colorwheel.hue_step; | |
107 | ||
108 | while (1) { | |
109 | /* set new color */ | |
110 | pwm_fade_hsv(&c, process->params.colorwheel.fade_step, process->params.colorwheel.fade_delay); | |
111 | ||
112 | c.hue += process->params.colorwheel.hue_step; | |
113 | ||
114 | /* wait until target reached */ | |
115 | PT_WAIT_UNTIL(&process->pt, pwm_target_reached()); | |
116 | ||
117 | /* sleep (in seconds, remember: we are called every 100ms) */ | |
118 | sleep = 10 * process->params.colorwheel.fade_sleep; | |
119 | while (sleep--) | |
120 | PT_YIELD(&process->pt); | |
121 | } | |
122 | ||
123 | PT_END(&process->pt); | |
124 | } | |
125 | ||
126 | PT_THREAD(program_random(struct process_t *process)) | |
127 | { | |
128 | static uint16_t sleep; | |
129 | static struct hsv_color_t c; | |
130 | ||
131 | PT_BEGIN(&process->pt); | |
132 | ||
133 | /* initialize random generator */ | |
134 | uint16_t seed = process->params.random.seed; | |
135 | if (process->params.random.use_address) | |
136 | seed ^= remote_address(); | |
137 | srandom(seed); | |
138 | ||
139 | c.value = process->params.random.value; | |
140 | c.saturation = process->params.random.saturation; | |
141 | ||
142 | while (1) { | |
143 | /* generate new color */ | |
144 | union uint32_t_access rnd; | |
145 | rnd.raw = random(); | |
146 | ||
147 | /* use lower word for hue */ | |
148 | rnd.words[0] %= 360; | |
149 | ||
150 | /* check for minimal color distance, regenerate random if not */ | |
151 | int16_t min_distance = process->params.random.min_distance; | |
152 | if (min_distance) { | |
153 | int16_t distance = c.hue - rnd.words[0]; | |
154 | if (distance < 0) | |
155 | distance = -distance; | |
156 | ||
157 | if (distance > 180) | |
158 | distance = 360-distance; | |
159 | ||
160 | if (distance < min_distance) | |
161 | continue; | |
162 | } | |
163 | ||
164 | /* copy color to structure */ | |
165 | c.hue = rnd.words[0]; | |
166 | ||
167 | /* fade to new color */ | |
168 | pwm_fade_hsv(&c, process->params.random.fade_step, process->params.random.fade_delay); | |
169 | ||
170 | /* wait until target reached */ | |
171 | if (process->params.random.wait_for_fade) | |
172 | PT_WAIT_UNTIL(&process->pt, pwm_target_reached()); | |
173 | ||
174 | /* sleep (remember: we are called every 100ms) */ | |
175 | if (process->params.random.fade_sleep > 0) { | |
176 | sleep = process->params.random.fade_sleep; | |
177 | ||
178 | while (sleep--) | |
179 | PT_YIELD(&process->pt); | |
180 | } | |
181 | } | |
182 | ||
183 | PT_END(&process->pt); | |
184 | } | |
185 | ||
186 | PT_THREAD(program_replay(struct process_t *process)) | |
187 | { | |
188 | static uint8_t pos; | |
189 | static enum { | |
190 | UP = 0, | |
191 | DOWN = 1, | |
192 | } direction; | |
193 | static struct storage_color_t c; | |
194 | ||
195 | PT_BEGIN(&process->pt); | |
196 | ||
197 | /* reset variables */ | |
198 | pos = process->params.replay.start; | |
199 | direction = UP; | |
200 | ||
201 | while (1) { | |
202 | /* load next color value */ | |
203 | storage_load_color(pos, &c); | |
204 | ||
205 | if (c.color.rgb_marker == 0xff) { | |
206 | struct rgb_color_t color; | |
207 | color.red = c.color.red; | |
208 | color.green = c.color.green; | |
209 | color.blue = c.color.blue; | |
210 | ||
211 | pwm_fade_rgb(&color, c.step, c.delay); | |
212 | } else { | |
213 | struct hsv_color_t color; | |
214 | color.hue = c.color.hue; | |
215 | color.saturation = c.color.saturation; | |
216 | color.value = c.color.value; | |
217 | ||
218 | pwm_fade_hsv(&color, c.step, c.delay); | |
219 | } | |
220 | ||
221 | /* update pos */ | |
222 | if (direction == UP) { | |
223 | /* check for upper end */ | |
224 | if (pos == process->params.replay.end) { | |
225 | switch (process->params.replay.repeat) { | |
226 | case REPEAT_NONE: PT_EXIT(&process->pt); | |
227 | break; | |
228 | case REPEAT_START: pos = process->params.replay.start; | |
229 | break; | |
230 | case REPEAT_REVERSE: direction = DOWN; | |
231 | pos--; | |
232 | break; | |
233 | } | |
234 | } else | |
235 | pos++; | |
236 | } else { | |
237 | if (pos == process->params.replay.start) { | |
238 | direction = UP; | |
239 | pos++; | |
240 | } else | |
241 | pos--; | |
242 | } | |
243 | ||
244 | /* wait */ | |
245 | while (c.pause--) | |
246 | PT_YIELD(&process->pt); | |
247 | } | |
248 | ||
249 | PT_END(&process->pt); | |
250 | } | |
251 | ||
252 | #endif |