SingingCat 0
application
led.c
Go to the documentation of this file.
1#include <main-header.h>
2#include "led.h"
3
4// the brightness required for each R,G,B value to trigger mosfets(if enabled)
5#define LED_WHITE_MIN (250 * 0xFF)
6
17# define LED_TIMER_FREQUENCY 130
18
19// 0=nothing, 1=fade, 2=blink,3=on,4=fade_to
20static byte operation;
21static uint8_t do_mosfet;
22static int ctr = 0;
23static int lastled = 0;
24static uint16_t fadetarget[3]; //0=R, 1=G, 2=B
25static uint16_t curled[3]; //0=R, 1=G, 2=B
26static uint16_t ledoffval[3]; //0=R, 1=G, 2=B
27static uint16_t blink_colour[3]; //0=R, 1=G, 2=B
28
29typedef struct leddef {
30 int pins[3]; //rgb
31 int timers[3];
32} _leddef;
33
34/*
35 * The timer numbers do _not_ match the STM32 documentation. The mculibrary counts
36 * timers from 0..n, whereas STM counts from 1...n.. Thus "timer 3" is "stm-timer 4"
37 */
38struct leddef intled = { .pins = { 106, 107, 108 }, .timers = { 3, 3, 3 } };
39struct leddef extled = { .pins = { 7, 110, 111 }, .timers = { 2, 1, 1 } };
40
41static struct leddef *curpins;
42
43static byte led_managed_by;
44static byte lastledconfig;
45
46typedef struct ledcolour {
47 uint32_t colour;
48 uint8_t brightness;
49 uint32_t on;
50 uint32_t off;
52
53struct ledcolour usercolour;
54struct ledcolour machinecolour;
55
56static void mosfet(uint8_t number, uint8_t state) {
57 mculib_pin_set(MAIN_MCULIBHANDLE, number + 100, state);
58}
59static int isSameRGB(uint16_t src[3], uint16_t dst[3]) {
60 if (src[0] != dst[0]) {
61 return 0;
62 }
63 if (src[1] != dst[1]) {
64 return 0;
65 }
66 if (src[2] != dst[2]) {
67 return 0;
68 }
69 return 1;
70}
71
72static void copy_colour(uint16_t src[3], uint16_t dst[3]) {
73 dst[0] = src[0];
74 dst[1] = src[1];
75 dst[2] = src[2];
76}
77static struct ledcolour *get_led_colour() {
78 if (led_managed_by == LED_USER) {
79 return &usercolour;
80 }
81 return &machinecolour;
82}
87static void colour_to_array(uint16_t *dest, uint32_t colour, uint8_t brightness) {
88 dest[0] = (colour >> 16) & 0xFF;
89 dest[1] = (colour >> 8) & 0xFF;
90 dest[2] = (colour) & 0xFF;
91 int i;
92
93 for (i = 0; i < 3; i++) {
94 dest[i] = dest[i] * (uint16_t)brightness;
95 }
96}
97static void set_blink_colour(uint32_t colour, int brightness) {
98 colour_to_array(blink_colour, colour, brightness);
99}
100
101static void set_led(uint16_t rgb[3]) {
102 // the uint16 is actually RGB byte values multiplied by brightness
103 copy_colour(rgb, curled);
104 if (config_get_flag(CONFIG_FLAGS_INTERNAL_LED_INVERTED)) {
105 mculib_timer_set_pwm(MAIN_MCULIBHANDLE, curpins->timers[0], curpins->pins[0], rgb[0]);
106 mculib_timer_set_pwm(MAIN_MCULIBHANDLE, curpins->timers[1], curpins->pins[1], rgb[1]);
107 mculib_timer_set_pwm(MAIN_MCULIBHANDLE, curpins->timers[2], curpins->pins[2], rgb[2]);
108 } else {
109 mculib_timer_set_pwm(MAIN_MCULIBHANDLE, curpins->timers[0], curpins->pins[0], 0xFFFF - rgb[0]);
110 mculib_timer_set_pwm(MAIN_MCULIBHANDLE, curpins->timers[1], curpins->pins[1], 0xFFFF - rgb[1]);
111 mculib_timer_set_pwm(MAIN_MCULIBHANDLE, curpins->timers[2], curpins->pins[2], 0xFFFF - rgb[2]);
112 }
113 // do_mosfet for some extra performance in the IRQ (set by userloop)
114 if (do_mosfet) {
115 // white handling
116 if ((rgb[0] > LED_WHITE_MIN) && (rgb[1] > LED_WHITE_MIN) && (rgb[2] > LED_WHITE_MIN)) {
117 // mosfets on
118 if (config_get_flag(CONFIG_FLAGS_WHITE_MOSFET0)) {
119 mosfet(0, 1);
120 }
121 if (config_get_flag(CONFIG_FLAGS_WHITE_MOSFET1)) {
122 mosfet(1, 1);
123 }
124 } else {
125 // mosfets off
126 if (config_get_flag(CONFIG_FLAGS_WHITE_MOSFET0)) {
127 mosfet(0, 0);
128 }
129 if (config_get_flag(CONFIG_FLAGS_WHITE_MOSFET1)) {
130 mosfet(1, 0);
131 }
132 }
133 }
134}
139static int inline cnt(int idx) {
140 if (fadetarget[idx] > curled[idx]) {
141 if ((fadetarget[idx] - curled[idx]) < 256) {
142 curled[idx] = fadetarget[idx];
143 } else {
144 curled[idx] = curled[idx] + 255;
145 }
146 set_led(curled);
147 return 1;
148 }
149 if (fadetarget[idx] < curled[idx]) {
150 if ((curled[idx] - fadetarget[idx]) < 256) {
151 curled[idx] = fadetarget[idx];
152 } else {
153 curled[idx] = curled[idx] - 256;
154 }
155 set_led(curled);
156 return 1;
157 }
158 return 0;
159}
160
164static void led_timer_irq() {
165 struct ledcolour *lc = get_led_colour();
166
167 if (operation == 1) { // fade
168 return;
169 } else if (operation == 2) { // blink
170 if (ctr > (lc->off + lc->on)) {
171 ctr = 0;
172 }
173 if (ctr == 0) {
174 set_blink_colour(lc->colour, lc->brightness);
175 set_led(blink_colour);
176 } else if (ctr == lc->on) {
177 if (lc->off != 0) {
178 curled[0] = 0;
179 curled[1] = 0;
180 curled[2] = 0;
181 set_led(curled);
182 }
183 }
184 ctr++;
185 } else if (operation == 3) { // flash
186 if (ctr == 0) {
187 set_led(blink_colour);
188 } else if (ctr == lc->on) {
189 set_led(ledoffval);
190 operation = 0;
191 }
192 ctr++;
193 } else if (operation == 4) { // fade to
194 if (isSameRGB(fadetarget, curled)) {
195 operation = 0;
196 return;
197 }
198 // count each byte up or down
199 cnt(0);
200 cnt(1);
201 cnt(2);
202 }
203}
204static void initpin(int pinno) {
205 int r = 0;
206 int pin = curpins->pins[pinno];
207 int timer = curpins->timers[pinno];
208
209 r = mculib_pin_out(MAIN_MCULIBHANDLE, pin, HAL_PIN_FASTEST);
210 printf("LED: Setting pin %i to timer %i\r\n", pin, timer);
211 if (r != 0) {
212 printf("Failed to config pin %i to timer: %\r\n", pin, r);
213 return;
214 }
215 r = mculib_timer_attach_pin_pwm(MAIN_MCULIBHANDLE, timer, pin);
216 if (r != 0) {
217 printf("Failed to attach pin %i to timer: %\r\n", pin, r);
218 return;
219 }
220}
221
222void led_init() {
223 lastledconfig = config_get_flag(CONFIG_FLAGS_LEDEXTERN);
224 ledoffval[0] = 0;
225 ledoffval[1] = 0;
226 ledoffval[2] = 0;
227 printf("Initializing LEDs\r\n");
228 curpins = &intled;
229 int r;
230
231 if (lastledconfig) {
232 mculib_timer_disable(MAIN_MCULIBHANDLE, 3);
233 curpins = &extled;
234 r = mculib_timer_enable_simple(MAIN_MCULIBHANDLE, 2, LED_TIMER_FREQUENCY, &led_timer_irq);
235 if (r != 0) {
236 printf("Failed to init timer for led: %\r\n", r);
237 return;
238 }
239 r = mculib_timer_enable_simple(MAIN_MCULIBHANDLE, 1, LED_TIMER_FREQUENCY, &led_timer_irq);
240 if (r != 0) {
241 printf("Failed to init timer for led: %\r\n", r);
242 return;
243 }
244 } else {
245 mculib_timer_disable(MAIN_MCULIBHANDLE, 1);
246 mculib_timer_disable(MAIN_MCULIBHANDLE, 2);
247 r = mculib_timer_enable_simple(MAIN_MCULIBHANDLE, 3, 300, &led_timer_irq);
248 if (r != 0) {
249 printf("Failed to init timer for led: %\r\n", r);
250 return;
251 }
252 }
253
254 led_set_machine_managed();
255
256 initpin(0);
257 initpin(1);
258 initpin(2);
259
260 if ((r = mculib_pin_out(MAIN_MCULIBHANDLE, 100, HAL_PIN_FASTEST))) {
261 printf("led mosfetinit: failed to set pin %i to out: %i\r\n", 100, r);
262 return;
263 }
264 if ((r = mculib_pin_out(MAIN_MCULIBHANDLE, 101, HAL_PIN_FASTEST))) {
265 printf("led mosfetinit: failed to set pin %i to out: %i\r\n", 101, r);
266 return;
267 }
268}
269
273void led_flash(LED_USAGE_TYPE lut, uint32_t colour, uint32_t duration) {
274 if (lut != led_managed_by) {
275 return;
276 }
277 operation = 0;
278 set_blink_colour(colour, 256);
279 get_led_colour()->on = duration;
280 operation = 3;
281 ctr = 0;
282}
283
288void led_blink(LED_USAGE_TYPE lut, uint32_t colour, uint8_t brightness, uint32_t on, uint32_t off) {
289 led_blink_flags(lut, colour, brightness, on, off, 0);
290}
291void led_blink_flags(LED_USAGE_TYPE lut, uint32_t colour, uint8_t brightness, uint32_t on, uint32_t off, uint32_t flags) {
292 if (lut != led_managed_by) {
293 return;
294 }
295
296 if (flags & LED_FLAG_FADE_TO) {
297 operation = 4;
298 colour_to_array((uint16_t *)&fadetarget, colour, brightness);
299 return;
300 }
301
302 operation = 0;
303 struct ledcolour *lc = get_led_colour();
304
305 lc->colour = colour;
306 lc->brightness = brightness;
307 lc->on = on;
308 lc->off = off;
309 set_blink_colour(lc->colour, lc->brightness);
310 operation = 2;
311 ctr = 0;
312}
313
314void led_print_status() {
315 if (operation == 2) {
316 printf("R=%p, G=%p, B=%p\r\n", (int)blink_colour[0], (int)blink_colour[1], (int)blink_colour[2]);
317 } else {
318 printf("Unprintable operation %i\r\n", operation);
319 }
320}
321
322
323void led_off(LED_USAGE_TYPE lut) {
324 if (lut != led_managed_by) {
325 return;
326 }
327 set_led(ledoffval);
328 operation = 0;
329}
330void led_loop() {
331 do_mosfet = config_get_flag(CONFIG_FLAGS_WHITE_MOSFET0) | config_get_flag(CONFIG_FLAGS_WHITE_MOSFET1);
332
333 if (config_get_flag(CONFIG_FLAGS_LEDEXTERN) != lastledconfig) {
334 led_off(led_managed_by);
335 led_init();
336 }
337
338 // if (lastled == curled) {
339 // return;
340 //}
341 //printf("Led: cur: %p, target: %p, dir=%i\r\n",curled,fadetarget,up);
342 //lastled = curled;
343 lastled++;
344}
345
346void led_set_machine_managed() {
347 led_managed_by = LED_MACHINE;
348}
349void led_set_user_managed() {
350 led_managed_by = LED_USER;
351}
352void led_set_wifi_managed() {
353 led_managed_by = LED_WIFI;
354}
355
356void led_indicate(LED_INDICATOR a) {
357 if (a == LED_POWERUP) {
358 led_blink(a, (uint32_t)0xFFFFFFFF, (uint8_t)50, (uint32_t)50, (uint32_t)100);
359 }
360 // unless it is the reset indicator we do not
361 // display status on leds if they are external
362 if (config_get_flag(CONFIG_FLAGS_LEDEXTERN)) {
363 return;
364 }
365 if (a == LED_FATALERROR) {
366 led_blink(a, (uint32_t)0xFF0000, (uint8_t)50, (uint32_t)50, (uint32_t)100);
367 } else if (a == LED_POWERUP) {
368 led_blink(a, (uint32_t)0x0000FF, (uint8_t)50, (uint32_t)50, (uint32_t)100);
369 } else if (a == LED_RESET) {
370 led_blink(a, (uint32_t)0x010101, (uint8_t)50, (uint32_t)100, (uint32_t)100);
371 } else if (a == LED_FLASHEND) {
372 led_blink(a, (uint32_t)0xFF0000, (uint8_t)255, (uint32_t)10, (uint32_t)300);
373 } else if (a == LED_WIFI_BRIDGE) {
374 led_blink(a, (uint32_t)0xFF0000, (uint8_t)256, (uint32_t)5, (uint32_t)150);
375 } else if (a == LED_WIFI_BRIDGE2) {
376 led_blink(a, (uint32_t)0x00FF00, (uint8_t)256, (uint32_t)5, (uint32_t)150);
377 } else if (a == LED_WIFI_STATION) {
378 // led_blink(LED_MACHINE, 0xFF0000, 255, 10, 300);
379 } else if (a == LED_WIFI_APMODE) {
380 //led_blink(LED_MACHINE, 0xFFFF00, 255, 10, 300);
381 } else if (a == LED_WIFI_CONNECTED) {
382 led_off(LED_MACHINE);
383 } else if (a == LED_POWERSAVE) {
384 led_blink(LED_MACHINE, 0xFFFFFF, 10, 5, 1000);
385 }
386}
void led_flash(LED_USAGE_TYPE lut, uint32_t colour, uint32_t duration)
will flash led once
Definition: led.c:273
void led_blink(LED_USAGE_TYPE lut, uint32_t colour, uint8_t brightness, uint32_t on, uint32_t off)
will keep blinking until told otherwise will repeat endlessly.
Definition: led.c:288
Definition: led.c:46
Definition: led.c:29