PD Buddy Sink Firmware
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

led.c 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /*
  2. * PD Buddy Sink Firmware - Smart power jack for USB Power Delivery
  3. * Copyright (C) 2017-2018 Clayton G. Hobbs <clay@lakeserv.net>
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "led.h"
  19. #include <hal.h>
  20. #include "priorities.h"
  21. /* Delays for blink modes */
  22. #define LED_FAST MS2ST(125)
  23. #define LED_MEDIUM MS2ST(250)
  24. #define LED_SLOW MS2ST(500)
  25. /* Number of blinks for temporary modes */
  26. #define LED_MEDIUM_BLINKS 3
  27. #define LED_FAST_BLINKS 8
  28. thread_t *pdbs_led_thread;
  29. /*
  30. * LED blinker thread.
  31. */
  32. static THD_WORKING_AREA(waLED, 128);
  33. static THD_FUNCTION(LED, arg) {
  34. (void) arg;
  35. /* LED starts turned off */
  36. eventmask_t state = PDBS_EVT_LED_OFF;
  37. /* The event just received */
  38. eventmask_t newstate;
  39. /* Timeout. TIME_INFINITE for steady modes, other values for blinking
  40. * modes. */
  41. systime_t timeout = TIME_INFINITE;
  42. /* Counter for blinking modes */
  43. int i = 0;
  44. while (true) {
  45. /* Wait for any event except the last one we saw */
  46. newstate = chEvtWaitOneTimeout(ALL_EVENTS & ~state, timeout);
  47. /* If we're changing state, reset the counter */
  48. if (newstate != 0) {
  49. /* Clear the events to make sure we don't get an unexpected state
  50. * change. As an example of such an unexpected state change, if we
  51. * set the state to ON, then ON, then BLINK, the second ON wouldn't
  52. * be seen until after we handled the BLINK event, causing us to
  53. * end up in the ON state in the end. */
  54. chEvtGetAndClearEvents(ALL_EVENTS);
  55. state = newstate;
  56. i = 0;
  57. }
  58. switch (state) {
  59. case PDBS_EVT_LED_OFF:
  60. timeout = TIME_INFINITE;
  61. palClearLine(LINE_LED);
  62. break;
  63. case PDBS_EVT_LED_ON:
  64. timeout = TIME_INFINITE;
  65. palSetLine(LINE_LED);
  66. break;
  67. case PDBS_EVT_LED_FAST_BLINK:
  68. timeout = LED_FAST;
  69. if (i == 0) {
  70. palSetLine(LINE_LED);
  71. } else {
  72. palToggleLine(LINE_LED);
  73. }
  74. break;
  75. case PDBS_EVT_LED_MEDIUM_BLINK_OFF:
  76. timeout = LED_MEDIUM;
  77. if (i == 0) {
  78. palSetLine(LINE_LED);
  79. } else if (i < (LED_MEDIUM_BLINKS * 2) - 1) {
  80. palToggleLine(LINE_LED);
  81. } else {
  82. palClearLine(LINE_LED);
  83. timeout = TIME_INFINITE;
  84. }
  85. break;
  86. case PDBS_EVT_LED_SLOW_BLINK:
  87. timeout = LED_SLOW;
  88. if (i == 0) {
  89. palSetLine(LINE_LED);
  90. } else {
  91. palToggleLine(LINE_LED);
  92. }
  93. break;
  94. case PDBS_EVT_LED_FAST_BLINK_SLOW:
  95. timeout = LED_FAST;
  96. if (i == 0) {
  97. palSetLine(LINE_LED);
  98. } else if (i < (LED_FAST_BLINKS * 2)) {
  99. palToggleLine(LINE_LED);
  100. } else {
  101. palClearLine(LINE_LED);
  102. timeout = TIME_INFINITE;
  103. chEvtSignal(pdbs_led_thread, PDBS_EVT_LED_SLOW_BLINK);
  104. }
  105. break;
  106. default:
  107. break;
  108. }
  109. /* Increment the counter for the blinking modes */
  110. i++;
  111. }
  112. }
  113. void pdbs_led_run(void)
  114. {
  115. pdbs_led_thread = chThdCreateStatic(waLED, sizeof(waLED), PDBS_PRIO_LED,
  116. LED, NULL);
  117. }