Hi All, I followed http://www.keil.com/forum/docs/thread11649.asp to try add 4 in endpoints with 64 byte data length on my MCB2300(LPC2368)board, But it can not be recognized. I can not fig it out what mistaks I made. My modified codes here based on the example USB_HID.
1.usbdesc.c
#include "type.h" #include "usb.h" #include "hid.h" #include "usbcfg.h" #include "usbdesc.h" #define INREPORT_SIZE 64 #define OUTREPORT_SIZE 64 /* HID Report Descriptor */ const BYTE HID_ReportDescriptor0[] = { HID_UsagePageVendor(0x00), HID_Usage(0x01), HID_Collection(HID_Application), HID_UsagePage(HID_USAGE_PAGE_BUTTON), HID_UsageMin(1), HID_UsageMax(3), HID_LogicalMin(0), HID_LogicalMax(1), //HID_ReportCount(3), //HID_ReportSize(1), HID_ReportCount( INREPORT_SIZE ), // bytes HID_ReportSize(8), // bits HID_Input(HID_Data | HID_Variable | HID_Absolute), //HID_ReportCount(1), //HID_ReportSize(5), //HID_Input(HID_Constant), HID_UsagePage(HID_USAGE_PAGE_LED), HID_Usage(HID_USAGE_LED_GENERIC_INDICATOR), HID_LogicalMin(0), HID_LogicalMax(1), HID_ReportCount(OUTREPORT_SIZE), HID_ReportSize(8), HID_Output(HID_Data | HID_Variable | HID_Absolute), HID_EndCollection, }; const BYTE HID_ReportDescriptor1[] = { HID_UsagePageVendor(0x00), HID_Usage(0x01), HID_Collection(HID_Application), HID_UsagePage(HID_USAGE_PAGE_BUTTON), HID_UsageMin(1), HID_UsageMax(3), HID_LogicalMin(0), HID_LogicalMax(1), //HID_ReportCount(3), //HID_ReportSize(1), HID_ReportCount( INREPORT_SIZE ), // bytes HID_ReportSize(8), // bits HID_Input(HID_Data | HID_Variable | HID_Absolute), //HID_ReportCount(1), //HID_ReportSize(5), //HID_Input(HID_Constant), HID_UsagePage(HID_USAGE_PAGE_LED), HID_Usage(HID_USAGE_LED_GENERIC_INDICATOR), HID_LogicalMin(0), HID_LogicalMax(1), HID_ReportCount(OUTREPORT_SIZE), HID_ReportSize(8), HID_Output(HID_Data | HID_Variable | HID_Absolute), HID_EndCollection, };
"Now, 4 HID devices can be found in device manager."
Contrats!! If no yellow "?" on the device instances icon on the Device Manager, the enumeration succeeds. Once enumerated, any software sniffer works. "My project use 4 endpoints to send different application data to PC"
Then, the next step is the host app. As you'll see on the Device Manager, Windows recognize the four interfaces as independent "devices". On the host app, you have to count up all four interfaces as independent HID devices. This post on USB-IF will help you for this task.
"multi-interface device" www.usb.org/.../viewtopic.php
As I said on above USB-IF post, HidD_GetProductString returns the string specified by the iInterface on the HID interface descriptor, when this iInterface is not zero. Then, this iInterface string is available to identify the HID interface.
HidD_GetProductString msdn.microsoft.com/.../ms790920.aspx "and PC send command to LPC2368 through 1 endpoint(enpoint0)."
I don't recommend you to use the default endpoint always to send commands to the device, when the commands are sent repeatedly. For this purpose, append an OUT endpoint to one of the HID interface, and send the commands over this OUT endpoint.
The reasons are twofold, a) Set_Report( OUTPUT ) request over the default endpoint is heavy for the firmware. The handling of Control transfer requires many steps on the firmware.
b) For the command over Set_Report( OUTPUT ) request, no delay is allowed to complete it. The command over Set_Report( OUTPUT ) request should complete when this request finishes. It means that, even while the firmware handles another command, the firmware should do this command. Set_Report( OUTPUT ) request should be applied just to commands of higher priority.
In this topic, I showed the way to add OUT endpoint to HID interface. "LPC2148 usb controller" http://www.keil.com/forum/docs/thread11137.asp 21-Nov-2007 17:02 by Tsuneo Chinzei -- body of modification 21-Nov-2007 17:03 by Tsuneo Chinzei -- continued 21-Nov-2007 23:19 by Tsuneo Chinzei -- interface descriptor fix
Tsuneo
Thank you very much Tsuneo. I will do it next week. Have a good weekend!
Jack
Hi Tsuneo, I modified my code to make 4 endpoint sending data to PC first, but my firware just sends 64 byte endpoint1 data(data is genrated in GetInReport1()), other 3 endpoint data can not be sent, it looks like GetInReport2() GetInReport3()GetInReport4() are not called.following are waht I modified:
//usbcfg.h #define USB_IF_NUM 5 #define USB_EP_EVENT 0x493// endpoint 0,1,4,7 10??? //usbcore.c switch (SetupPacket.bmRequestType.BM.Recipient) { case REQUEST_TO_INTERFACE: #if USB_HID if ((SetupPacket.wIndex.WB.L == USB_HID_IF_NUM0)|| (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM1)|| (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM2)|| (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM3)) { switch (SetupPacket.bRequest) { case HID_REQUEST_GET_REPORT: if (HID_GetReport()) { EP0Data.pData = EP0Buf; USB_DataInStage(); goto class_ok; } break; ... //hiduser.c BOOL HID_GetReport (void) { int i; /* ReportID = SetupPacket.wValue.WB.L; */ switch (SetupPacket.wValue.WB.H) { case HID_REPORT_INPUT: if (SetupPacket.wIndex.WB.L == USB_HID_IF_NUM0){ GetInReport1(); for(i=0;i<INREPORT_SIZE;i++) EP0Buf[i] = InReport1[i]; } else if(SetupPacket.wIndex.WB.L == USB_HID_IF_NUM1) { GetInReport2(); for(i=0;i<INREPORT_SIZE;i++) EP0Buf[i] = InReport2[i]; } else if(SetupPacket.wIndex.WB.L == USB_HID_IF_NUM2){ GetInReport3(); for(i=0;i<INREPORT_SIZE;i++) EP0Buf[i] = InReport3[i];} else if(SetupPacket.wIndex.WB.L == USB_HID_IF_NUM3){ GetInReport3(); for(i=0;i<INREPORT_SIZE;i++) EP0Buf[i] = InReport3[i]; } break; case HID_REPORT_OUTPUT: return (FALSE); /* Not Supported */ case HID_REPORT_FEATURE: /* EP0Buf[] = ...; */ /* break; */ return (FALSE); /* Not Supported */ } return (TRUE); } void USB_EndPoint1 (DWORD event) { switch (event) { case USB_EVT_IN: GetInReport1(); USB_WriteEP(0x81, InReport1, sizeof(InReport1)); break; } } void USB_EndPoint4 (DWORD event) { switch (event) { case USB_EVT_IN: GetInReport2(); USB_WriteEP(0x84, InReport2, sizeof(InReport2)); break; } } void USB_EndPoint7 (DWORD event) { switch (event) { case USB_EVT_IN: GetInReport3(); USB_WriteEP(0x87, InReport3, sizeof(InReport3)); break; } } void USB_EndPoint10 (DWORD event) { switch (event) {case USB_EVT_IN: GetInReport4(); USB_WriteEP(0x8A, InReport4, sizeof(InReport4)); break; } }
Thank you very much! Jack