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
I got the encoder working; In the device manager, I can see another keyboard HID interface.
Everything seems to be fine, but if I change the vendor ID and / or the product ID -> the USB HID device will be unknown. No keyboard device will be available in the device manager. Both report descriptors won't be read by the host.
Is it correct, that there are some information stored in the registry (which driver has to be loaded for this USB connection and so on)?
Jan
> if I change the vendor ID and / or the product ID -> the USB HID device will be unknown.
When you change VID/PID, the device is recognized as a new device for Windows. Applying the default INF, input.inf, Windows will make up new registry entries for the device, without any intervention of user.
Did you assign a new VID/PID, which is not occupied by other USB device? USBDeview lists up all USB devices with VID/PID, regardless of current connection. Check it on USBDeview.
USBDeview www.nirsoft.net/.../usb_devices_view.html
In development, you can assign any VID/PID, unless it is occupied by other device on your PC. Higher end of VID, such as 0xFFF0 is likely not occupied yet. When you release the device, get official VID/PID for your device.
Even if you would assign unique VID/PID, but above problem occurs, it suggests firmware bug on enumeration. To catch a clue, take a trace on a hardware analyzer or software sniffer. The enumeration sequence is captured using software sniffers, like USBlyzer "Capture Hot-plugged" option.
USBlyzer (1 month trial) http://www.usblyzer.com/
What is the first error on the log?
Tsuneo
It's a little bit strange. If I start the host with the connected usb device, the device won't be shown as keyboard in the device manager.
If I try to search for new connected hardware (in the device manager), then the device will be found and shown. Therefore I'm not able to find the existing error using USBlyzer, because this software always search for new connected devices at startup.
I've some volatile global variables for the encoder part; if I delete them (6 volatile char variables) the device will be recognized by the host after booting.
The stack-size is big enough.
If I start the host with the device connected to the usb port (with new vendor and product ID), the device will be shown as unknown in the device manager. After a while, windows tries to talk to the device a second time, and after that both HID interrfaces from the device will be shown in the device manager (without any kind of error)....
ok I deleted the whole code for the encoder - getting the same problem; the device is always listened in the device manager as "other devices".
summary:
a) booten -> device manager shows usb device -> "other devices" -> after a while -> some usb resets occur -> usb device is shown as keyboard and mouse HID device
b) host is already running -> connect usb device -> device manager shows device as keyboard and mouse device (as expected)
In both ways, I use a new vendor and product ID.
Is your device bus-powered (supplied by USB line), or self-powered (has stand alone power supply) ?
KEIL examples are made for bus-powered devices. For self-powered, you have to add several process to your code. - VBUS detection - USB physical connection detection and additional initialization
That's a point. My device is self-powered.
> VBUS detection - USB physical connection detection and additional initialization
I'm using an external pullup on data+ line for the correct detection of the usb device (full-speed). I can enable / disable the usb detection by the device controller, because the pullup 1k5 is directly connected to an GPIO.
By the way, is my report descriptor for the touch (configurated as mouse device) ok?
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) 0x15, 0x81, // LOGICAL_MINIMUM (-127) 0x25, 0x7F, // LOGICAL_MAXIMUM (127) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x02, // REPORT_COUNT (2) 0x81, 0x06, // INPUT (Data,Var,Relative) 0xc0, // END_COLLECTION 0xc0, // END_COLLECTION };
In the device manager, I can see a second HID usb mouse device.
unsigned short coordinate[2]; GetValue(&coordinate[0]); USB_WriteEP(0x82, (BYTE *) &coordinate[0], 2 * sizeof(unsigned int));
I'm not sure if this USB_WriteEP() will work. Moreover is it better to use LOGICAL_MINIMUM, LOGICAL_MAXIMUM (-127, 127) or (0, 255)?