suspend.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /* TODO */
  2. #include <ch.h>
  3. #include <hal.h>
  4. #include "matrix.h"
  5. #include "action.h"
  6. #include "action_util.h"
  7. #include "mousekey.h"
  8. #include "host.h"
  9. #include "suspend.h"
  10. #include "led.h"
  11. #include "wait.h"
  12. #ifdef AUDIO_ENABLE
  13. # include "audio.h"
  14. #endif /* AUDIO_ENABLE */
  15. #ifdef BACKLIGHT_ENABLE
  16. # include "backlight.h"
  17. #endif
  18. #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
  19. # include "rgblight.h"
  20. #endif
  21. #ifdef LED_MATRIX_ENABLE
  22. # include "led_matrix.h"
  23. #endif
  24. #ifdef RGB_MATRIX_ENABLE
  25. # include "rgb_matrix.h"
  26. #endif
  27. /** \brief suspend idle
  28. *
  29. * FIXME: needs doc
  30. */
  31. void suspend_idle(uint8_t time) {
  32. // TODO: this is not used anywhere - what units is 'time' in?
  33. wait_ms(time);
  34. }
  35. /** \brief Run keyboard level Power down
  36. *
  37. * FIXME: needs doc
  38. */
  39. __attribute__((weak)) void suspend_power_down_user(void) {}
  40. /** \brief Run keyboard level Power down
  41. *
  42. * FIXME: needs doc
  43. */
  44. __attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); }
  45. /** \brief suspend power down
  46. *
  47. * FIXME: needs doc
  48. */
  49. void suspend_power_down(void) {
  50. #ifdef BACKLIGHT_ENABLE
  51. backlight_set(0);
  52. #endif
  53. #ifdef LED_MATRIX_ENABLE
  54. led_matrix_task();
  55. #endif
  56. #ifdef RGB_MATRIX_ENABLE
  57. rgb_matrix_task();
  58. #endif
  59. // Turn off LED indicators
  60. uint8_t leds_off = 0;
  61. #if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
  62. if (is_backlight_enabled()) {
  63. // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
  64. leds_off |= (1 << USB_LED_CAPS_LOCK);
  65. }
  66. #endif
  67. led_set(leds_off);
  68. // TODO: figure out what to power down and how
  69. // shouldn't power down TPM/FTM if we want a breathing LED
  70. // also shouldn't power down USB
  71. #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
  72. rgblight_suspend();
  73. #endif
  74. #if defined(LED_MATRIX_ENABLE)
  75. led_matrix_set_suspend_state(true);
  76. #endif
  77. #if defined(RGB_MATRIX_ENABLE)
  78. rgb_matrix_set_suspend_state(true);
  79. #endif
  80. #ifdef AUDIO_ENABLE
  81. stop_all_notes();
  82. #endif /* AUDIO_ENABLE */
  83. suspend_power_down_kb();
  84. // on AVR, this enables the watchdog for 15ms (max), and goes to
  85. // SLEEP_MODE_PWR_DOWN
  86. wait_ms(17);
  87. }
  88. /** \brief suspend wakeup condition
  89. *
  90. * FIXME: needs doc
  91. */
  92. __attribute__((weak)) void matrix_power_up(void) {}
  93. __attribute__((weak)) void matrix_power_down(void) {}
  94. bool suspend_wakeup_condition(void) {
  95. matrix_power_up();
  96. matrix_scan();
  97. matrix_power_down();
  98. for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
  99. if (matrix_get_row(r)) return true;
  100. }
  101. return false;
  102. }
  103. /** \brief run user level code immediately after wakeup
  104. *
  105. * FIXME: needs doc
  106. */
  107. __attribute__((weak)) void suspend_wakeup_init_user(void) {}
  108. /** \brief run keyboard level code immediately after wakeup
  109. *
  110. * FIXME: needs doc
  111. */
  112. __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
  113. /** \brief suspend wakeup condition
  114. *
  115. * run immediately after wakeup
  116. * FIXME: needs doc
  117. */
  118. void suspend_wakeup_init(void) {
  119. // clear keyboard state
  120. // need to do it manually, because we're running from ISR
  121. // and clear_keyboard() calls print
  122. // so only clear the variables in memory
  123. // the reports will be sent from main.c afterwards
  124. // or if the PC asks for GET_REPORT
  125. clear_mods();
  126. clear_weak_mods();
  127. clear_keys();
  128. #ifdef MOUSEKEY_ENABLE
  129. mousekey_clear();
  130. #endif /* MOUSEKEY_ENABLE */
  131. #ifdef EXTRAKEY_ENABLE
  132. host_system_send(0);
  133. host_consumer_send(0);
  134. #endif /* EXTRAKEY_ENABLE */
  135. #ifdef BACKLIGHT_ENABLE
  136. backlight_init();
  137. #endif /* BACKLIGHT_ENABLE */
  138. led_set(host_keyboard_leds());
  139. #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
  140. rgblight_wakeup();
  141. #endif
  142. #if defined(LED_MATRIX_ENABLE)
  143. led_matrix_set_suspend_state(false);
  144. #endif
  145. #if defined(RGB_MATRIX_ENABLE)
  146. rgb_matrix_set_suspend_state(false);
  147. #endif
  148. suspend_wakeup_init_kb();
  149. }