Hi,
I try to implement the HID keyboard protocol based on the HID example on my LPC1768 but unfortunately is doesn't work yet. The problem occurs after the host (Windows 7) reads the report descriptor. The host waits for incoming data on Endpoint 1 (0x81) but nothing is happen and so the host makes a reset.
I read a lot of posts in this forum but nothing helps. Below are the changes I made in HID example. I hope anyone can help.
usbcfg.h:
... #define USB_POWER 0 #define USB_IF_NUM 1 #define USB_EP_NUM 16 #define USB_MAX_PACKET0 8 #define USB_DMA 0 #define USB_DMA_EP 0x00000000 ... #define USB_EP_EVENT 0x0003 #define USB_CONFIGURE_EVENT 1 #define USB_INTERFACE_EVENT 1 #define USB_FEATURE_EVENT 0 ... #define USB_HID 1
hiduser.c
... U8 InReport[USB_MAX_PACKET0]; U8 OutReport[USB_MAX_PACKET0]; ... BOOL HID_GetReport (void) { /* ReportID = SetupPacket.wValue.WB.L; */ switch (SetupPacket.wValue.WB.H) { case HID_REPORT_INPUT: memcpy(EP0Buf, InReport, SetupPacket.wLength); // <--------- break; case HID_REPORT_OUTPUT: return (__FALSE); /* Not Supported */ case HID_REPORT_FEATURE: /* EP0Buf[] = ...; */ /* break; */ return (__FALSE); /* Not Supported */ } return (__TRUE); } ... BOOL HID_SetReport (void) { /* ReportID = SetupPacket.wValue.WB.L; */ switch (SetupPacket.wValue.WB.H) { case HID_REPORT_INPUT: return (__FALSE); /* Not Supported */ case HID_REPORT_OUTPUT: memcpy(OutReport, EP0Buf, SetupPacket.wLength); // <--------- break; case HID_REPORT_FEATURE: return (__FALSE); /* Not Supported */ } return (__TRUE); } ...
usbdesc.c
... /* byte 0 -> modifier keys * byte 1 -> reserved * byte 2..7 -> keys */ const U8 HID_ReportDescriptor[] = { 0x05, 0x01, // usage page (generic desktop) 0x09, 0x06, // usage (keyboard) 0xA1, 0x01, // collection (application) 0x05, 0x07, // usage page (keyboard) 0x19, 0xE0, // usage minimum (keyboard left control) 0x29, 0xE7, // usage maximium (keyboard right gui) 0x15, 0x00, // logical minimum 0 0x25, 0x01, // logical maximum 1 0x75, 0x01, // report size 1 0x95, 0x08, // report count 8 0x81, 0x02, // input (data, var, abs) 0x95, 0x01, // report count 1 0x75, 0x08, // report size 8 0x81, 0x01, // input (const, var, abs) 0x95, 0x05, // report count 5 0x75, 0x01, // report size 1 0x05, 0x08, // usage page led 0x19, 0x01, // usage minimum (num lock) 0x29, 0x05, // usage maximum (kana) 0x91, 0x02, // output (data, var, abs) 0x95, 0x01, // report count 1 0x75, 0x03, // report size 3 0x91, 0x01, // output (const, var, abs) 0x95, 0x06, // report count 6 0x75, 0x08, // reoprt size 8 0x15, 0x00, // logical minimum 0 0x25, 0x65, // logical maximum 101 0x05, 0x07, // usage page (keyboard) 0x19, 0x00, // usage minimum (no event) 0x29, 0x65, // usage maximum (keyboard application) 0x81, 0x00, // input (data, array, abs) 0xC0 // end }; ... const U8 USB_DeviceDescriptor[] = { USB_DEVICE_DESC_SIZE, /* bLength */ USB_DEVICE_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(0x0100), /* 1.00 */ /* bcdUSB */ 0x00, /* bDeviceClass */ 0x00, /* bDeviceSubClass */ 0x00, /* bDeviceProtocol */ USB_MAX_PACKET0, /* bMaxPacketSize0 */ WBVAL(0xFFFF), /* idVendor */ WBVAL(0x2201), /* idProduct */ WBVAL(0x0100), /* 1.00 */ /* bcdDevice */ 0x01, /* iManufacturer */ 0x02, /* iProduct */ 0x03, /* iSerialNumber */ 0x01 /* bNumConfigurations: one possible configuration*/ }; ... const U8 USB_ConfigDescriptor[] = { /* Configuration 1 */ USB_CONFIGUARTION_DESC_SIZE, /* bLength */ USB_CONFIGURATION_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL( /* wTotalLength */ USB_CONFIGUARTION_DESC_SIZE + USB_INTERFACE_DESC_SIZE + HID_DESC_SIZE + USB_ENDPOINT_DESC_SIZE ), 0x01, /* bNumInterfaces */ 0x01, /* bConfigurationValue: 0x01 is used to select this configuration */ 0x00, /* iConfiguration: no string to describe this configuration */ 0xa0 /* USB_CONFIG_BUS_POWERED */ /*|*/ /* bmAttributes */ /*USB_CONFIG_REMOTE_WAKEUP*/, USB_CONFIG_POWER_MA(100), /* bMaxPower, device power consumption is 100 mA */ /* Interface 0, Alternate Setting 0, HID Class */ USB_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x00, /* bInterfaceNumber */ 0x00, /* bAlternateSetting */ 0x01, /* bNumEndpoints */ USB_DEVICE_CLASS_HUMAN_INTERFACE, /* bInterfaceClass */ HID_SUBCLASS_NONE, /* bInterfaceSubClass */ HID_PROTOCOL_KEYBOARD, /* bInterfaceProtocol */ // <---------- 0x00, /* iInterface */ /* HID Class Descriptor */ /* HID_DESC_OFFSET = 0x0012 */ HID_DESC_SIZE, /* bLength */ HID_HID_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(0x0101), /* 1.01 */ /* bcdHID */ 0x00, /* bCountryCode */ 0x01, /* bNumDescriptors */ HID_REPORT_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(HID_REPORT_DESC_SIZE), /* wDescriptorLength */ /* Endpoint, HID Interrupt In */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(1), /* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ WBVAL(0x0008), /* 8 byte */ /* wMaxPacketSize */ // <--------- 0x20, /* 32ms */ /* bInterval */ // <--------- /* Terminator */ 0 /* bLength */ }; ...
usbuser.c
... void USB_Configure_Event (void) { if (USB_Configuration) { /* Check if USB is configured */ memset(InReport, 0, sizeof(InReport)); USB_WriteEP(HID_EP_IN, InReport, sizeof(InReport)); } } ... void USB_Interface_Event (void) { USB_Configure_Event(); } ... void USB_EndPoint1 (U32 event) { switch (event) { case USB_EVT_IN: USB_WriteEP(HID_EP_IN, InReport, sizeof(InReport)); break; } } ...