Fixed LowLevel Keyboard demo not saving the issued report only after it has been...
authorDean Camera <dean@fourwalledcubicle.com>
Fri, 20 Nov 2009 04:39:41 +0000 (04:39 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Fri, 20 Nov 2009 04:39:41 +0000 (04:39 +0000)
Added support for multiple keyboard keycodes in a single report to the LowLevel and ClassDriver Keyboard demos.

12 files changed:
Demos/Device/ClassDriver/Keyboard/Keyboard.c
Demos/Device/ClassDriver/Keyboard/Keyboard.txt
Demos/Device/LowLevel/Keyboard/Keyboard.c
Demos/Device/LowLevel/Keyboard/Keyboard.h
Demos/Device/LowLevel/Keyboard/Keyboard.txt
Demos/Device/LowLevel/Mouse/Mouse.c
Demos/Host/ClassDriver/JoystickHostWithParser/JoystickHostWithParser.c
Demos/Host/ClassDriver/MouseHostWithParser/MouseHostWithParser.c
Demos/Host/Incomplete/RNDISEthernetHost/RNDISEthernetHost.c
LUFA/ManPages/ChangeLog.txt
LUFA/ManPages/FutureChanges.txt
Projects/Incomplete/StandaloneProgrammer/StandaloneProgrammer.c

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