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