]>
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" | |
32 | ||
33 | #if CONFIG_SCRIPT | |
34 | ||
35 | /* global list of programs */ | |
36 | PROGMEM program_handler static_programs[] = { | |
37 | program_colorwheel, | |
38 | program_random, | |
39 | program_replay, | |
0c9ba54a | 40 | program_showcfg, |
ec1bef8e | 41 | }; |
42 | ||
0c9ba54a | 43 | PT_THREAD(program_showcfg(struct process_t *process)) |
44 | { | |
45 | static uint16_t sleep; | |
46 | struct rgb_color_t c, d; | |
47 | ||
48 | PT_BEGIN(&process->pt); | |
49 | ||
50 | c.red = (remote_address() & 0x01u) * 128u; | |
51 | c.green = (remote_address() & 0x02u) * 128u; | |
52 | c.blue = (remote_address() & 0x04u) * 128u; | |
53 | ||
54 | d.red = d.green = d.blue = 128u; | |
55 | ||
56 | pwm_fade_rgb(&d, 0xffu, 0); | |
57 | ||
58 | PT_WAIT_UNTIL(&process->pt, pwm_target_reached()); | |
59 | ||
60 | /* sleep .5s (remember: we are called every 100ms) */ | |
61 | sleep = 5; | |
62 | while (sleep--) | |
63 | PT_YIELD(&process->pt); | |
64 | ||
65 | pwm_fade_rgb(&c, 0xffu, 0); | |
66 | ||
67 | PT_WAIT_UNTIL(&process->pt, pwm_target_reached()); | |
68 | ||
69 | /* sleep 1s (remember: we are called every 100ms) */ | |
70 | sleep = 10; | |
71 | while (sleep--) | |
72 | PT_YIELD(&process->pt); | |
73 | pwm_fade_rgb(&d, 0xffu, 0); | |
74 | ||
75 | PT_WAIT_UNTIL(&process->pt, pwm_target_reached()); | |
76 | ||
77 | /* sleep .5s (remember: we are called every 100ms) */ | |
78 | sleep = 5; | |
79 | while (sleep--) | |
80 | PT_YIELD(&process->pt); | |
81 | ||
82 | pwm_fade_rgb(&c, 0xffu, 0); | |
83 | ||
84 | PT_WAIT_UNTIL(&process->pt, pwm_target_reached()); | |
85 | ||
86 | /* sleep 1s (remember: we are called every 100ms) */ | |
87 | sleep = 10; | |
88 | while (sleep--) | |
89 | PT_YIELD(&process->pt); | |
90 | ||
91 | /* now start default script */ | |
92 | if (storage_valid_config() && (startup_config.params.mode == STARTUP_PROGRAM)) { | |
93 | script_start(0, startup_config.params.program, (union program_params_t *)startup_config.params.program_parameters); | |
94 | } else { | |
95 | script_start_default(); | |
96 | } | |
97 | ||
98 | PT_END(&process->pt); | |
99 | } | |
100 | ||
ec1bef8e | 101 | PT_THREAD(program_colorwheel(struct process_t *process)) |
102 | { | |
103 | static uint16_t sleep; | |
104 | static struct hsv_color_t c; | |
105 | ||
106 | PT_BEGIN(&process->pt); | |
107 | ||
108 | c.hue = process->params.colorwheel.hue_start; | |
109 | c.value = process->params.colorwheel.value; | |
110 | c.saturation = process->params.colorwheel.saturation; | |
111 | ||
112 | int8_t add = process->params.colorwheel.add_addr; | |
113 | c.hue += remote_address() * add * process->params.colorwheel.hue_step; | |
114 | ||
115 | while (1) { | |
116 | /* set new color */ | |
117 | pwm_fade_hsv(&c, process->params.colorwheel.fade_step, process->params.colorwheel.fade_delay); | |
118 | ||
119 | c.hue += process->params.colorwheel.hue_step; | |
120 | ||
121 | /* wait until target reached */ | |
122 | PT_WAIT_UNTIL(&process->pt, pwm_target_reached()); | |
123 | ||
124 | /* sleep (in seconds, remember: we are called every 100ms) */ | |
125 | sleep = 10 * process->params.colorwheel.fade_sleep; | |
126 | while (sleep--) | |
127 | PT_YIELD(&process->pt); | |
128 | } | |
129 | ||
130 | PT_END(&process->pt); | |
131 | } | |
132 | ||
133 | PT_THREAD(program_random(struct process_t *process)) | |
134 | { | |
135 | static uint16_t sleep; | |
136 | static struct hsv_color_t c; | |
137 | ||
138 | PT_BEGIN(&process->pt); | |
139 | ||
140 | /* initialize random generator */ | |
141 | uint16_t seed = process->params.random.seed; | |
142 | if (process->params.random.use_address) | |
143 | seed ^= remote_address(); | |
144 | srandom(seed); | |
145 | ||
146 | c.value = process->params.random.value; | |
147 | c.saturation = process->params.random.saturation; | |
148 | ||
149 | while (1) { | |
150 | /* generate new color */ | |
151 | union uint32_t_access rnd; | |
152 | rnd.raw = random(); | |
153 | ||
154 | /* use lower word for hue */ | |
155 | rnd.words[0] %= 360; | |
156 | ||
157 | /* check for minimal color distance, regenerate random if not */ | |
158 | int16_t min_distance = process->params.random.min_distance; | |
159 | if (min_distance) { | |
160 | int16_t distance = c.hue - rnd.words[0]; | |
161 | if (distance < 0) | |
162 | distance = -distance; | |
163 | ||
164 | if (distance > 180) | |
165 | distance = 360-distance; | |
166 | ||
167 | if (distance < min_distance) | |
168 | continue; | |
169 | } | |
170 | ||
171 | /* copy color to structure */ | |
172 | c.hue = rnd.words[0]; | |
173 | ||
174 | /* fade to new color */ | |
175 | pwm_fade_hsv(&c, process->params.random.fade_step, process->params.random.fade_delay); | |
176 | ||
177 | /* wait until target reached */ | |
178 | if (process->params.random.wait_for_fade) | |
179 | PT_WAIT_UNTIL(&process->pt, pwm_target_reached()); | |
180 | ||
181 | /* sleep (remember: we are called every 100ms) */ | |
182 | if (process->params.random.fade_sleep > 0) { | |
183 | sleep = process->params.random.fade_sleep; | |
184 | ||
185 | while (sleep--) | |
186 | PT_YIELD(&process->pt); | |
187 | } | |
188 | } | |
189 | ||
190 | PT_END(&process->pt); | |
191 | } | |
192 | ||
193 | PT_THREAD(program_replay(struct process_t *process)) | |
194 | { | |
195 | static uint8_t pos; | |
196 | static enum { | |
197 | UP = 0, | |
198 | DOWN = 1, | |
199 | } direction; | |
200 | static struct storage_color_t c; | |
201 | ||
202 | PT_BEGIN(&process->pt); | |
203 | ||
204 | /* reset variables */ | |
205 | pos = process->params.replay.start; | |
206 | direction = UP; | |
207 | ||
208 | while (1) { | |
209 | /* load next color value */ | |
210 | storage_load_color(pos, &c); | |
211 | ||
212 | if (c.color.rgb_marker == 0xff) { | |
213 | struct rgb_color_t color; | |
214 | color.red = c.color.red; | |
215 | color.green = c.color.green; | |
216 | color.blue = c.color.blue; | |
217 | ||
218 | pwm_fade_rgb(&color, c.step, c.delay); | |
219 | } else { | |
220 | struct hsv_color_t color; | |
221 | color.hue = c.color.hue; | |
222 | color.saturation = c.color.saturation; | |
223 | color.value = c.color.value; | |
224 | ||
225 | pwm_fade_hsv(&color, c.step, c.delay); | |
226 | } | |
227 | ||
228 | /* update pos */ | |
229 | if (direction == UP) { | |
230 | /* check for upper end */ | |
231 | if (pos == process->params.replay.end) { | |
232 | switch (process->params.replay.repeat) { | |
233 | case REPEAT_NONE: PT_EXIT(&process->pt); | |
234 | break; | |
235 | case REPEAT_START: pos = process->params.replay.start; | |
236 | break; | |
237 | case REPEAT_REVERSE: direction = DOWN; | |
238 | pos--; | |
239 | break; | |
240 | } | |
241 | } else | |
242 | pos++; | |
243 | } else { | |
244 | if (pos == process->params.replay.start) { | |
245 | direction = UP; | |
246 | pos++; | |
247 | } else | |
248 | pos--; | |
249 | } | |
250 | ||
251 | /* wait */ | |
252 | while (c.pause--) | |
253 | PT_YIELD(&process->pt); | |
254 | } | |
255 | ||
256 | PT_END(&process->pt); | |
257 | } | |
258 | ||
259 | #endif |