Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

10 роки тому
11 роки тому
11 роки тому
10 роки тому
10 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
11 роки тому
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