suspend.c 3.6 KB

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