suspend.c 3.1 KB

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