| /* |
| * Copyright (c) 2019 Vestas Wind Systems A/S |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <CANopen.h> |
| #include <canopennode.h> |
| |
| struct canopen_leds_state { |
| CO_NMT_t *nmt; |
| canopen_led_callback_t green_cb; |
| void *green_arg; |
| canopen_led_callback_t red_cb; |
| void *red_arg; |
| bool green : 1; |
| bool red : 1; |
| bool program_download : 1; |
| }; |
| |
| static struct canopen_leds_state canopen_leds; |
| |
| static void canopen_leds_update(struct k_timer *timer_id) |
| { |
| bool green = false; |
| bool red = false; |
| |
| ARG_UNUSED(timer_id); |
| |
| CO_NMT_blinkingProcess50ms(canopen_leds.nmt); |
| |
| if (canopen_leds.program_download) { |
| green = LED_TRIPLE_FLASH(canopen_leds.nmt); |
| } else { |
| green = LED_GREEN_RUN(canopen_leds.nmt); |
| } |
| |
| red = LED_RED_ERROR(canopen_leds.nmt); |
| |
| #ifdef CONFIG_CANOPENNODE_LEDS_BICOLOR |
| if (red && canopen_leds.red_cb) { |
| green = false; |
| } |
| #endif |
| |
| if (canopen_leds.green_cb) { |
| if (green != canopen_leds.green) { |
| canopen_leds.green_cb(green, canopen_leds.green_arg); |
| canopen_leds.green = green; |
| } |
| } |
| |
| if (canopen_leds.red_cb) { |
| if (red != canopen_leds.red) { |
| canopen_leds.red_cb(red, canopen_leds.red_arg); |
| canopen_leds.red = red; |
| } |
| } |
| } |
| |
| K_TIMER_DEFINE(canopen_leds_timer, canopen_leds_update, NULL); |
| |
| void 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) |
| { |
| k_timer_stop(&canopen_leds_timer); |
| |
| canopen_leds.nmt = nmt; |
| |
| /* Call existing callbacks to turn off LEDs */ |
| if (canopen_leds.green_cb) { |
| canopen_leds.green_cb(false, canopen_leds.green_arg); |
| } |
| if (canopen_leds.red_cb) { |
| canopen_leds.red_cb(false, canopen_leds.red_arg); |
| } |
| |
| canopen_leds.green_cb = green_cb; |
| canopen_leds.green_arg = green_arg; |
| canopen_leds.green = false; |
| canopen_leds.red_cb = red_cb; |
| canopen_leds.red_arg = red_arg; |
| canopen_leds.red = false; |
| |
| /* Call new callbacks to turn off LEDs */ |
| if (canopen_leds.green_cb) { |
| canopen_leds.green_cb(false, canopen_leds.green_arg); |
| } |
| if (canopen_leds.red_cb) { |
| canopen_leds.red_cb(false, canopen_leds.red_arg); |
| } |
| |
| if (nmt && (green_cb || red_cb)) { |
| k_timer_start(&canopen_leds_timer, K_MSEC(50), K_MSEC(50)); |
| } |
| } |
| |
| void canopen_leds_program_download(bool in_progress) |
| { |
| canopen_leds.program_download = in_progress; |
| } |