#include "backlight.h" | #include "backlight.h" | ||||
#include "suspend_avr.h" | #include "suspend_avr.h" | ||||
#include "suspend.h" | #include "suspend.h" | ||||
#include "timer.h" | |||||
#ifdef PROTOCOL_LUFA | #ifdef PROTOCOL_LUFA | ||||
#include "lufa.h" | #include "lufa.h" | ||||
#endif | #endif | ||||
* WDTO_4S | * WDTO_4S | ||||
* WDTO_8S | * WDTO_8S | ||||
*/ | */ | ||||
void suspend_power_down(uint8_t wdto) | |||||
static uint8_t wdt_timeout = 0; | |||||
static void power_down(uint8_t wdto) | |||||
{ | { | ||||
#ifdef PROTOCOL_LUFA | #ifdef PROTOCOL_LUFA | ||||
if (USB_DeviceState == DEVICE_STATE_Configured) return; | if (USB_DeviceState == DEVICE_STATE_Configured) return; | ||||
#endif | #endif | ||||
wdt_timeout = wdto; | |||||
// Watchdog Interrupt Mode | // Watchdog Interrupt Mode | ||||
wdt_intr_enable(wdto); | wdt_intr_enable(wdto); | ||||
// - prescale clock | // - prescale clock | ||||
// - BOD disable | // - BOD disable | ||||
// - Power Reduction Register PRR | // - Power Reduction Register PRR | ||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN); | set_sleep_mode(SLEEP_MODE_PWR_DOWN); | ||||
sleep_enable(); | sleep_enable(); | ||||
sei(); | sei(); | ||||
wdt_disable(); | wdt_disable(); | ||||
} | } | ||||
void suspend_power_down(void) | |||||
{ | |||||
power_down(WDTO_15MS); | |||||
} | |||||
bool suspend_wakeup_condition(void) | bool suspend_wakeup_condition(void) | ||||
{ | { | ||||
matrix_power_up(); | matrix_power_up(); | ||||
/* watchdog timeout */ | /* watchdog timeout */ | ||||
ISR(WDT_vect) | ISR(WDT_vect) | ||||
{ | { | ||||
/* wakeup from MCU sleep mode */ | |||||
/* | |||||
// blink LED | |||||
static uint8_t led_state = 0; | |||||
static uint8_t led_count = 0; | |||||
led_count++; | |||||
if ((led_count & 0x07) == 0) { | |||||
led_set((led_state ^= (1<<USB_LED_CAPS_LOCK))); | |||||
// compensate timer for sleep | |||||
switch (wdt_timeout) { | |||||
case WDTO_15MS: | |||||
timer_count += 15 + 2; // WDTO_15MS + 2(from observation) | |||||
break; | |||||
default: | |||||
; | |||||
} | } | ||||
*/ | |||||
} | } | ||||
#endif | #endif |
void suspend_idle(uint8_t timeout); | void suspend_idle(uint8_t timeout); | ||||
void suspend_power_down(uint8_t timeout); | |||||
void suspend_power_down(void); | |||||
bool suspend_wakeup_condition(void); | bool suspend_wakeup_condition(void); | ||||
void suspend_wakeup_init(void); | void suspend_wakeup_init(void); | ||||
- Do not power-down during USB connection is active - DONE 11/11 | - Do not power-down during USB connection is active - DONE 11/11 | ||||
(USB_DeviceState == USB_DEVICE_Configured) is used to check USB connection | (USB_DeviceState == USB_DEVICE_Configured) is used to check USB connection | ||||
matrix_power_down() matrix.c - 11/23 | matrix_power_down() matrix.c - 11/23 | ||||
- timer is slow while power down - DONE 11/26 | |||||
- time out interrupt is lost while power down? | |||||
- interrupt of watchdog timer compensates timer counter(avr/suspend.c) | |||||
Todo: | Todo: | ||||
Design: | Design: | ||||
- suspend.h - DONE 11/26 | |||||
- remove argument from suspend_power_down() for backward compatitibility | |||||
- remove MCU dependent power saving code from core/keyboard | - remove MCU dependent power saving code from core/keyboard | ||||
- it should be located in project matrix.c - DONE 11/23 | - it should be located in project matrix.c - DONE 11/23 | ||||
- HHKB matrix.c needs matrix_prev? | - HHKB matrix.c needs matrix_prev? | ||||
- During USB suspend change clock source to internal RC from external Xtal(6.8) | - During USB suspend change clock source to internal RC from external Xtal(6.8) | ||||
- FRZCLK: you can freeze clock for power saving. still WAKEUPI and VBUSTI interrupts are available while freezing.(21.7.3) | - FRZCLK: you can freeze clock for power saving. still WAKEUPI and VBUSTI interrupts are available while freezing.(21.7.3) | ||||
- Suspend: Clear Suspend Bit, Freeze clock, disable PLL, MCU sleep(21.13) | - Suspend: Clear Suspend Bit, Freeze clock, disable PLL, MCU sleep(21.13) | ||||
- Voltage reference(8.1.1) | |||||
- to reduce power consumption while power down mode | |||||
Improving: | Improving: | ||||
- BT LED; connecting, linked, sleeping, deep sleeping | - BT LED; connecting, linked, sleeping, deep sleeping |
if (USB_DeviceState == DEVICE_STATE_Configured) return; | if (USB_DeviceState == DEVICE_STATE_Configured) return; | ||||
if (timer_elapsed32(matrix_last_modified) <= MATRIX_POWER_SAVE) return; | if (timer_elapsed32(matrix_last_modified) <= MATRIX_POWER_SAVE) return; | ||||
KEY_POWER_OFF(); | KEY_POWER_OFF(); | ||||
suspend_power_down(WDTO_15MS); | |||||
suspend_power_down(); | |||||
matrix_power = false; | matrix_power = false; | ||||
} | } |
print("Keyboard start.\n"); | print("Keyboard start.\n"); | ||||
while (1) { | while (1) { | ||||
while (USB_DeviceState == DEVICE_STATE_Suspended) { | while (USB_DeviceState == DEVICE_STATE_Suspended) { | ||||
suspend_power_down(WDTO_120MS); | |||||
suspend_power_down(); | |||||
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { | if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { | ||||
USB_Device_SendRemoteWakeup(); | USB_Device_SendRemoteWakeup(); | ||||
} | } |
print("Keyboard start.\n"); | print("Keyboard start.\n"); | ||||
while (1) { | while (1) { | ||||
while (USB_DeviceState == DEVICE_STATE_Suspended) { | while (USB_DeviceState == DEVICE_STATE_Suspended) { | ||||
suspend_power_down(WDTO_120MS); | |||||
suspend_power_down(); | |||||
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { | if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) { | ||||
USB_Device_SendRemoteWakeup(); | USB_Device_SendRemoteWakeup(); | ||||
} | } |