suspend.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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. # ifdef RGBLIGHT_ANIMATIONS
  48. rgblight_timer_disable();
  49. # endif
  50. if (!is_suspended) {
  51. is_suspended = true;
  52. rgblight_enabled = rgblight_config.enable;
  53. rgblight_disable_noeeprom();
  54. }
  55. #endif
  56. suspend_power_down_kb();
  57. // on AVR, this enables the watchdog for 15ms (max), and goes to
  58. // SLEEP_MODE_PWR_DOWN
  59. wait_ms(17);
  60. }
  61. /** \brief suspend wakeup condition
  62. *
  63. * FIXME: needs doc
  64. */
  65. __attribute__((weak)) void matrix_power_up(void) {}
  66. __attribute__((weak)) void matrix_power_down(void) {}
  67. bool suspend_wakeup_condition(void) {
  68. matrix_power_up();
  69. matrix_scan();
  70. matrix_power_down();
  71. for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
  72. if (matrix_get_row(r)) return true;
  73. }
  74. return false;
  75. }
  76. /** \brief run user level code immediately after wakeup
  77. *
  78. * FIXME: needs doc
  79. */
  80. __attribute__((weak)) void suspend_wakeup_init_user(void) {}
  81. /** \brief run keyboard level code immediately after wakeup
  82. *
  83. * FIXME: needs doc
  84. */
  85. __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_user(); }
  86. /** \brief suspend wakeup condition
  87. *
  88. * run immediately after wakeup
  89. * FIXME: needs doc
  90. */
  91. void suspend_wakeup_init(void) {
  92. // clear keyboard state
  93. // need to do it manually, because we're running from ISR
  94. // and clear_keyboard() calls print
  95. // so only clear the variables in memory
  96. // the reports will be sent from main.c afterwards
  97. // or if the PC asks for GET_REPORT
  98. clear_mods();
  99. clear_weak_mods();
  100. clear_keys();
  101. #ifdef MOUSEKEY_ENABLE
  102. mousekey_clear();
  103. #endif /* MOUSEKEY_ENABLE */
  104. #ifdef EXTRAKEY_ENABLE
  105. host_system_send(0);
  106. host_consumer_send(0);
  107. #endif /* EXTRAKEY_ENABLE */
  108. #ifdef BACKLIGHT_ENABLE
  109. backlight_init();
  110. #endif /* BACKLIGHT_ENABLE */
  111. #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
  112. is_suspended = false;
  113. if (rgblight_enabled) {
  114. rgblight_enable_noeeprom();
  115. }
  116. # ifdef RGBLIGHT_ANIMATIONS
  117. rgblight_timer_enable();
  118. # endif
  119. #endif
  120. suspend_wakeup_init_kb();
  121. }