AP_BoardLED.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. #include "AP_BoardLED.h"
  14. #include "AP_Notify.h"
  15. #if (defined(HAL_GPIO_A_LED_PIN) && defined(HAL_GPIO_B_LED_PIN) && \
  16. defined(HAL_GPIO_C_LED_PIN))
  17. static_assert((HAL_GPIO_A_LED_PIN != HAL_GPIO_B_LED_PIN) &&
  18. (HAL_GPIO_A_LED_PIN != HAL_GPIO_C_LED_PIN) &&
  19. (HAL_GPIO_B_LED_PIN != HAL_GPIO_C_LED_PIN), "Duplicate LED assignments detected");
  20. extern const AP_HAL::HAL& hal;
  21. bool AP_BoardLED::init(void)
  22. {
  23. // setup the main LEDs as outputs
  24. hal.gpio->pinMode(HAL_GPIO_A_LED_PIN, HAL_GPIO_OUTPUT);
  25. hal.gpio->pinMode(HAL_GPIO_B_LED_PIN, HAL_GPIO_OUTPUT);
  26. hal.gpio->pinMode(HAL_GPIO_C_LED_PIN, HAL_GPIO_OUTPUT);
  27. // turn all lights off
  28. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  29. hal.gpio->write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_OFF);
  30. hal.gpio->write(HAL_GPIO_C_LED_PIN, HAL_GPIO_LED_OFF);
  31. return true;
  32. }
  33. /*
  34. main update function called at 50Hz
  35. */
  36. void AP_BoardLED::update(void)
  37. {
  38. _counter++;
  39. // we never want to update LEDs at a higher than 16Hz rate
  40. if (_counter % 3 != 0) {
  41. return;
  42. }
  43. // counter2 used to drop frequency down to 16hz
  44. uint8_t counter2 = _counter / 3;
  45. // initialising
  46. if (AP_Notify::flags.initialising) {
  47. // blink LEDs A and C at 8Hz (full cycle) during initialisation
  48. hal.gpio->write(HAL_GPIO_A_LED_PIN, (counter2 & 1) ? HAL_GPIO_LED_ON : HAL_GPIO_LED_OFF);
  49. hal.gpio->write(HAL_GPIO_C_LED_PIN, (counter2 & 1) ? HAL_GPIO_LED_OFF : HAL_GPIO_LED_ON);
  50. return;
  51. }
  52. // save trim and ESC calibration
  53. if (AP_Notify::flags.save_trim || AP_Notify::flags.esc_calibration) {
  54. static uint8_t save_trim_counter = 0;
  55. if ((counter2 & 0x2) == 0) {
  56. save_trim_counter++;
  57. }
  58. switch(save_trim_counter) {
  59. case 0:
  60. hal.gpio->write(HAL_GPIO_C_LED_PIN, HAL_GPIO_LED_OFF);
  61. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON);
  62. break;
  63. case 1:
  64. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  65. hal.gpio->write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_ON);
  66. break;
  67. case 2:
  68. hal.gpio->write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_OFF);
  69. hal.gpio->write(HAL_GPIO_C_LED_PIN, HAL_GPIO_LED_ON);
  70. break;
  71. default:
  72. save_trim_counter = -1;
  73. break;
  74. }
  75. return;
  76. }
  77. // arming light
  78. static uint8_t arm_counter = 0;
  79. if (AP_Notify::flags.armed) {
  80. // red led solid
  81. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON);
  82. }else{
  83. if ((counter2 & 0x2) == 0) {
  84. arm_counter++;
  85. }
  86. if (AP_Notify::flags.pre_arm_check) {
  87. // passed pre-arm checks so slower single flash
  88. switch(arm_counter) {
  89. case 0:
  90. case 1:
  91. case 2:
  92. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON);
  93. break;
  94. case 3:
  95. case 4:
  96. case 5:
  97. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  98. break;
  99. default:
  100. // reset counter to restart the sequence
  101. arm_counter = -1;
  102. break;
  103. }
  104. }else{
  105. // failed pre-arm checks so double flash
  106. switch(arm_counter) {
  107. case 0:
  108. case 1:
  109. case 3:
  110. case 4:
  111. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON);
  112. break;
  113. case 2:
  114. case 5:
  115. case 6:
  116. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  117. break;
  118. default:
  119. arm_counter = -1;
  120. break;
  121. }
  122. }
  123. }
  124. // gps light
  125. switch (AP_Notify::flags.gps_status) {
  126. case 0:
  127. // no GPS attached
  128. hal.gpio->write(HAL_GPIO_C_LED_PIN, HAL_GPIO_LED_OFF);
  129. break;
  130. case 1:
  131. // GPS attached but no lock, blink at 4Hz
  132. if ((counter2 & 0x3) == 0) {
  133. hal.gpio->toggle(HAL_GPIO_C_LED_PIN);
  134. }
  135. break;
  136. case 2:
  137. // GPS attached but 2D lock, blink more slowly (around 2Hz)
  138. if ((counter2 & 0x7) == 0) {
  139. hal.gpio->toggle(HAL_GPIO_C_LED_PIN);
  140. }
  141. break;
  142. default:
  143. // solid blue on gps lock
  144. hal.gpio->write(HAL_GPIO_C_LED_PIN, HAL_GPIO_LED_ON);
  145. break;
  146. }
  147. }
  148. #else
  149. bool AP_BoardLED::init(void) {return true;}
  150. void AP_BoardLED::update(void) {return;}
  151. #endif