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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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 "suspend_avr.h"
  9. #include "suspend.h"
  10. #ifdef PROTOCOL_LUFA
  11. #include "lufa.h"
  12. #endif
  13. #define wdt_intr_enable(value) \
  14. __asm__ __volatile__ ( \
  15. "in __tmp_reg__,__SREG__" "\n\t" \
  16. "cli" "\n\t" \
  17. "wdr" "\n\t" \
  18. "sts %0,%1" "\n\t" \
  19. "out __SREG__,__tmp_reg__" "\n\t" \
  20. "sts %0,%2" "\n\t" \
  21. : /* no outputs */ \
  22. : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \
  23. "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \
  24. "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \
  25. _BV(WDIE) | (value & 0x07)) ) \
  26. : "r0" \
  27. )
  28. void suspend_idle(uint8_t time)
  29. {
  30. cli();
  31. set_sleep_mode(SLEEP_MODE_IDLE);
  32. sleep_enable();
  33. sei();
  34. sleep_cpu();
  35. sleep_disable();
  36. }
  37. /* Power down MCU with watchdog timer
  38. * wdto: watchdog timer timeout defined in <avr/wdt.h>
  39. * WDTO_15MS
  40. * WDTO_30MS
  41. * WDTO_60MS
  42. * WDTO_120MS
  43. * WDTO_250MS
  44. * WDTO_500MS
  45. * WDTO_1S
  46. * WDTO_2S
  47. * WDTO_4S
  48. * WDTO_8S
  49. */
  50. void suspend_power_down(uint8_t wdto)
  51. {
  52. #ifdef PROTOCOL_LUFA
  53. if (USB_DeviceState == DEVICE_STATE_Configured) return;
  54. #endif
  55. // Watchdog Interrupt Mode
  56. wdt_intr_enable(wdto);
  57. // TODO: more power saving
  58. // See PicoPower application note
  59. // - I/O port input with pullup
  60. // - prescale clock
  61. // - BOD disable
  62. // - Power Reduction Register PRR
  63. set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  64. sleep_enable();
  65. sei();
  66. sleep_cpu();
  67. sleep_disable();
  68. // Disable watchdog after sleep
  69. wdt_disable();
  70. }
  71. bool suspend_wakeup_condition(void)
  72. {
  73. matrix_power_up();
  74. matrix_scan();
  75. matrix_power_down();
  76. for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
  77. if (matrix_get_row(r)) return true;
  78. }
  79. return false;
  80. }
  81. // run immediately after wakeup
  82. void suspend_wakeup_init(void)
  83. {
  84. // clear keyboard state
  85. clear_keyboard();
  86. #ifdef BACKLIGHT_ENABLE
  87. backlight_init();
  88. #endif
  89. }
  90. #ifndef NO_SUSPEND_POWER_DOWN
  91. /* watchdog timeout */
  92. ISR(WDT_vect)
  93. {
  94. /* wakeup from MCU sleep mode */
  95. /*
  96. // blink LED
  97. static uint8_t led_state = 0;
  98. static uint8_t led_count = 0;
  99. led_count++;
  100. if ((led_count & 0x07) == 0) {
  101. led_set((led_state ^= (1<<USB_LED_CAPS_LOCK)));
  102. }
  103. */
  104. }
  105. #endif