Hi,
working with the SMT32 processor, I've some troubles with the usb interface. I want to install two HID interface descriptors (each has one endpoint - endpoint1 and endpoint4).
In the device manager of my computer, I get two usb HID interfaces - which sounds good; but there's only a communication with the endpoint1 not with the endpoint4!
void USB_EndPoint3 (DWORD event) { }
This function will be never called!
I tried to debug the code and I found out that at the beginning I get a Set-Address command with the addr 0x86 (which sounds good for these two endpoints); after that the host reads the usb device descriptor and the string descriptors; after that dataoutstage function is called, but the EP0Data.pData is 0x00...
void USB_DataOutStage (void) { DWORD cnt; cnt = USB_ReadEP(0x00, EP0Data.pData); EP0Data.pData += cnt; EP0Data.Count -= cnt; }
After that an reset event occured; I don't know why...
And the whole process will start from the beginning; except that the endpoint4 won't be configurated again; that means Set-Address command includes only the first endpoint1 but not the endpoint4!
At the moment I've no idea where the problem could be!
void USB_Configure_Event (void) { unsigned char InReportKeyboard[5]; unsigned char InReportTouch[6]; //es werden nur demo packets an die inputs geschickt keien richtigen daten memset( &InReportKeyboard[0], 0, sizeof(InReportKeyboard) ); memset( &InReportTouch[0], 0, sizeof(InReportTouch) ); if (USB_Configuration) { /* Check if USB is configured */ USB_WriteEP(0x81, InReportKeyboard, sizeof(InReportKeyboard)); USB_WriteEP(0x84, InReportTouch, sizeof(InReportTouch)); } }
Do someone know if this function is correct with these two USB_WriteEP calls?
These are my descriptors:
const BYTE 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 + /* interface two: descriptor length */ USB_INTERFACE_DESC_SIZE + HID_DESC_SIZE + USB_ENDPOINT_DESC_SIZE ), 0x02, /* bNumInterfaces */ 0x01, /* bConfigurationValue */ 0x00, /* iConfiguration */ USB_CONFIG_SELF_POWERED //USB_CONFIG_BUS_POWERED /*|*/ /* bmAttributes */ /*USB_CONFIG_REMOTE_WAKEUP*/, USB_CONFIG_POWER_MA(0), //USB_CONFIG_POWER_MA(100), /* bMaxPower */ 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_NONE, /* bInterfaceProtocol */ 0x5E, HID_DESC_SIZE, /* bLength */ HID_HID_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(0x0100), /* 1.00 */ /* bcdHID */ 0x00, /* bCountryCode */ 0x01, /* bNumDescriptors */ HID_REPORT_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(HID_REPORT_DESC_SIZE), USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(1), /* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ WBVAL(0x0008), /* wMaxPacketSize (muss so groß sein, dass das kompl. pkt reinpasst an daten */ 0x25, USB_INTERFACE_DESC_SIZE, /* bLength */ USB_INTERFACE_DESCRIPTOR_TYPE, /* bDescriptorType */ 0x01, /* bInterfaceNumber -> zweites interface im configuration descriptor */ 0x00, /* bAlternateSetting */ 0x01, /* bNumEndpoints -> wieviele endpoints besitzt dieses interface */ USB_DEVICE_CLASS_HUMAN_INTERFACE, /* bInterfaceClass */ HID_SUBCLASS_NONE, /* bInterfaceSubClass */ HID_PROTOCOL_NONE, /* bInterfaceProtocol */ 0x00, HID_DESC_SIZE, /* bLength */ HID_HID_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(0x0100), /* 1.00 */ /* bcdHID */ 0x00, /* bCountryCode */ 0x01, /* bNumDescriptors */ HID_REPORT_DESCRIPTOR_TYPE, /* bDescriptorType */ WBVAL(HID_REPORT_DESC_SIZE_2), USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(4), /* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ WBVAL(0x0008), /* wMaxPacketSize (muss so groß sein, dass das kompl. pkt (report descriptor) reinpasst an daten */ 0x20, /* Terminator */ 0 /* bLength */
best regards Jan
Moved from SiLabs USB forum, because the target MCU is STM32, and the firmware is based on KEIL example. www.cygnal.org/.../002075.html
A brief summary of the discussion on above thread,
1) The OP observed bus reset and Clear_Feature( ENDPOINT_HALT ) for EP4, after enumeration finishes. It was thought as error recovery sequence for EP4 by the host HID class driver. This problem was solved by changing the USB_EP_NUM value on usbcnfg.h
usbcnfg.h #define USB_EP_NUM 2 // <---- 5 ( = 1 + 4 )
2) Revised report descriptor was proposed for the first HID interface, which provides system keyboard.
// Report format // Input report - 1 byte // byte value // 0 0: not pressed, 1: Space bar, 2: Down arrow, 3: Up arrow // // Output report - 1 byte // byte // 0 0x00 - 0xFF // // Feature report - HID_FEATURE_REPORT_BYTES // byte // 0 0x00 - 0xFF // .. // HID_FEATURE_REPORT_BYTES - 1 // const BYTE HID_ReportDescriptor[] = { HID_UsagePage( 0x01 ), // Generic Desktop HID_Usage ( 0x06 ), // keyboard HID_Collection ( HID_Application ), // --------- common globals ----- HID_ReportSize ( 8 ), // 8 bits HID_LogicalMin ( 0x00 ), // value range: 0 - // --------- input report ----- HID_LogicalMax ( 0x03 ), // value range: 0 - 3 HID_ReportCount ( 1 ), // 1 byte HID_UsagePage( 0x07 ), // Keycode page HID_Usage( 0x00 ), // key null - not pressed HID_Usage( 0x2C ), // Space bar HID_Usage( 0x51 ), // Down arrow HID_Usage( 0x52 ), // Up arrow HID_Input ( HID_Data | HID_Array ), // --------- output report ----- HID_LogicalMaxS ( 0xFF ), // value range: 0 - 0xFF HID_UsagePageVendor( 0x01 ), // Vendor specific page HID_Usage ( 0x01 ), HID_Output ( HID_Data | HID_Variable | HID_Absolute ), // --------- feature report ----- HID_ReportCount ( HID_FEATURE_REPORT_BYTES ), HID_Usage ( 0x01 ), HID_Feature ( HID_Data | HID_Variable | HID_Absolute ), HID_EndCollection, };
This report descriptor is under testing on the OP side.
3) Four options are proposed for the second HID top-level collection for touchscreen
a) Generic Desktop - Mouse b) Generic Desktop - Joystick (or GamePad) c) Digitizer page - Pen (or Touchscreen) d) Vendor specific device
Tsuneo
I will try to use the version a) - writing my own calibration method.
const WORD HID_ReportDescSize = sizeof(HID_ReportDescriptor); //report descriptor touchscreen const BYTE HID_ReportDescriptor2[] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x02, // USAGE (Mouse) 0xa1, 0x01, // COLLECTION (Application) 0x09, 0x01, // USAGE (Pointer) 0xa1, 0x00, // COLLECTION (Physical) 0x05, 0x01, // USAGE PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) HID_LogicalMin ( 0x000 ), HID_LogicalMaxS ( 0x320 ), // max value 800px HID_ReportSize ( 16 ), HID_ReportCount ( 2 ), HID_Input ( HID_Data | HID_Variable | HID_Absolute), //0x81, 0x06, // INPUT (Data,Var,Relative) 0xc0, // END_COLLECTION 0xc0, // END_COLLECTION };
I can't uss the relative values in the original descriptor therefore I will use absolute values. The maximum size of the display is 800px -> therefore one 16bit value for each length (height and width) will be enough.
Therefore I changed the usb report descriptor to this one. In USBlyzer I can see the values transmitted, but the mouse is always at the left top corner...
Here's my endpoint descriptor - I only changed the size to 32bit.
/* Endpoint, HID Interrupt In */ USB_ENDPOINT_DESC_SIZE, /* bLength */ USB_ENDPOINT_DESCRIPTOR_TYPE, /* bDescriptorType */ USB_ENDPOINT_IN(2), /* bEndpointAddress */ USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes */ WBVAL(0x0020), /* wMaxPacketSize */ 0x0A, /* 8ms */ /* bInterval */
One small additional question: is it possible to add a feature report to the report descriptor of a mouse? If I only read, that it is not possible to add a output report to a mouse...
const WORD HID_ReportDescSize = sizeof(HID_ReportDescriptor); //report descriptor touchscreen const BYTE HID_ReportDescriptor2[] = { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x02, // USAGE (Mouse) 0xa1, 0x01, // COLLECTION (Application) 0x09, 0x01, // USAGE (Pointer) 0xa1, 0x00, // COLLECTION (Physical) 0x05, 0x01, // USAGE PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) 0x09, 0x31, // USAGE (Y) HID_LogicalMin ( 0x000 ), HID_LogicalMaxS ( 0x320 ), // max value 800px HID_ReportSize ( 16 ), HID_ReportCount ( 2 ), HID_Input ( HID_Data | HID_Variable | HID_Absolute), //0x81, 0x06, // INPUT (Data,Var,Relative) 0xc0, // END_COLLECTION HID_ReportCount ( HID_FEATURE_REPORT_BYTES ), HID_Usage ( 0x01 ), HID_Feature ( HID_Data | HID_Variable | HID_Absolute ), 0xc0, // END_COLLECTION };
View all questions in Keil forum