AP_BoardLED2.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  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_BoardLED2.h"
  14. #include "AP_Notify.h"
  15. // show all status on only 2 leds
  16. #if defined(HAL_GPIO_A_LED_PIN) && defined(HAL_GPIO_B_LED_PIN)
  17. static_assert((HAL_GPIO_A_LED_PIN != HAL_GPIO_B_LED_PIN), "Duplicate LED assignments detected");
  18. extern const AP_HAL::HAL& hal;
  19. bool AP_BoardLED2::init(void)
  20. {
  21. // setup the main LEDs as outputs
  22. hal.gpio->pinMode(HAL_GPIO_A_LED_PIN, HAL_GPIO_OUTPUT);
  23. hal.gpio->pinMode(HAL_GPIO_B_LED_PIN, HAL_GPIO_OUTPUT);
  24. // turn all lights off
  25. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  26. hal.gpio->write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_OFF);
  27. _sat_cnt=0;
  28. save_trim_counter = 0;
  29. arm_counter = 0;
  30. return true;
  31. }
  32. /*
  33. main update function called at 50Hz
  34. */
  35. void AP_BoardLED2::update(void)
  36. {
  37. _counter++;
  38. // we never want to update LEDs at a higher than 16Hz rate
  39. if (_counter % 3 != 0) {
  40. return;
  41. }
  42. // counter2 used to drop frequency down to 16hz
  43. uint8_t counter2 = _counter / 3;
  44. // initialising
  45. if (AP_Notify::flags.initialising) {
  46. // blink LEDs A at 8Hz (full cycle) during initialisation
  47. hal.gpio->write(HAL_GPIO_A_LED_PIN, (counter2 & 1) ? HAL_GPIO_LED_ON : HAL_GPIO_LED_OFF);
  48. return;
  49. }
  50. if ((counter2 & 0x2) == 0) {
  51. save_trim_counter++;
  52. }
  53. bool led_a_used=false;
  54. // save trim and ESC calibration
  55. if (AP_Notify::flags.save_trim || AP_Notify::flags.esc_calibration) {
  56. switch(save_trim_counter) {
  57. case 0:
  58. hal.gpio->write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_OFF);
  59. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON);
  60. break;
  61. case 1:
  62. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  63. hal.gpio->write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_ON);
  64. break;
  65. default:
  66. save_trim_counter = -1;
  67. break;
  68. }
  69. return;
  70. }
  71. if(AP_Notify::flags.compass_cal_running){ // compass calibration
  72. switch(save_trim_counter) {
  73. case 0:
  74. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON); // short blinks by both LEDs
  75. hal.gpio->write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_ON);
  76. break;
  77. case 1:
  78. case 2:
  79. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  80. hal.gpio->write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_OFF);
  81. break;
  82. case 3:
  83. case 4:
  84. case 5:
  85. case 6:
  86. case 7:
  87. break;
  88. default:
  89. // reset counter to restart the sequence
  90. save_trim_counter = -1;
  91. break;
  92. }
  93. return;
  94. }
  95. if(AP_Notify::events.autotune_complete){
  96. switch(save_trim_counter) {
  97. case 0:
  98. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON); // short darkening
  99. break;
  100. case 1:
  101. case 2:
  102. case 3:
  103. case 4:
  104. case 5:
  105. case 6:
  106. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  107. break;
  108. case 7:
  109. break;
  110. default:
  111. // reset counter to restart the sequence
  112. save_trim_counter = -1;
  113. break;
  114. }
  115. led_a_used=true;
  116. }
  117. if(AP_Notify::events.autotune_failed){
  118. switch(save_trim_counter) {
  119. case 0:
  120. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON); // short double darkening
  121. break;
  122. case 1:
  123. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  124. break;
  125. case 2:
  126. case 3:
  127. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON);
  128. break;
  129. case 4:
  130. case 5:
  131. case 6:
  132. case 7:
  133. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  134. break;
  135. default:
  136. // reset counter to restart the sequence
  137. save_trim_counter = -1;
  138. break;
  139. }
  140. led_a_used=true;
  141. }
  142. // arming light
  143. if(!led_a_used) {
  144. if (AP_Notify::flags.armed) {
  145. if(AP_Notify::flags.failsafe_battery){// blink slowly (around 2Hz)
  146. if ((counter2 & 0x7) == 0) {
  147. hal.gpio->toggle(HAL_GPIO_A_LED_PIN);
  148. }
  149. }else if(AP_Notify::flags.failsafe_radio){// blink fast (around 4Hz)
  150. if ((counter2 & 0x3) == 0) {
  151. hal.gpio->toggle(HAL_GPIO_A_LED_PIN);
  152. }
  153. } else {
  154. // ARM led solid
  155. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON);
  156. }
  157. }else{
  158. if ((counter2 & 0x2) == 0) {
  159. arm_counter++;
  160. }
  161. if (AP_Notify::flags.pre_arm_check) {
  162. // passed pre-arm checks so slower single flash
  163. switch(arm_counter) {
  164. case 0:
  165. case 1:
  166. case 2:
  167. case 3:
  168. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON);
  169. break;
  170. case 4:
  171. case 5:
  172. case 6:
  173. case 7:
  174. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  175. break;
  176. default:
  177. // reset counter to restart the sequence
  178. arm_counter = -1;
  179. break;
  180. }
  181. }else{
  182. // failed pre-arm checks so double flash
  183. switch(arm_counter) {
  184. case 0:
  185. case 1:
  186. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON);
  187. break;
  188. case 2:
  189. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  190. break;
  191. case 3:
  192. case 4:
  193. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_ON);
  194. break;
  195. case 5:
  196. case 6:
  197. case 7: // add one tick to do period be a multiple of the second
  198. hal.gpio->write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
  199. break;
  200. default:
  201. arm_counter = -1;
  202. break;
  203. }
  204. }
  205. }
  206. }
  207. // gps light
  208. switch (AP_Notify::flags.gps_status) {
  209. case 0:
  210. case 1:
  211. // no GPS attached or no lock - be dark
  212. hal.gpio->write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_OFF);
  213. break;
  214. case 2: // 2d lock
  215. case 3:// 3d lock
  216. default: // show number of sats
  217. if ((counter2 & 0x2) == 0) {
  218. _sat_cnt++;
  219. }
  220. uint16_t sats = AP_Notify::flags.gps_num_sats;
  221. if(_sat_cnt<8) { // pause between pulses
  222. hal.gpio->write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_OFF);
  223. } else if(_sat_cnt< (8 + (sats-6)*2) ) {
  224. hal.gpio->toggle(HAL_GPIO_B_LED_PIN); // 2Hz
  225. } else {
  226. _sat_cnt=-1;
  227. }
  228. break;
  229. }
  230. }
  231. #else
  232. bool AP_BoardLED2::init(void) {return true;}
  233. void AP_BoardLED2::update(void) {return;}
  234. #endif