From 7ef58eef7a57c46ab53ed8a26805b58dcffd7010 Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Fri, 20 Nov 2009 04:39:41 +0000 Subject: [PATCH] Fixed LowLevel Keyboard demo not saving the issued report only after it has been written to the endpoint. Added support for multiple keyboard keycodes in a single report to the LowLevel and ClassDriver Keyboard demos. --- Demos/Device/ClassDriver/Keyboard/Keyboard.c | 24 +++++++++---- .../Device/ClassDriver/Keyboard/Keyboard.txt | 11 +++--- Demos/Device/LowLevel/Keyboard/Keyboard.c | 36 +++++++++++++------ Demos/Device/LowLevel/Keyboard/Keyboard.h | 1 + Demos/Device/LowLevel/Keyboard/Keyboard.txt | 11 +++--- Demos/Device/LowLevel/Mouse/Mouse.c | 8 ++--- .../JoystickHostWithParser.c | 2 +- .../MouseHostWithParser/MouseHostWithParser.c | 2 +- .../RNDISEthernetHost/RNDISEthernetHost.c | 2 +- LUFA/ManPages/ChangeLog.txt | 2 ++ LUFA/ManPages/FutureChanges.txt | 3 +- .../StandaloneProgrammer.c | 2 +- 12 files changed, 68 insertions(+), 36 deletions(-) diff --git a/Demos/Device/ClassDriver/Keyboard/Keyboard.c b/Demos/Device/ClassDriver/Keyboard/Keyboard.c index ea373a802a..2918f5a67a 100644 --- a/Demos/Device/ClassDriver/Keyboard/Keyboard.c +++ b/Demos/Device/ClassDriver/Keyboard/Keyboard.c @@ -144,22 +144,34 @@ bool CALLBACK_HID_Device_CreateHIDReport(USB_ClassInfo_HID_Device_t* const HIDIn uint8_t JoyStatus_LCL = Joystick_GetStatus(); uint8_t ButtonStatus_LCL = Buttons_GetStatus(); + static uint8_t PrevUsedKeyCodes; + uint8_t UsedKeyCodes = 0; + if (JoyStatus_LCL & JOY_UP) - KeyboardReport->KeyCode[0] = 0x04; // A + KeyboardReport->KeyCode[UsedKeyCodes++] = 0x04; // A else if (JoyStatus_LCL & JOY_DOWN) - KeyboardReport->KeyCode[0] = 0x05; // B + KeyboardReport->KeyCode[UsedKeyCodes++] = 0x05; // B if (JoyStatus_LCL & JOY_LEFT) - KeyboardReport->KeyCode[0] = 0x06; // C + KeyboardReport->KeyCode[UsedKeyCodes++] = 0x06; // C else if (JoyStatus_LCL & JOY_RIGHT) - KeyboardReport->KeyCode[0] = 0x07; // D + KeyboardReport->KeyCode[UsedKeyCodes++] = 0x07; // D if (JoyStatus_LCL & JOY_PRESS) - KeyboardReport->KeyCode[0] = 0x08; // E + KeyboardReport->KeyCode[UsedKeyCodes++] = 0x08; // E if (ButtonStatus_LCL & BUTTONS_BUTTON1) - KeyboardReport->KeyCode[0] = 0x09; // F + KeyboardReport->KeyCode[UsedKeyCodes++] = 0x09; // F + /* The host will ignore the device if we add a new keycode to the report while another keycode is currently + * being sent (i.e. the user has pressed another key while a key is already being pressed) - we need to intersperse + * the two reports with a zeroed report to force the host to accept the additional keys */ + if (UsedKeyCodes != PrevUsedKeyCodes) + { + memset(KeyboardReport, sizeof(USB_KeyboardReport_Data_t), 0x00); + PrevUsedKeyCodes = UsedKeyCodes; + } + *ReportSize = sizeof(USB_KeyboardReport_Data_t); return false; } diff --git a/Demos/Device/ClassDriver/Keyboard/Keyboard.txt b/Demos/Device/ClassDriver/Keyboard/Keyboard.txt index b1f5c2b537..89dde83052 100644 --- a/Demos/Device/ClassDriver/Keyboard/Keyboard.txt +++ b/Demos/Device/ClassDriver/Keyboard/Keyboard.txt @@ -49,11 +49,12 @@ * OSes (i.e. no special drivers required). It is boot protocol compatible, and thus * works under compatible BIOS as if it was a native keyboard (e.g. PS/2). * - * On start-up the system will automatically enumerate and function - * as a keyboard when the USB connection to a host is present. To use - * the keyboard example, manipulate the joystick to send the letters - * a, b, c, d and e. See the USB HID documentation for more information - * on sending keyboard event and key presses. + * On start-up the system will automatically enumerate and function as a keyboard + * when the USB connection to a host is present. To use the keyboard example, + * manipulate the joystick to send the letters a, b, c, d and e. See the USB HID + * documentation for more information on sending keyboard event and key presses. Unlike + * other LUFA Keyboard demos, this example shows explicitly how to send multiple keypresses + * inside the same report to the host. * * \section SSec_Options Project Options * diff --git a/Demos/Device/LowLevel/Keyboard/Keyboard.c b/Demos/Device/LowLevel/Keyboard/Keyboard.c index 32765af3de..33a6d840ad 100644 --- a/Demos/Device/LowLevel/Keyboard/Keyboard.c +++ b/Demos/Device/LowLevel/Keyboard/Keyboard.c @@ -84,6 +84,7 @@ void SetupHardware(void) Joystick_Init(); LEDs_Init(); USB_Init(); + Buttons_Init(); } /** Event handler for the USB_Connect event. This indicates that the device is enumerating via the status LEDs and @@ -257,23 +258,38 @@ void EVENT_USB_Device_StartOfFrame(void) */ void CreateKeyboardReport(USB_KeyboardReport_Data_t* ReportData) { - uint8_t JoyStatus_LCL = Joystick_GetStatus(); + static uint8_t PrevUsedKeyCodes; + uint8_t UsedKeyCodes = 0; + uint8_t JoyStatus_LCL = Joystick_GetStatus(); + uint8_t ButtonStatus_LCL = Buttons_GetStatus(); /* Clear the report contents */ memset(ReportData, 0, sizeof(USB_KeyboardReport_Data_t)); - + if (JoyStatus_LCL & JOY_UP) - ReportData->KeyCode[0] = 0x04; // A + ReportData->KeyCode[UsedKeyCodes++] = 0x04; // A else if (JoyStatus_LCL & JOY_DOWN) - ReportData->KeyCode[0] = 0x05; // B + ReportData->KeyCode[UsedKeyCodes++] = 0x05; // B if (JoyStatus_LCL & JOY_LEFT) - ReportData->KeyCode[0] = 0x06; // C + ReportData->KeyCode[UsedKeyCodes++] = 0x06; // C else if (JoyStatus_LCL & JOY_RIGHT) - ReportData->KeyCode[0] = 0x07; // D + ReportData->KeyCode[UsedKeyCodes++] = 0x07; // D if (JoyStatus_LCL & JOY_PRESS) - ReportData->KeyCode[0] = 0x08; // E + ReportData->KeyCode[UsedKeyCodes++] = 0x08; // E + + if (ButtonStatus_LCL & BUTTONS_BUTTON1) + ReportData->KeyCode[UsedKeyCodes++] = 0x09; // F + + /* The host will ignore the device if we add a new keycode to the report while another keycode is currently + * being sent (i.e. the user has pressed another key while a key is already being pressed) - we need to intersperse + * the two reports with a zeroed report to force the host to accept the additional keys */ + if (UsedKeyCodes != PrevUsedKeyCodes) + { + memset(ReportData, 0, sizeof(USB_KeyboardReport_Data_t)); + PrevUsedKeyCodes = UsedKeyCodes; + } } /** Processes a received LED report, and updates the board LEDs states to match. @@ -310,9 +326,6 @@ void SendNextReport(void) /* Check to see if the report data has changed - if so a report MUST be sent */ SendReport = (memcmp(&PrevKeyboardReportData, &KeyboardReportData, sizeof(USB_KeyboardReport_Data_t)) != 0); - /* Save the current report data for later comparison to check for changes */ - PrevKeyboardReportData = KeyboardReportData; - /* Check if the idle period is set and has elapsed */ if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining))) { @@ -329,6 +342,9 @@ void SendNextReport(void) /* Check if Keyboard Endpoint Ready for Read/Write and if we should send a new report */ if (Endpoint_IsReadWriteAllowed() && SendReport) { + /* Save the current report data for later comparison to check for changes */ + PrevKeyboardReportData = KeyboardReportData; + /* Write Keyboard Report Data */ Endpoint_Write_Stream_LE(&KeyboardReportData, sizeof(KeyboardReportData)); diff --git a/Demos/Device/LowLevel/Keyboard/Keyboard.h b/Demos/Device/LowLevel/Keyboard/Keyboard.h index f319ab73ba..576e080308 100644 --- a/Demos/Device/LowLevel/Keyboard/Keyboard.h +++ b/Demos/Device/LowLevel/Keyboard/Keyboard.h @@ -49,6 +49,7 @@ #include #include #include + #include #include /* Macros: */ diff --git a/Demos/Device/LowLevel/Keyboard/Keyboard.txt b/Demos/Device/LowLevel/Keyboard/Keyboard.txt index 1aa1675ab7..2bdaa6cc37 100644 --- a/Demos/Device/LowLevel/Keyboard/Keyboard.txt +++ b/Demos/Device/LowLevel/Keyboard/Keyboard.txt @@ -49,11 +49,12 @@ * OSes (i.e. no special drivers required). It is boot protocol compatible, and thus * works under compatible BIOS as if it was a native keyboard (e.g. PS/2). * - * On start-up the system will automatically enumerate and function - * as a keyboard when the USB connection to a host is present. To use - * the keyboard example, manipulate the joystick to send the letters - * a, b, c, d and e. See the USB HID documentation for more information - * on sending keyboard event and key presses. + * On start-up the system will automatically enumerate and function as a keyboard + * when the USB connection to a host is present. To use the keyboard example, + * manipulate the joystick to send the letters a, b, c, d and e. See the USB HID + * documentation for more information on sending keyboard event and key presses. Unlike + * other LUFA Keyboard demos, this example shows explicitly how to send multiple keypresses + * inside the same report to the host. * * \section SSec_Options Project Options * diff --git a/Demos/Device/LowLevel/Mouse/Mouse.c b/Demos/Device/LowLevel/Mouse/Mouse.c index 4b318e30ce..ff54c6544a 100644 --- a/Demos/Device/LowLevel/Mouse/Mouse.c +++ b/Demos/Device/LowLevel/Mouse/Mouse.c @@ -268,9 +268,6 @@ void SendNextReport(void) if ((MouseReportData.Y != 0) || (MouseReportData.X != 0)) SendReport = true; - /* Save the current report data for later comparison to check for changes */ - PrevMouseReportData = MouseReportData; - /* Check if the idle period is set and has elapsed */ if ((IdleCount != HID_IDLE_CHANGESONLY) && (!(IdleMSRemaining))) { @@ -286,7 +283,10 @@ void SendNextReport(void) /* Check if Mouse Endpoint Ready for Read/Write and if we should send a new report */ if (Endpoint_IsReadWriteAllowed() && SendReport) - { + { + /* Save the current report data for later comparison to check for changes */ + PrevMouseReportData = MouseReportData; + /* Write Mouse Report Data */ Endpoint_Write_Stream_LE(&MouseReportData, sizeof(MouseReportData)); diff --git a/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.c b/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.c index 037f722372..c620702ffa 100644 --- a/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.c +++ b/Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.c @@ -263,7 +263,7 @@ bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* CurrentItem) /* Iterate through the item's collection path, until either the root collection node or a collection with the * Joystick Usage is found - this prevents Mice, which use identical descriptors except for the Joystick usage - * parent node, from being erroneously treated as a joystick + * parent node, from being erroneously treated as a joystick by the demo */ for (HID_CollectionPath_t* CurrPath = CurrentItem->CollectionPath; CurrPath != NULL; CurrPath = CurrPath->Parent) { diff --git a/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c b/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c index 289a323f5c..938dc26d54 100644 --- a/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c +++ b/Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c @@ -278,7 +278,7 @@ bool CALLBACK_HIDParser_FilterHIDReportItem(HID_ReportItem_t* CurrentItem) /* Iterate through the item's collection path, until either the root collection node or a collection with the * Mouse Usage is found - this prevents Joysticks, which use identical descriptors except for the Joystick usage - * parent node, from being erroneously treated as a mouse + * parent node, from being erroneously treated as a mouse by the demo */ for (HID_CollectionPath_t* CurrPath = CurrentItem->CollectionPath; CurrPath != NULL; CurrPath = CurrPath->Parent) { diff --git a/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.c b/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.c index f3252cd87b..237d94dfee 100644 --- a/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.c +++ b/Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.c @@ -263,7 +263,7 @@ void RNDIS_Host_Task(void) } if (RetrievedPacketFilter != PacketFilter) - printf("ERROR: Retrieved Packet Filter %08lx != Set Packet Filter %08lx!\r\n", RetrievedPacketFilter, PacketFilter); + printf("ERROR: Retrieved Packet Filter 0x%08lx != Set Packet Filter 0x%08lx!\r\n", RetrievedPacketFilter, PacketFilter); uint32_t VendorID; if ((ErrorCode = RNDIS_QueryRNDISProperty(OID_GEN_VENDOR_ID, diff --git a/LUFA/ManPages/ChangeLog.txt b/LUFA/ManPages/ChangeLog.txt index 84fa2a617c..8390fde2ca 100644 --- a/LUFA/ManPages/ChangeLog.txt +++ b/LUFA/ManPages/ChangeLog.txt @@ -34,6 +34,7 @@ * - Changed MouseHostWithParser demos to check that the report items have a Mouse usage collection as a parent at some point, * to prevent Joysticks from enumerating with the demo * - Corrected the name of the misnamed USB_GetDeviceConfigDescriptor() function to USB_Host_GetDeviceConfigDescriptor(). + * - Keyboard LowLevel/ClassDriver demos now support multiple simultaneous keypresses (up to 6) per report * * Fixed: * - Fixed PrinterHost demo returning invalid Device ID data when the attached device does not have a @@ -49,6 +50,7 @@ * - Fixed HID report parser collection paths invalid due to misplaced semicolon in the free path item search loop * - Fixed HID host Class driver report send/receive report broken when issued through the control pipe * - Fixed HOST_STATE_AS_GPIOR compile time option being ignored when in host mode (thanks to David Lyons) + * - Fixed LowLevel Keyboard demo not saving the issues report only after it has been sent to the host * * \section Sec_ChangeLog090924 Version 090924 * diff --git a/LUFA/ManPages/FutureChanges.txt b/LUFA/ManPages/FutureChanges.txt index 20caca016d..f58b09cdaa 100644 --- a/LUFA/ManPages/FutureChanges.txt +++ b/LUFA/ManPages/FutureChanges.txt @@ -21,9 +21,7 @@ * - Add detailed overviews of how each demo works * - Master LUFA include file rather than per-module includes * - Change makefiles to allow for absolute LUFA location to be used - * - Add unit testing to APIs * - Add board overviews - * - Add resume interrupt support * - Correct mishandling of error cases in Mass Storage demo * - Add RNDIS Host Class driver * - Make new demos @@ -34,4 +32,5 @@ * -# AVR32 UC3B series microcontrollers * -# Atmel ARM7 series microcontrollers * -# Other (commercial) C compilers + * - Write LUFA tutorials */ diff --git a/Projects/Incomplete/StandaloneProgrammer/StandaloneProgrammer.c b/Projects/Incomplete/StandaloneProgrammer/StandaloneProgrammer.c index 655d13a515..afe3b3a360 100644 --- a/Projects/Incomplete/StandaloneProgrammer/StandaloneProgrammer.c +++ b/Projects/Incomplete/StandaloneProgrammer/StandaloneProgrammer.c @@ -96,7 +96,7 @@ FATFS DataflashData; /** Stream character fetching routine for the FAT driver so that characters from the currently open file can be - * readin sequence when applied to a stdio stream. + * read in sequence when applied to a stdio stream. */ static int Dataflash_getchar(FILE* Stream) {