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 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * PD Buddy - USB Power Delivery for everyone
  3. * Copyright (C) 2017 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 medium blink off mode */
  26. #define LED_MEDIUM_BLINKS 3
  27. thread_t *pdb_led_thread;
  28. /*
  29. * LED blinker thread.
  30. */
  31. static THD_WORKING_AREA(waLED, 128);
  32. static THD_FUNCTION(LED, arg) {
  33. (void) arg;
  34. /* LED starts turned off */
  35. eventmask_t state = PDB_EVT_LED_OFF;
  36. /* The event just received */
  37. eventmask_t newstate;
  38. /* Timeout. TIME_INFINITE for steady modes, other values for blinking
  39. * modes. */
  40. systime_t timeout = TIME_INFINITE;
  41. /* Counter for blinking modes */
  42. int i = 0;
  43. while (true) {
  44. /* Wait for any event except the last one we saw */
  45. newstate = chEvtWaitOneTimeout(ALL_EVENTS & ~state, timeout);
  46. /* If we're changing state, reset the counter */
  47. if (newstate != 0) {
  48. /* Clear the events to make sure we don't get an unexpected state
  49. * change. As an example of such an unexpected state change, if we
  50. * set the state to ON, then ON, then BLINK, the second ON wouldn't
  51. * be seen until after we handled the BLINK event, causing us to
  52. * end up in the ON state in the end. */
  53. chEvtGetAndClearEvents(ALL_EVENTS);
  54. state = newstate;
  55. i = 0;
  56. }
  57. switch (state) {
  58. case PDB_EVT_LED_OFF:
  59. timeout = TIME_INFINITE;
  60. palClearLine(LINE_LED);
  61. break;
  62. case PDB_EVT_LED_ON:
  63. timeout = TIME_INFINITE;
  64. palSetLine(LINE_LED);
  65. break;
  66. case PDB_EVT_LED_FAST_BLINK:
  67. timeout = LED_FAST;
  68. if (i == 0) {
  69. palSetLine(LINE_LED);
  70. } else {
  71. palToggleLine(LINE_LED);
  72. }
  73. break;
  74. case PDB_EVT_LED_MEDIUM_BLINK_OFF:
  75. timeout = LED_MEDIUM;
  76. if (i == 0) {
  77. palSetLine(LINE_LED);
  78. } else if (i < (LED_MEDIUM_BLINKS * 2) - 1) {
  79. palToggleLine(LINE_LED);
  80. } else {
  81. palClearLine(LINE_LED);
  82. timeout = TIME_INFINITE;
  83. }
  84. break;
  85. case PDB_EVT_LED_SLOW_BLINK:
  86. timeout = LED_SLOW;
  87. if (i == 0) {
  88. palSetLine(LINE_LED);
  89. } else {
  90. palToggleLine(LINE_LED);
  91. }
  92. break;
  93. default:
  94. break;
  95. }
  96. /* Increment the counter for the blinking modes */
  97. i++;
  98. }
  99. }
  100. void pdb_led_run(void)
  101. {
  102. pdb_led_thread = chThdCreateStatic(waLED, sizeof(waLED), PDB_PRIO_LED, LED,
  103. NULL);
  104. }