]> git.zerfleddert.de Git - fnordlicht-mini/blob - firmware/fnordlicht-firmware/static_programs.c
d5a79e086090f829b151c74fa3d8981d9760c4f6
[fnordlicht-mini] / firmware / fnordlicht-firmware / static_programs.c
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,
40 program_showcfg,
41 };
42
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
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
Impressum, Datenschutz