]>
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, | |
40 | }; | |
41 | ||
42 | PT_THREAD(program_colorwheel(struct process_t *process)) | |
43 | { | |
44 | static uint16_t sleep; | |
45 | static struct hsv_color_t c; | |
46 | ||
47 | PT_BEGIN(&process->pt); | |
48 | ||
49 | c.hue = process->params.colorwheel.hue_start; | |
50 | c.value = process->params.colorwheel.value; | |
51 | c.saturation = process->params.colorwheel.saturation; | |
52 | ||
53 | int8_t add = process->params.colorwheel.add_addr; | |
54 | c.hue += remote_address() * add * process->params.colorwheel.hue_step; | |
55 | ||
56 | while (1) { | |
57 | /* set new color */ | |
58 | pwm_fade_hsv(&c, process->params.colorwheel.fade_step, process->params.colorwheel.fade_delay); | |
59 | ||
60 | c.hue += process->params.colorwheel.hue_step; | |
61 | ||
62 | /* wait until target reached */ | |
63 | PT_WAIT_UNTIL(&process->pt, pwm_target_reached()); | |
64 | ||
65 | /* sleep (in seconds, remember: we are called every 100ms) */ | |
66 | sleep = 10 * process->params.colorwheel.fade_sleep; | |
67 | while (sleep--) | |
68 | PT_YIELD(&process->pt); | |
69 | } | |
70 | ||
71 | PT_END(&process->pt); | |
72 | } | |
73 | ||
74 | PT_THREAD(program_random(struct process_t *process)) | |
75 | { | |
76 | static uint16_t sleep; | |
77 | static struct hsv_color_t c; | |
78 | ||
79 | PT_BEGIN(&process->pt); | |
80 | ||
81 | /* initialize random generator */ | |
82 | uint16_t seed = process->params.random.seed; | |
83 | if (process->params.random.use_address) | |
84 | seed ^= remote_address(); | |
85 | srandom(seed); | |
86 | ||
87 | c.value = process->params.random.value; | |
88 | c.saturation = process->params.random.saturation; | |
89 | ||
90 | while (1) { | |
91 | /* generate new color */ | |
92 | union uint32_t_access rnd; | |
93 | rnd.raw = random(); | |
94 | ||
95 | /* use lower word for hue */ | |
96 | rnd.words[0] %= 360; | |
97 | ||
98 | /* check for minimal color distance, regenerate random if not */ | |
99 | int16_t min_distance = process->params.random.min_distance; | |
100 | if (min_distance) { | |
101 | int16_t distance = c.hue - rnd.words[0]; | |
102 | if (distance < 0) | |
103 | distance = -distance; | |
104 | ||
105 | if (distance > 180) | |
106 | distance = 360-distance; | |
107 | ||
108 | if (distance < min_distance) | |
109 | continue; | |
110 | } | |
111 | ||
112 | /* copy color to structure */ | |
113 | c.hue = rnd.words[0]; | |
114 | ||
115 | /* fade to new color */ | |
116 | pwm_fade_hsv(&c, process->params.random.fade_step, process->params.random.fade_delay); | |
117 | ||
118 | /* wait until target reached */ | |
119 | if (process->params.random.wait_for_fade) | |
120 | PT_WAIT_UNTIL(&process->pt, pwm_target_reached()); | |
121 | ||
122 | /* sleep (remember: we are called every 100ms) */ | |
123 | if (process->params.random.fade_sleep > 0) { | |
124 | sleep = process->params.random.fade_sleep; | |
125 | ||
126 | while (sleep--) | |
127 | PT_YIELD(&process->pt); | |
128 | } | |
129 | } | |
130 | ||
131 | PT_END(&process->pt); | |
132 | } | |
133 | ||
134 | PT_THREAD(program_replay(struct process_t *process)) | |
135 | { | |
136 | static uint8_t pos; | |
137 | static enum { | |
138 | UP = 0, | |
139 | DOWN = 1, | |
140 | } direction; | |
141 | static struct storage_color_t c; | |
142 | ||
143 | PT_BEGIN(&process->pt); | |
144 | ||
145 | /* reset variables */ | |
146 | pos = process->params.replay.start; | |
147 | direction = UP; | |
148 | ||
149 | while (1) { | |
150 | /* load next color value */ | |
151 | storage_load_color(pos, &c); | |
152 | ||
153 | if (c.color.rgb_marker == 0xff) { | |
154 | struct rgb_color_t color; | |
155 | color.red = c.color.red; | |
156 | color.green = c.color.green; | |
157 | color.blue = c.color.blue; | |
158 | ||
159 | pwm_fade_rgb(&color, c.step, c.delay); | |
160 | } else { | |
161 | struct hsv_color_t color; | |
162 | color.hue = c.color.hue; | |
163 | color.saturation = c.color.saturation; | |
164 | color.value = c.color.value; | |
165 | ||
166 | pwm_fade_hsv(&color, c.step, c.delay); | |
167 | } | |
168 | ||
169 | /* update pos */ | |
170 | if (direction == UP) { | |
171 | /* check for upper end */ | |
172 | if (pos == process->params.replay.end) { | |
173 | switch (process->params.replay.repeat) { | |
174 | case REPEAT_NONE: PT_EXIT(&process->pt); | |
175 | break; | |
176 | case REPEAT_START: pos = process->params.replay.start; | |
177 | break; | |
178 | case REPEAT_REVERSE: direction = DOWN; | |
179 | pos--; | |
180 | break; | |
181 | } | |
182 | } else | |
183 | pos++; | |
184 | } else { | |
185 | if (pos == process->params.replay.start) { | |
186 | direction = UP; | |
187 | pos++; | |
188 | } else | |
189 | pos--; | |
190 | } | |
191 | ||
192 | /* wait */ | |
193 | while (c.pause--) | |
194 | PT_YIELD(&process->pt); | |
195 | } | |
196 | ||
197 | PT_END(&process->pt); | |
198 | } | |
199 | ||
200 | #endif |