summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortmk <nobody@nowhere>2014-11-20 17:06:46 +0900
committertmk <nobody@nowhere>2014-11-20 17:24:56 +0900
commitc2d830c07c823c48a17c214b093ec1bab989fb6a (patch)
tree388b86cd7bfbf3b78528a498c8e3f39a20fc778f
parent6c06b9031fd09479d552f9750a3b1cfe259678fd (diff)
USB initialize when plug-in during battery powered
-rw-r--r--common/avr/suspend.c49
-rw-r--r--common/suspend.h3
-rw-r--r--protocol/lufa/lufa.c15
3 files changed, 50 insertions, 17 deletions
diff --git a/common/avr/suspend.c b/common/avr/suspend.c
index f44a036beb..66a579fd78 100644
--- a/common/avr/suspend.c
+++ b/common/avr/suspend.c
@@ -7,6 +7,9 @@
#include "backlight.h"
#include "suspend_avr.h"
#include "suspend.h"
+#ifdef PROTOCOL_LUFA
+#include "lufa.h"
+#endif
#define wdt_intr_enable(value) \
@@ -26,30 +29,45 @@ __asm__ __volatile__ ( \
)
-void suspend_power_down(void)
+void suspend_idle(uint8_t time)
{
-#ifdef BACKLIGHT_ENABLE
- backlight_set(0);
-#endif
-#ifndef NO_SUSPEND_POWER_DOWN
- // Enable watchdog to wake from MCU sleep
cli();
- wdt_reset();
+ set_sleep_mode(SLEEP_MODE_IDLE);
+ sleep_enable();
+ sei();
+ sleep_cpu();
+ sleep_disable();
+}
+
+/* Power down MCU with watchdog timer
+ * wdto: watchdog timer timeout defined in <avr/wdt.h>
+ * WDTO_15MS
+ * WDTO_30MS
+ * WDTO_60MS
+ * WDTO_120MS
+ * WDTO_250MS
+ * WDTO_500MS
+ * WDTO_1S
+ * WDTO_2S
+ * WDTO_4S
+ * WDTO_8S
+ */
+void suspend_power_down(uint8_t wdto)
+{
+#ifdef PROTOCOL_LUFA
+ if (USB_DeviceState == DEVICE_STATE_Configured) return;
+#endif
- // Watchdog Interrupt and System Reset Mode
- //wdt_enable(WDTO_1S);
- //WDTCSR |= _BV(WDIE);
-
// Watchdog Interrupt Mode
- wdt_intr_enable(WDTO_120MS);
-
+ wdt_intr_enable(wdto);
+
// TODO: more power saving
// See PicoPower application note
// - I/O port input with pullup
// - prescale clock
// - BOD disable
// - Power Reduction Register PRR
- // sleep in power down mode
+
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sei();
@@ -58,12 +76,13 @@ void suspend_power_down(void)
// Disable watchdog after sleep
wdt_disable();
-#endif
}
bool suspend_wakeup_condition(void)
{
+ matrix_power_up();
matrix_scan();
+ matrix_power_down();
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
if (matrix_get_row(r)) return true;
}
diff --git a/common/suspend.h b/common/suspend.h
index 9b76f280d1..f339c670ac 100644
--- a/common/suspend.h
+++ b/common/suspend.h
@@ -5,7 +5,8 @@
#include <stdbool.h>
-void suspend_power_down(void);
+void suspend_idle(uint8_t timeout);
+void suspend_power_down(uint8_t timeout);
bool suspend_wakeup_condition(void);
void suspend_wakeup_init(void);
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index 16a602df13..6802f3b631 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -148,10 +148,23 @@ static void Console_Task(void)
*/
void EVENT_USB_Device_Connect(void)
{
+ /* For battery powered device */
+ if (!USB_IsInitialized) {
+ USB_Init();
+ USB_Device_EnableSOFEvents();
+ }
}
void EVENT_USB_Device_Disconnect(void)
{
+ /* For battery powered device */
+/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
+ if (USB_IsInitialized) {
+ USB_Disable(); // Disable all interrupts
+ USB_Controller_Enable();
+ USB_INT_Enable(USB_INT_VBUSTI);
+ }
+*/
}
void EVENT_USB_Device_Reset(void)
@@ -574,7 +587,7 @@ int main(void)
print("Keyboard start.\n");
while (1) {
while (USB_DeviceState == DEVICE_STATE_Suspended) {
- suspend_power_down();
+ suspend_power_down(WDTO_120MS);
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
USB_Device_SendRemoteWakeup();
}