canopen_leds.c 2.2 KB

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