Skip to content

Commit 4cda3aa

Browse files
committed
core: Fix suspend/wake for converters #386
1 parent 4e15247 commit 4cda3aa

File tree

2 files changed

+63
-11
lines changed

2 files changed

+63
-11
lines changed

common/avr/suspend.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ bool suspend_wakeup_condition(void)
102102
void suspend_wakeup_init(void)
103103
{
104104
// clear keyboard state
105+
matrix_init();
105106
clear_keyboard();
106107
#ifdef BACKLIGHT_ENABLE
107108
backlight_init();

protocol/lufa/lufa.c

Lines changed: 62 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* Copyright 2012 Jun Wako <[email protected]>
33
* This file is based on:
44
* LUFA-120219/Demos/Device/Lowlevel/KeyboardMouse
@@ -54,9 +54,14 @@
5454
#include "avr/suart.h"
5555
#endif
5656

57+
#include "matrix.h"
5758
#include "descriptor.h"
5859
#include "lufa.h"
5960

61+
62+
//#define LUFA_DEBUG
63+
64+
6065
uint8_t keyboard_idle = 0;
6166
/* 0: Boot Protocol, 1: Report Protocol(default) */
6267
uint8_t keyboard_protocol = 1;
@@ -104,10 +109,10 @@ static void Console_Task(void)
104109
{
105110
/* Create a temporary buffer to hold the read in report from the host */
106111
uint8_t ConsoleData[CONSOLE_EPSIZE];
107-
112+
108113
/* Read Console Report Data */
109114
Endpoint_Read_Stream_LE(&ConsoleData, sizeof(ConsoleData), NULL);
110-
115+
111116
/* Process Console Report Data */
112117
//ProcessConsoleHIDReport(ConsoleData);
113118
}
@@ -168,7 +173,7 @@ void EVENT_USB_Device_Disconnect(void)
168173
print("[D]");
169174
/* For battery powered device */
170175
USB_IsInitialized = false;
171-
/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
176+
/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
172177
if (USB_IsInitialized) {
173178
USB_Disable(); // Disable all interrupts
174179
USB_Controller_Enable();
@@ -179,18 +184,24 @@ void EVENT_USB_Device_Disconnect(void)
179184

180185
void EVENT_USB_Device_Reset(void)
181186
{
187+
#ifdef LUFA_DEBUG
182188
print("[R]");
189+
#endif
183190
}
184191

185192
void EVENT_USB_Device_Suspend()
186193
{
194+
#ifdef LUFA_DEBUG
187195
print("[S]");
196+
#endif
188197
hook_usb_suspend_entry();
189198
}
190199

191200
void EVENT_USB_Device_WakeUp()
192201
{
202+
#ifdef LUFA_DEBUG
193203
print("[W]");
204+
#endif
194205
hook_usb_wakeup();
195206
}
196207

@@ -221,7 +232,9 @@ void EVENT_USB_Device_StartOfFrame(void)
221232
*/
222233
void EVENT_USB_Device_ConfigurationChanged(void)
223234
{
235+
#ifdef LUFA_DEBUG
224236
print("[c]");
237+
#endif
225238
bool ConfigSuccess = true;
226239

227240
/* Setup Keyboard HID Report Endpoints */
@@ -275,7 +288,6 @@ Other Device Required Optional Optional Optional Optional Opti
275288
*/
276289
void EVENT_USB_Device_ControlRequest(void)
277290
{
278-
print("[r]");
279291
uint8_t* ReportData = NULL;
280292
uint8_t ReportSize = 0;
281293

@@ -299,6 +311,9 @@ void EVENT_USB_Device_ControlRequest(void)
299311
/* Write the report data to the control endpoint */
300312
Endpoint_Write_Control_Stream_LE(ReportData, ReportSize);
301313
Endpoint_ClearOUT();
314+
#ifdef LUFA_DEBUG
315+
xprintf("[r%d]", USB_ControlRequest.wIndex);
316+
#endif
302317
}
303318

304319
break;
@@ -322,6 +337,9 @@ void EVENT_USB_Device_ControlRequest(void)
322337

323338
Endpoint_ClearOUT();
324339
Endpoint_ClearStatusStage();
340+
#ifdef LUFA_DEBUG
341+
xprintf("[L%d]", USB_ControlRequest.wIndex);
342+
#endif
325343
break;
326344
}
327345

@@ -338,6 +356,9 @@ void EVENT_USB_Device_ControlRequest(void)
338356
Endpoint_Write_8(keyboard_protocol);
339357
Endpoint_ClearIN();
340358
Endpoint_ClearStatusStage();
359+
#ifdef LUFA_DEBUG
360+
print("[p]");
361+
#endif
341362
}
342363
}
343364

