1 /*
2 * Copyright (c) 2019 Vestas Wind Systems A/S
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <CANopen.h>
8 #include <canopennode.h>
9
10 struct canopen_leds_state {
11 CO_NMT_t *nmt;
12 canopen_led_callback_t green_cb;
13 void *green_arg;
14 canopen_led_callback_t red_cb;
15 void *red_arg;
16 bool green : 1;
17 bool red : 1;
18 bool program_download : 1;
19 };
20
21 static struct canopen_leds_state canopen_leds;
22
canopen_leds_update(struct k_timer * timer_id)23 static void canopen_leds_update(struct k_timer *timer_id)
24 {
25 bool green = false;
26 bool red = false;
27
28 ARG_UNUSED(timer_id);
29
30 CO_NMT_blinkingProcess50ms(canopen_leds.nmt);
31
32 if (canopen_leds.program_download) {
33 green = LED_TRIPLE_FLASH(canopen_leds.nmt);
34 } else {
35 green = LED_GREEN_RUN(canopen_leds.nmt);
36 }
37
38 red = LED_RED_ERROR(canopen_leds.nmt);
39
40 #ifdef CONFIG_CANOPENNODE_LEDS_BICOLOR
41 if (red && canopen_leds.red_cb) {
42 green = false;
43 }
44 #endif
45
46 if (canopen_leds.green_cb) {
47 if (green != canopen_leds.green) {
48 canopen_leds.green_cb(green, canopen_leds.green_arg);
49 canopen_leds.green = green;
50 }
51 }
52
53 if (canopen_leds.red_cb) {
54 if (red != canopen_leds.red) {
55 canopen_leds.red_cb(red, canopen_leds.red_arg);
56 canopen_leds.red = red;
57 }
58 }
59 }
60
61 K_TIMER_DEFINE(canopen_leds_timer, canopen_leds_update, NULL);
62
canopen_leds_init(CO_NMT_t * nmt,canopen_led_callback_t green_cb,void * green_arg,canopen_led_callback_t red_cb,void * red_arg)63 void canopen_leds_init(CO_NMT_t *nmt,
64 canopen_led_callback_t green_cb, void *green_arg,
65 canopen_led_callback_t red_cb, void *red_arg)
66 {
67 k_timer_stop(&canopen_leds_timer);
68
69 canopen_leds.nmt = nmt;
70
71 /* Call existing callbacks to turn off LEDs */
72 if (canopen_leds.green_cb) {
73 canopen_leds.green_cb(false, canopen_leds.green_arg);
74 }
75 if (canopen_leds.red_cb) {
76 canopen_leds.red_cb(false, canopen_leds.red_arg);
77 }
78
79 canopen_leds.green_cb = green_cb;
80 canopen_leds.green_arg = green_arg;
81 canopen_leds.green = false;
82 canopen_leds.red_cb = red_cb;
83 canopen_leds.red_arg = red_arg;
84 canopen_leds.red = false;
85
86 /* Call new callbacks to turn off LEDs */
87 if (canopen_leds.green_cb) {
88 canopen_leds.green_cb(false, canopen_leds.green_arg);
89 }
90 if (canopen_leds.red_cb) {
91 canopen_leds.red_cb(false, canopen_leds.red_arg);
92 }
93
94 if (nmt && (green_cb || red_cb)) {
95 k_timer_start(&canopen_leds_timer, K_MSEC(50), K_MSEC(50));
96 }
97 }
98
canopen_leds_program_download(bool in_progress)99 void canopen_leds_program_download(bool in_progress)
100 {
101 canopen_leds.program_download = in_progress;
102 }
103