CO_LEDs.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * CANopen Indicator specification (CiA 303-3 v1.4.0)
  3. *
  4. * @file CO_LEDs.h
  5. * @ingroup CO_LEDs
  6. * @author Janez Paternoster
  7. * @copyright 2020 Janez Paternoster
  8. *
  9. * This file is part of CANopenNode, an opensource CANopen Stack.
  10. * Project home page is <https://github.com/CANopenNode/CANopenNode>.
  11. * For more information on CANopen see <http://www.can-cia.org/>.
  12. *
  13. * Licensed under the Apache License, Version 2.0 (the "License");
  14. * you may not use this file except in compliance with the License.
  15. * You may obtain a copy of the License at
  16. *
  17. * http://www.apache.org/licenses/LICENSE-2.0
  18. *
  19. * Unless required by applicable law or agreed to in writing, software
  20. * distributed under the License is distributed on an "AS IS" BASIS,
  21. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  22. * See the License for the specific language governing permissions and
  23. * limitations under the License.
  24. */
  25. #include "303/CO_LEDs.h"
  26. #if (CO_CONFIG_LEDS) & CO_CONFIG_LEDS_ENABLE
  27. /******************************************************************************/
  28. CO_ReturnError_t CO_LEDs_init(CO_LEDs_t *LEDs) {
  29. CO_ReturnError_t ret = CO_ERROR_NO;
  30. /* verify arguments */
  31. if (LEDs == NULL) {
  32. return CO_ERROR_ILLEGAL_ARGUMENT;
  33. }
  34. /* clear the object */
  35. memset(LEDs, 0, sizeof(CO_LEDs_t));
  36. return ret;
  37. }
  38. /******************************************************************************/
  39. void CO_LEDs_process(CO_LEDs_t *LEDs,
  40. uint32_t timeDifference_us,
  41. CO_NMT_internalState_t NMTstate,
  42. bool_t LSSconfig,
  43. bool_t ErrCANbusOff,
  44. bool_t ErrCANbusWarn,
  45. bool_t ErrRpdo,
  46. bool_t ErrSync,
  47. bool_t ErrHbCons,
  48. bool_t ErrOther,
  49. bool_t firmwareDownload,
  50. uint32_t *timerNext_us)
  51. {
  52. (void)timerNext_us; /* may be unused */
  53. uint8_t rd = 0;
  54. uint8_t gr = 0;
  55. bool_t tick = false;
  56. LEDs->LEDtmr50ms += timeDifference_us;
  57. while (LEDs->LEDtmr50ms >= 50000) {
  58. bool_t rdFlickerNext = (LEDs->LEDred & CO_LED_flicker) == 0;
  59. tick = true;
  60. LEDs->LEDtmr50ms -= 50000;
  61. if (++LEDs->LEDtmr200ms > 3) {
  62. /* calculate 2,5Hz blinking and flashing */
  63. LEDs->LEDtmr200ms = 0;
  64. rd = gr = 0;
  65. if ((LEDs->LEDred & CO_LED_blink) == 0) rd |= CO_LED_blink;
  66. else gr |= CO_LED_blink;
  67. switch (++LEDs->LEDtmrflash_1) {
  68. case 1: rd |= CO_LED_flash_1; break;
  69. case 2: gr |= CO_LED_flash_1; break;
  70. case 6: LEDs->LEDtmrflash_1 = 0; break;
  71. default: break;
  72. }
  73. switch (++LEDs->LEDtmrflash_2) {
  74. case 1: case 3: rd |= CO_LED_flash_2; break;
  75. case 2: case 4: gr |= CO_LED_flash_2; break;
  76. case 8: LEDs->LEDtmrflash_2 = 0; break;
  77. default: break;
  78. }
  79. switch (++LEDs->LEDtmrflash_3) {
  80. case 1: case 3: case 5: rd |= CO_LED_flash_3; break;
  81. case 2: case 4: case 6: gr |= CO_LED_flash_3; break;
  82. case 10: LEDs->LEDtmrflash_3 = 0; break;
  83. default: break;
  84. }
  85. switch (++LEDs->LEDtmrflash_4) {
  86. case 1: case 3: case 5: case 7: rd |= CO_LED_flash_4; break;
  87. case 2: case 4: case 6: case 8: gr |= CO_LED_flash_4; break;
  88. case 12: LEDs->LEDtmrflash_4 = 0; break;
  89. default: break;
  90. }
  91. }
  92. else {
  93. /* clear flicker and CANopen bits, keep others */
  94. rd = LEDs->LEDred & (0xFF ^ (CO_LED_flicker | CO_LED_CANopen));
  95. gr = LEDs->LEDgreen & (0xFF ^ (CO_LED_flicker | CO_LED_CANopen));
  96. }
  97. /* calculate 10Hz flickering */
  98. if (rdFlickerNext) rd |= CO_LED_flicker;
  99. else gr |= CO_LED_flicker;
  100. } /* while (LEDs->LEDtmr50ms >= 50000) */
  101. if (tick) {
  102. uint8_t rd_co, gr_co;
  103. /* CANopen red ERROR LED */
  104. if (ErrCANbusOff) rd_co = 1;
  105. else if (NMTstate == CO_NMT_INITIALIZING) rd_co = rd & CO_LED_flicker;
  106. else if (ErrRpdo) rd_co = rd & CO_LED_flash_4;
  107. else if (ErrSync) rd_co = rd & CO_LED_flash_3;
  108. else if (ErrHbCons) rd_co = rd & CO_LED_flash_2;
  109. else if (ErrCANbusWarn) rd_co = rd & CO_LED_flash_1;
  110. else if (ErrOther) rd_co = rd & CO_LED_blink;
  111. else rd_co = 0;
  112. /* CANopen green RUN LED */
  113. if (LSSconfig) gr_co = gr & CO_LED_flicker;
  114. else if (firmwareDownload) gr_co = gr & CO_LED_flash_3;
  115. else if (NMTstate == CO_NMT_STOPPED) gr_co = gr & CO_LED_flash_1;
  116. else if (NMTstate == CO_NMT_PRE_OPERATIONAL)gr_co = gr & CO_LED_blink;
  117. else if (NMTstate == CO_NMT_OPERATIONAL) gr_co = 1;
  118. else gr_co = 0;
  119. if (rd_co != 0) rd |= CO_LED_CANopen;
  120. if (gr_co != 0) gr |= CO_LED_CANopen;
  121. LEDs->LEDred = rd;
  122. LEDs->LEDgreen = gr;
  123. } /* if (tick) */
  124. #if (CO_CONFIG_LEDS) & CO_CONFIG_FLAG_TIMERNEXT
  125. if (timerNext_us != NULL) {
  126. uint32_t diff = 50000 - LEDs->LEDtmr50ms;
  127. if (*timerNext_us > diff) {
  128. *timerNext_us = diff;
  129. }
  130. }
  131. #endif
  132. }
  133. #endif /* (CO_CONFIG_LEDS) & CO_CONFIG_LEDS_ENABLE */