Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
Este repositório está arquivado. Você pode visualizar os arquivos e realizar clone, mas não poderá realizar push nem abrir issues e pull requests.

11 anos atrás
11 anos atrás
11 anos atrás
11 anos atrás
11 anos atrás
11 anos atrás
11 anos atrás
11 anos atrás
11 anos atrás
11 anos atrás
11 anos atrás
11 anos atrás
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #include <stdbool.h>
  2. #include <avr/sleep.h>
  3. #include <avr/wdt.h>
  4. #include <avr/interrupt.h>
  5. #include "matrix.h"
  6. #include "action.h"
  7. #include "backlight.h"
  8. #include "softpwm_led.h"
  9. #include "suspend_avr.h"
  10. #include "suspend.h"
  11. #include "timer.h"
  12. #ifdef PROTOCOL_LUFA
  13. #include "lufa.h"
  14. #endif
  15. #define wdt_intr_enable(value) \
  16. __asm__ __volatile__ ( \
  17. "in __tmp_reg__,__SREG__" "\n\t" \
  18. "cli" "\n\t" \
  19. "wdr" "\n\t" \
  20. "sts %0,%1" "\n\t" \
  21. "out __SREG__,__tmp_reg__" "\n\t" \
  22. "sts %0,%2" "\n\t" \
  23. : /* no outputs */ \
  24. : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
  25. "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
  26. "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
  27. _BV(WDIE) | (value & 0x07)) ) \
  28. : "r0" \
  29. )
  30. void suspend_idle(uint8_t time)
  31. {
  32. cli();
  33. set_sleep_mode(SLEEP_MODE_IDLE);
  34. sleep_enable();
  35. sei();
  36. sleep_cpu();
  37. sleep_disable();
  38. }
  39. /* Power down MCU with watchdog timer
  40. * wdto: watchdog timer timeout defined in <avr/wdt.h>
  41. * WDTO_15MS
  42. * WDTO_30MS
  43. * WDTO_60MS
  44. * WDTO_120MS
  45. * WDTO_250MS
  46. * WDTO_500MS
  47. * WDTO_1S
  48. * WDTO_2S
  49. * WDTO_4S
  50. * WDTO_8S
  51. */
  52. static uint8_t wdt_timeout = 0;
  53. static void power_down(uint8_t wdto)
  54. {
  55. #ifdef PROTOCOL_LUFA
  56. if (USB_DeviceState == DEVICE_STATE_Configured) return;
  57. #endif
  58. wdt_timeout = wdto;
  59. // Watchdog Interrupt Mode
  60. wdt_intr_enable(wdto);
  61. // TODO: more power saving
  62. // See PicoPower application note
  63. // - I/O port input with pullup
  64. // - prescale clock
  65. // - BOD disable
  66. // - Power Reduction Register PRR
  67. #ifdef SUSPEND_ACTION
  68. suspend_power_down_action();
  69. #endif
  70. #ifdef SOFTPWM_LED_ENABLE
  71. softpwm_led_disable();
  72. #endif
  73. set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  74. sleep_enable();
  75. sei();
  76. sleep_cpu();
  77. sleep_disable();
  78. // Disable watchdog after sleep
  79. wdt_disable();
  80. }
  81. void suspend_power_down(void)
  82. {
  83. power_down(WDTO_15MS);
  84. }
  85. bool suspend_wakeup_condition(void)
  86. {
  87. matrix_power_up();
  88. matrix_scan();
  89. matrix_power_down();
  90. for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
  91. if (matrix_get_row(r)) return true;
  92. }
  93. return false;
  94. }
  95. // run immediately after wakeup
  96. void suspend_wakeup_init(void)
  97. {
  98. // clear keyboard state
  99. clear_keyboard();
  100. #ifdef SUSPEND_ACTION
  101. suspend_wakeup_init_action();
  102. #endif
  103. #ifdef BACKLIGHT_ENABLE
  104. backlight_init();
  105. #endif
  106. }
  107. #ifndef NO_SUSPEND_POWER_DOWN
  108. /* watchdog timeout */
  109. ISR(WDT_vect)
  110. {
  111. // compensate timer for sleep
  112. switch (wdt_timeout) {
  113. case WDTO_15MS:
  114. timer_count += 15 + 2; // WDTO_15MS + 2(from observation)
  115. break;
  116. default:
  117. ;
  118. }
  119. }
  120. #endif
  121. #ifdef SUSPEND_ACTION
  122. __attribute__ ((weak))
  123. void suspend_power_down_action(void)
  124. {
  125. }
  126. __attribute__ ((weak))
  127. void suspend_wakeup_init_action(void)
  128. {
  129. }
  130. #endif