@@ -351,6 +372,9 @@ void EVENT_USB_Device_ControlRequest(void)
351372

352373
keyboard_protocol = (USB_ControlRequest.wValue & 0xFF);
353374
clear_keyboard();
375+
#ifdef LUFA_DEBUG
376+
print("[P]");
377+
#endif
354378
}
355379
}
356380

@@ -362,6 +386,9 @@ void EVENT_USB_Device_ControlRequest(void)
362386
Endpoint_ClearStatusStage();
363387

364388
keyboard_idle = ((USB_ControlRequest.wValue & 0xFF00) >> 8);
389+
#ifdef LUFA_DEBUG
390+
xprintf("[I%d]%d", USB_ControlRequest.wIndex, (USB_ControlRequest.wValue & 0xFF00) >> 8);
391+
#endif
365392
}
366393

367394
break;
@@ -373,14 +400,17 @@ void EVENT_USB_Device_ControlRequest(void)
373400
Endpoint_Write_8(keyboard_idle);
374401
Endpoint_ClearIN();
375402
Endpoint_ClearStatusStage();
403+
#ifdef LUFA_DEBUG
404+
print("[i]");
405+
#endif
376406
}
377407

378408
break;
379409
}
380410
}
381411

382412
/*******************************************************************************
383-
* Host driver
413+
* Host driver
384414
******************************************************************************/
385415
static uint8_t keyboard_leds(void)
386416
{
@@ -595,11 +625,15 @@ static void setup_usb(void)
595625
int main(void) __attribute__ ((weak));
596626
int main(void)
597627
{
628+
setup_mcu();
629+
598630
#ifdef LUFA_DEBUG_SUART
599-
DDRD |= (1<<SUART_OUT_BIT);
631+
SUART_OUT_DDR |= (1<<SUART_OUT_BIT);
632+
SUART_OUT_PORT |= (1<<SUART_OUT_BIT);
600633
#endif
601634
print_set_sendchar(sendchar);
602-
setup_mcu();
635+
print("\r\ninit\n");
636+
603637
hook_early_init();
604638
keyboard_setup();
605639
setup_usb();
@@ -626,7 +660,9 @@ int main(void)
626660
hook_late_init();
627661
while (1) {
628662
while (USB_DeviceState == DEVICE_STATE_Suspended) {
663+
#ifdef LUFA_DEBUG
629664
print("[s]");
665+
#endif
630666
hook_usb_suspend_loop();
631667
}
632668

@@ -646,9 +682,19 @@ void hook_early_init(void) {}
646682
__attribute__((weak))
647683
void hook_late_init(void) {}
648684

685+
static uint8_t _led_stats = 0;
649686
__attribute__((weak))
650687
void hook_usb_suspend_entry(void)
651688
{
689+
// Turn LED off to save power
690+
// Set 0 with putting aside status before suspend and restore
691+
// it after wakeup, then LED is updated at keyboard_task() in main loop
692+
_led_stats = keyboard_led_stats;
693+
keyboard_led_stats = 0;
694+
led_set(keyboard_led_stats);
695+
696+
matrix_init();
697+
clear_keyboard();
652698
#ifdef SLEEP_LED_ENABLE
653699
sleep_led_enable();
654700
#endif
@@ -659,7 +705,7 @@ void hook_usb_suspend_loop(void)
659705
{
660706
suspend_power_down();
661707
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
662-
USB_Device_SendRemoteWakeup();
708+
USB_Device_SendRemoteWakeup();
663709
}
664710
}
665711

@@ -669,7 +715,12 @@ void hook_usb_wakeup(void)
669715
suspend_wakeup_init();
670716
#ifdef SLEEP_LED_ENABLE
671717
sleep_led_disable();
672-
// NOTE: converters may not accept this
673-
led_set(host_keyboard_leds());
674718
#endif
719+
720+
// Restore LED status
721+
// BIOS/grub won't recognize/enumerate if led_set() takes long(around 40ms?)
722+
// Converters fall into the case and miss wakeup event(timeout to reply?) in the end.
723+
//led_set(host_keyboard_leds());
724+
// Instead, restore stats and update at keyboard_task() in main loop
725+
keyboard_led_stats = _led_stats;
675726
}

0 commit comments

Comments
 (0)