diff --git a/Demos/Device/ClassDriver/Keyboard/Keyboard.c b/Demos/Device/ClassDriver/Keyboard/Keyboard.c index ea373a802a8c8e0d5f72125fb2fda02c05fa35c1..2918f5a67aab799a84697645ac92d902b30d18c3 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 b1f5c2b537b877d76d96b7d74566caf5bed99315..89dde830522252ad127873b97284beca966be983 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 32765af3deab87c1f1e94ad32f9c43f98c0c603a..33a6d840ad7cb6acd4e01f5c0ed0df23306f1350 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 f319ab73ba3cf1e3c85b86b2c0018403a8b228e0..576e0803082da439c8aebe9475325c52fbf43e45 100644 --- a/Demos/Device/LowLevel/Keyboard/Keyboard.h +++ b/Demos/Device/LowLevel/Keyboard/Keyboard.h @@ -49,6 +49,7 @@ #include <LUFA/Version.h> #include <LUFA/Drivers/USB/USB.h> #include <LUFA/Drivers/Board/Joystick.h> + #include <LUFA/Drivers/Board/Buttons.h> #include <LUFA/Drivers/Board/LEDs.h> /* Macros: */ diff --git a/Demos/Device/LowLevel/Keyboard/Keyboard.txt b/Demos/Device/LowLevel/Keyboard/Keyboard.txt index 1aa1675ab7634af049ea4b80ce44f894f102476d..2bdaa6cc3714f91c48f336da8c3b988e9dd61b81 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 4b318e30cece55b224c9450dca8191375d496902..ff54c6544a528b6bac6516b3f752a34159a11e0d 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 037f7223727d2c2d491afa9bebdc295a8a61e262..c620702ffa62e38fbd539ff293c9275a6a113a3b 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 289a323f5c5dd4b68bc625cd23f4edbaa4daf4d6..938dc26d547b80457e067cb47b912327810fee5f 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 f3252cd87bd8e0c0749cb044b34f8607cc6db630..237d94dfeea4664d499cfe37033061ae41fc7689 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 84fa2a617c37aefcaa123fce8998c21426dd0425..8390fde2ca54f6589d9a887d05273b23742a08c7 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 * * <b>Fixed:</b> * - 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 20caca016d27a5fd9b234078fe26ddfab6899e5f..f58b09cdaa3fa8a810aae2c771d37f45dcb162f3 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 655d13a5150cc3328130cc5ee95e34302c305c56..afe3b3a360e9c55fd1b9e531ebc4c89efcbbb691 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) {