Tsuneo |
posted October 23, 2006 01:22 AM USB composite device Examples USB_CDC_HID_IAD_10.zip
Passed USBCV R1.3.1, the ch9 and HID test On the original WinXP SP2 (usbser.sys, usbccgp.sys: 5.1.2600.2180),
Passed the USB compliance test, USBCV 1.3, ch9 and HID test.
Using composite device, multiple functions are combined into a single device. Another advantage of composite device is that it eases the device driver development. +----------------------------+ +---------------------- | Composite Device | | Host PC | | | | Function 0 -- Interface 0 --------- Device driver A <---> | | | | Function 1 -- Interface 1 --------- Device driver B <---> +----------------------------+ +-----------------------
Windows have these built-in class drivers. Please note, available drivers for a composite device are not limited only to class drivers. Any driver can be applied, as long as it doesn't require a device class (class defined in device descriptor). For example, SiLabs USB_INT and USB_bulk drivers are also applicable for composite devices.
"Enumeration of the Composite Parent Device" from MSDN 3. Implementation 3.1 Device firmware
3.1.1 Descriptors
3.2.1 INF file
Tsuneo [This message has been edited by Tsuneo (edited May 10, 2008).] IP: Logged |
Patryk |
posted October 23, 2006 05:51 AM Just some spottings/clarifications to make your excellent post perfect :-) 1. 3.1.2.1... 2. "3.1.2.2 ... 3. "3.2.2..." Regards, IP: Logged |
Tsuneo |
posted October 17, 2007 09:31 AM Added an example, USB_HID_composite See the first post. Tsuneo IP: Logged |
MikeB |
posted November 02, 2007 06:29 AM Tsuneo, Thank you for providing this excellent example. Can you point me to a clear description of how one communicates with composite HID devices from Windows? I have found several examples for single devices but I have not yet worked out how this translates to the composite device case. Many thanks. Mike. IP: Logged |
LiMing.Sun |
posted November 02, 2007 09:33 PM Seems that the 3-HID composite devices share the same VID and PID,i just want to know how to distinguish them on host; Besides,as mentioned by tsuneo,packets between the composite device and host may miss their order,we need to build some rules to arrange packets in their order for right HID. IP: Logged |
Tsuneo |
posted November 03, 2007 10:00 PM I was writing a host app example for the three HID composite firmware. I'm using a note PC for the development of these personal projects, but the hard disk was broken on Wednesday of the last week. I have a recent backup for data files (one week ago), then the crash is not so much disastrous, I thought so at first time. But it takes so long to recover the OS and applications on a new HD, because tons of heavy apps are installed, like KEIL (C51 and ARM), Xilinx and Altera, TI DSP, MS VS (2005,2003 VC6) and Office, Eclipse, etc. etc... Please wait for a while.
As I wrote in the first post of this topic, USB\VID_vvvv&PID_pppp&MI_mm Run msinfo32.exe (included in the Windows system) and you'll confirm it. This is an example of msinfo32 output from MS Coding4Fun brog.
These instances are distinguished by the device "path" string. Tsuneo [This message has been edited by Tsuneo (edited November 03, 2007).] IP: Logged |
MikeB |
posted November 05, 2007 05:21 AM Tsuneo, I'm sorry for your laptop problems. Thanks for the extra explanation. Mike. IP: Logged |
Tsuneo |
posted May 10, 2008 08:10 AM Added an example of a composite device, CDC (with IAD) + HID, to the first post. Interface Association Descriptor (IAD) There are classes like CDC, which consists of multiple interfaces. On the Device descriptor, the triad (Class, Subclass, Protocol) is set to that of IAD as follows. 0xEF, // bDeviceClass (Misc)0x02, // bDeviceSubClass (common)0x01, // bDeviceProtocol (IAD) On the Config descriptor set, IAD is placed just before the interface descriptors which are tied together. // Interface Association Descriptorsizeof(Tinterface_association_descriptor), // bLengthDSC_TYPE_IAD, // bDescriptorType = 110x00, // bFirstInterface0x02, // bInterfaceCount0x02, // bFunctionClass (Communication Class)0x02, // bFunctionSubClass (Abstract Control Model)0x01, // bFunctionProcotol (V.25ter, Common AT commands)0x00, // iInterface }, // // Follows the first interface bound by the IAD //
There is no other difference from ordinary composite devices. Tsuneo IP: Logged |
smhinchy |
posted May 13, 2008 04:20 PM Hello, Should this example work out of the box? I am using SiLabs IDE 3.3, SDCC Version 2.8.0 and Windows XP SP2. The program compiles and downloads, but when I run it I get the USB three dings and nothing else. Any suggestions? Shawn IP: Logged |
vanmierlo |
posted May 14, 2008 04:01 AM In the ReadMe.txt Tsuneo wrote that it works on WinXP SP3 and Vista SP1. I suggest installing the latest SP. Maarten IP: Logged |
xiaofan |
posted May 15, 2008 03:42 AM As discussed previously, you need two hot fixes for Windows XP SP2. http://www.cygnal.org/ubb/Forum9/HTML/001572.html It is easier to use Windows XP SP3. I have tested a dual CDC-ACM IAD USB Composite device under Windows XP SP3 and it is working. IP: Logged |
ryyu |
posted May 15, 2008 09:48 PM I am currently studying USB HID. I want to make a composite HID mouse + keyboard.Besides, I have downloaded the USB_HID_composite_01. However, I don't know how to control the cursor or keyboard through that example. Therefore, could anyone give me some more helpful examples, Thanks Ray IP: Logged |
Tsuneo |
posted May 15, 2008 11:49 PM Hello Ray, I recommend you to make separated mouse and keyboard implementations at first. SiLabs provides a mouse example. Then, you have to make a keyboard implementation. USB HID spec 1.11 Of course, the HID spec is massive one and it isn't written just for keyboard and mouse. Then, you have to extract the concerning description from the spec. On the spec, the mouse description follows the keyboard one.
If you assign the same VID/PID to another implementation, delete the device instance on the Device Manager, once. You can see all instances on the Device Manager using following procedure. 2) Double click DevManager.bat, and Device Manager comes up. Tsuneo IP: Logged |
xiaofan |
posted May 16, 2008 03:31 AM There is another way to do this without using a composite device. You can actually implement using an HID device with two reports, one for keyboard and one for mouse. IP: Logged |
xiaofan |
posted May 16, 2008 03:41 AM Example from ST. Keyboard + Mouse + Gamepad: http://www.st.com/stonline/books/pdf/docs/6904.pdf The code is here: IP: Logged |
Tsuneo |
posted May 16, 2008 04:28 AM Ah, you are talking about multiple top-level collections. It was discussed once on this topic. multiple HID and one MSD on a -340 The flaw of this method is that it doesn't support boot device. Tsuneo IP: Logged |
Robonz |
posted May 20, 2008 09:40 AM Hi Tsuneo Firstly thanks for all your reference code I hope Silabs are sending you money or beer or something, because you have helped us a lot over the years. I dont know how you find the time to do all the posting you do. Two of us have been working on an urgent bug for a commercial product we sell. We have spent 4 x 12 hour days to find the cause using a bus analyser. The root cause was quite simple but it took us a long time. I thought I would share this fix with you all. When you have firmware that must turn off USB interrupts for timing critical reasons there is a catch with the current code. A sent stall flag can arrive with a setup packet in one interrupt. All our previous code did not turn off interrupts. Sent stalls always (well we didnt have a bus analyser) came as a seperate interrupt. Here is the fix, but it doesnt work, see if (ControlReg & rbSTSTL){ Cheers [This message has been edited by Robonz (edited May 21, 2008).] IP: Logged |
Tsuneo |
posted May 21, 2008 03:36 AM Thanks Keith, You make me aware the problem of STALL handling here. Following USB spec, STALL condition of the default endpoint is cleared just by SETUP packet from the host. Then, the stack has to clear SDSTL and return to EP_IDLE, just when the engine receives SETUP. However, my code (and SiLabs' also) clears SDSTL when it sees STSTL bit, ie. when the STALL is sent to the host, before it sees SETUP. Usually, it works fine, because the host sends SETUP next to STALL reception, but it is not guaranteed. I should examine the behavior of the engine on this STALL handling more. Tsuneo IP: Logged |
scene |
posted August 01, 2008 05:01 AM Hi Tsuneo, I wonder if you could help me with me with a related question. I have a situation where I need to emulate a commercial HID device which is supplied with it's own vendor driver (say, a touch screen). Additionally, I want to add keyboard and mouse interfaces to this device to make a composite device. The VID/PID will 'copied' from the commercial HID device. I would like Windows to bind the original vendor driver to the device and also bind it's KB/Mouse drivers to the other interfaces. Is this possible? In my initial experiments I cannot get the original vendor driver to bind if any additional interfaces are added to the original descriptors. Would IAD help? Thanks. Ray. [This message has been edited by scene (edited August 01, 2008).] IP: Logged |
Tsuneo |
posted August 01, 2008 06:34 AM Hello Ray, "Is this possible? Sound like possible. "In my initial experiments I cannot get the original vendor driver to bind if any additional interfaces are added to the original descriptors. Did you modify the INF file of the original device? After modifying the INF file, delete the device instance of the original HID device once. Device instance records are held on the registry. Windows doesn't refresh it automatically, even when the device or INF file is changed. You have to do it manually. This utility is handy for this job. USBDeview For the additional keyboard and mouse, no INF file is required. Tsuneo IP: Logged |
scene |
posted August 01, 2008 09:08 AM Thanks for your prompt reply. Is there ANY way to do this without editing the .inf file? Alternatively, is there a way to make the vendor driver bind to the first interface found? Ray.
[This message has been edited by scene (edited August 01, 2008).] IP: Logged |
Tsuneo |
posted August 03, 2008 02:16 AM In above post, I described a popular method. But some tablet manufacturers implement the HID device in another way. I examined a Wacom tablet and it's device driver.
As this device tree shows, this HID tablet is recognized as generic HID device with the built-in HID driver using the default input.inf on Windows. Instead of providing a custom device driver directly to this device, Wacom installs HID minidrivers for the two virtual HID devices, one for mouse and one for keyboard. The minidrivers catch the generic HID device, and translate the device traffic into those of HID mouse and keyboard. Clever way.
For this configuration, there is no need to modify the INF file to make it a composite device or top-level collections. Tsuneo IP: Logged |
egawtry |
posted October 13, 2008 07:18 PM Tsuneo (or anyone who knows), I implemented this setup, but while I see the CDC just fine, I am not seeing the HID when I enumerate HIDs. Any ideas? If I have to I can post code, but I would like to avoid posting huge amounts of code. Above you mention changes to the INF file - could that be an issue? I am using my standard CDC driver INF. -Erik IP: Logged |
Tsuneo |
posted October 13, 2008 08:39 PM Hi Erik, At the top of the first post of this topic, I posted a composite device of CDC and HID, USB_CDC_HID_IAD_10.zip For a composite device of CDC, IAD (Interface Association Descriptor) is required. And it is supported after WinXP SP3 and Vista SP1. Tsuneo IP: Logged |
egawtry |
posted October 15, 2008 03:28 PM Ok, I must be a dummy because I cannot figure out several things: 1. Why do you have only one buffer for both input and output packets? 2. What do you mean by "loopback"? 3. Why was everything moved to the main loop and polled instead of leaving it in the interrupt? (Timing?) ================================== I am seeing the CDC and HID interfaces, but I cannot get the HID to read/write (it is always NULLs on the PC end). Any ideas there? Thanks, IP: Logged |
Tsuneo |
posted October 16, 2008 12:51 PM "1. Why do you have only one buffer for both input and output packets?" For loopback.
Loopback means, sending back the output report from the host directly to the host.
Which interrupt do you mean? When the data load/unload is handled in the endpoint interrupts, its timing is determined by the host. If the USB routines, POLL_WRITE_BYTE, etc., are called in a main loop task, these calls are guarded by disabling USB interrupt around the call, as the example shows. If the USB routines are called an other ISR like timer, no guard is required, but the interrupt priority of the ISR should be the same as USB ISR.
Modify Jan Axelson's HID example for host app, and check it. Tsuneo IP: Logged |
egawtry |
posted October 17, 2008 09:48 AM "Loopback means, sending back the output report from the host directly to the host. Orthodox way to check communication." Why would I want to do that? I just want to send packets to and from the device, like in the HID from INT example. I cannot do everything from the InputReport and OutputReport calls - the USB HID spec says that to do that is bad. I guess I will have to hack on it to resolve this. -Erik IP: Logged |
Tsuneo |
posted October 17, 2008 10:35 AM "Why would I want to do that?" Of course, you don't need to do that, once the USB side has been established. But I needed it to test the implementation. Also, it was needed to show the implementation works fine. As this topic has been discussed on the composite device, I posted the simplest implementation just along with the theme. The usage of HID endpoints was discussed on "How to convert USB_Interrupt (USB_INT) to HID". Then apply the experience to the HID endpoints to extend them. If you don't like this focused approach and request more detailed examples, sorry, it's beyond my personal project.
Huh? Tsuneo IP: Logged |
egawtry |
posted October 17, 2008 11:29 AM Tsuneo, Your code is something like this: OUT3_FIFO_loaded = FALSE; POLL_WRITE_BYTE( INDEX, 3 ); // loop back the data from OUT EP to IN EP EIE1 |= EUSB0_save; // restore USB interrupt That is great for loopback, but where do you handle the read and write of the basic data to the Host? In the "HID from INT" (good job there, btw) code, it is in the handler, but all you do in this handler is echo the data back to the host. There is no way to change it in the 34x. If I change the HID_InOut_Packet, it gets erased by the read before the write back to the host even occurs. -Erik IP: Logged |
Tsuneo |
posted October 17, 2008 01:31 PM OK, this is the separated version, without any cutting corner Tsuneo
USB_Main.h//-----------------------------------------------------------------------------// Global variables//----------------------------------------------------------------------------- extern BYTE xdata HID_Out_Packet[ HID_OUT_REPORT_SIZE ]; // Last packet received from hostextern BYTE xdata HID_In_Packet[ HID_IN_REPORT_SIZE ]; // packet to send to host USB_Main.c // HID loopback supportBYTE xdata HID_Out_Packet[ HID_OUT_REPORT_SIZE ]; // Last packet received from hostBYTE xdata HID_In_Packet[ HID_IN_REPORT_SIZE ]; // packet to send to host void main(void){ ... { // task2: USB EP3 handling - HID support // loopback from OUT to IN unsigned char EUSB0_save; unsigned char idx; // Read out from HID OUT EP if ( (Ep_StatusOUT3 != EP_HALT) && OUT3_FIFO_loaded ) { // To prevent conflict with USB interrupt EUSB0_save = EIE1 & 0x02; // save USB interrupt enable bit EIE1 &= ~0x02; // disable USB interrupt temporarily OUT3_FIFO_loaded = FALSE; POLL_WRITE_BYTE( INDEX, 3 ); // unload packet from OUT FIFO FIFO_Read_xdata( FIFO_EP3, HID_OUT_REPORT_SIZE, HID_Out_Packet ); POLL_WRITE_BYTE( EOUTCSRL, 0 ); // Clear Out Packet ready bit EIE1 |= EUSB0_save; // restore USB interrupt } // Write to HID IN EP if ( (Ep_StatusIN3 != EP_HALT) && IN3_FIFO_empty ) { // copy data for loopback for ( idx = 0; idx < HID_OUT_REPORT_SIZE; idx++ ) HID_In_Packet[idx] = HID_Out_Packet[idx]; // To prevent conflict with USB interrupt EUSB0_save = EIE1 & 0x02; // save USB interrupt enable bit EIE1 &= ~0x02; // disable USB interrupt temporarily IN3_FIFO_empty = FALSE; POLL_WRITE_BYTE( INDEX, 3 ); // load packet to IN FIFO FIFO_Write_xdata( FIFO_EP3, HID_IN_REPORT_SIZE, HID_In_Packet ); POLL_WRITE_BYTE( EINCSRL, rbInINPRDY ); // set FIFO ready flag EIE1 |= EUSB0_save; // restore USB interrupt } } }} USB_Class_Request.c//-----------------------------------------------------------------------------// Get_Report//----------------------------------------------------------------------------- static void Get_Report( void ){ if ( (Setup.bmRequestType == IN_CL_INTERFACE) && (Setup.wValue.c[LSB] == 0) ) // Report ID { switch ( Setup.wValue.c[MSB] ) { case HID_REPORT_TYPE_INPUT: // Input report DataPtr = (BYTE *)HID_In_Packet; // <------- modified DataSize = HID_IN_REPORT_SIZE; setup_handled = TRUE; break; [This message has been edited by Tsuneo (edited October 17, 2008).] IP: Logged |
egawtry |
posted October 17, 2008 02:12 PM Wow! That is exactly what I did to make it work! Great minds think alike, eh? :-) Thank you for the code. -Erik IP: Logged |
jeremy |
posted November 05, 2008 04:49 PM In Usb_Reset(), the status of each EP is set to EP_HALT: Ep_StatusIN1 = EP_HALT; Why is this necessary? The EP is only set to EP_IDLE on another SET_CONFIG. I'm finding Windows is issuing a USB reset, and my firmware then stops responding because the EP is "halted". IP: Logged |
Tsuneo |
posted November 05, 2008 07:02 PM In Usb_Reset(), the status of each EP is set to EP_HALT: Ep_StatusIN1 = EP_HALT; Why is this necessary? The EP is only set to EP_IDLE on another SET_CONFIG. I don't think this implementation has any problem. When the device receives bus reset, the device state moves to the DEFAULT state. EP1-3 should not respond to any access from the host side until the device state moves to CONFIGURED by Set_Configuration. In other word, to access the EPs other than the default EP, the host should issue Set_Address and Set_Configuration after bus reset - ie. re-enumeration.
Windows often put bus reset, unnecessarily. If it doesn't, it's a bug of Windows. Tsuneo IP: Logged |
egawtry |
posted November 10, 2008 12:34 PM Tsuneo, Any idea on how to get the pair of connections from Windows? (HID+CDC) I can easily find all the 342's HID and CDC connections, but there isn't any way I have found to pair them up. I am currently pairing them assuming that they are enumerated in order, eg. the first HID is the first CDC, the second HID is the second CDC, etc. - but I don't trust that algorythm. Windows has to have a call or a registry entry for Multi interfaces. Thanks for any ideas. -Erik IP: Logged |
Tsuneo |
posted November 11, 2008 07:59 AM Hi Erik, "Any idea on how to get the pair of connections from Windows? (HID+CDC) I can easily find all the 342's HID and CDC connections, but there isn't any way I have found to pair them up." Do you mean,
a) HID device path and serial number HID device is counted up using SetupDi- API, as usual. C:\SiLabs\MCU\Examples\C8051F34x\USB\USB_HID\BlinkyExample\Host\HIDDevice.cpp After opening the device handle using CreatFile, serial number of the HID device is retrieved using this API, HidD_GetSerialNumberString()
In this topic, I posted a short snippet that lists up COM port and serial number for CP210x. Actually, this snippet is applied to CDC virtual COM port, too, just by changing the VID/PID. "CP2102 & Vista registry" For your composite device, CString deviceID( _T("USB\\VID_10C4&PID_EA60\\") ); // device ID of CP210x VCP Modify above line like, CString deviceID( _T("USB\\VID_vvvv&PID_pppp&MI_mm\\") ); where, Then, you can retrieve COM port and serial number in a pair.
Tsuneo [This message has been edited by Tsuneo (edited November 11, 2008).] IP: Logged |
Myst1uk |
posted November 12, 2008 05:52 AM I have a simple question.. is it possible to modify one of the silicon labs HID examples to use an isochronous endpoint? IP: Logged |
Tsuneo |
posted November 13, 2008 04:39 AM "is it possible to modify one of the silicon labs HID examples to use an isochronous endpoint?" It's possible, but USB_Interrupt example is better. Tsuneo IP: Logged |
egawtry |
posted November 17, 2008 09:15 AM Tsuneo, I have already tried all you have suggested except for the serial number idea. I will try that. If I get it to work I will post it. One note, the MI_mm does NOT match between HID and CDC devices, in fact, the CDC device string does not include the MI_mm string. Also the MI_mm for the HID gets changed from the string in the INF to a random number. -Erik P.S. I tried your CDC serial number routine. It doesn't work. The DeviceID stuff on the right is junk. [This message has been edited by egawtry (edited November 17, 2008).] IP: Logged |
egawtry |
posted November 17, 2008 01:39 PM Figured it out: // Get the address of the selected deviceBOOL GetSerialNumberForCDC(LPCWSTR lpDevPath, LPWSTR lpAddress, UINT cbAddress){ // Check the VID PID WCHAR *ptrVID, *ptrPID, *ptrMI, *ptrCode;WORD wVID, wPID, wMI; if( cbAddress == 0 ) return FALSE; // Initialize *lpAddress = NULL;wVID = wPID = wMI = 0; // Get the VID and PID for the enum searchptrVID = wcsstr(lpDevPath, L"vid_"); ptrPID = wcsstr(lpDevPath, L"pid_");ptrMI = wcsstr(lpDevPath, L"mi_"); if( ptrVID ) wVID = (WORD)_xtoi(ptrVID+4);if( ptrPID ) wPID = (WORD)_xtoi(ptrPID+4); // Get the MI and the CODE pointerif( ptrMI ) { wMI = (WORD)_xtoi(ptrMI+3); ptrMI += 3;while( *ptrMI && (*ptrMI != '#') ) ++ptrMI; if( *ptrMI == '#' ) ptrCode = ++ptrMI; else ptrCode = NULL; } elsereturn FALSE; // found the code? if( ptrCode ) { // Find the USB enumed entry WCHAR wszKey[256];swprintf_s(wszKey, _countof(wszKey), L"SYSTEM\\ControlSet001\\Enum\\USB\\VID_%04X&PID_%04X", wVID, wPID);HKEY hKeyEnum, hKeyItem;if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, wszKey, 0, KEY_READ, &hKeyEnum) == ERROR_SUCCESS ){ // Search the sub-keys WCHAR wszName[256]; UINT iIndex = 0;while( RegEnumKey(hKeyEnum, iIndex++, wszName, _countof(wszName)) == ERROR_SUCCESS ){ // Open the sub-keyif( RegOpenKeyEx(hKeyEnum, wszName, 0, KEY_READ, &hKeyItem) == ERROR_SUCCESS ){ WCHAR wszData[256]; DWORD lData = _countof(wszData)*sizeof(WCHAR);DWORD dwType = REG_SZ; // Check the ParentIdPrefix for a matchif( RegQueryValueEx(hKeyItem, L"ParentIdPrefix", NULL, &dwType, (LPBYTE)wszData, &lData) == ERROR_SUCCESS ){ if( !wcsncmp(wszData, ptrCode, 10) ) { // Found the address! wcscpy_s(lpAddress, cbAddress, wszName);RegCloseKey(hKeyItem); break; } }RegCloseKey(hKeyItem); } } RegCloseKey(hKeyEnum); } }if( *lpAddress ) return TRUE; return FALSE;} Note: _xtoi() just converts a Hex string Note2: Fixed 11/19/2008: Change compare to only 10 chars to make it XP compatible.
[This message has been edited by egawtry (edited December 07, 2008).] IP: Logged |
Tsuneo |
posted November 17, 2008 04:37 PM "I tried your CDC serial number routine. It doesn't work. The DeviceID stuff on the right is junk." I see.
To get the parent DevInst, For HID, For CDC,
Tsuneo IP: Logged |
egawtry |
posted November 18, 2008 07:52 PM "I found a good answer on this issue"
I am also getting "OK" as my serial number from HidD_GetSerialNumberString() - looks like a parsing error. Of course, this messes up my matching by Serial Number. Now I have the CDC serial number, but not the HID! -Erik P.S. Figured out the "OK". Mia culpa. The Serial Number method works again.
[This message has been edited by egawtry (edited November 19, 2008).] IP: Logged |
egawtry |
posted December 10, 2008 08:00 PM Tsuneo, I have an implementation of the HID/CDC going. The problem is that if I send CDC serial data from the PC to the 340 in a steady stream, it stops receiving after 384 characters (my buffer is 240 chars). The funny thing is that it will still transmit to the PC unerringly. Any ideas? Should I post a zip of my code? Thanks, P.S. More details - if I send chumks of less than 384 chars it will send forever, but the second I use a 384 char chunk it dies.
[This message has been edited by egawtry (edited December 12, 2008).] IP: Logged |
egawtry |
posted December 12, 2008 04:22 PM Found it! It was a bug in the Handle_Out3. There needs to be two changes: if ( Ep_StatusOUT2 != EP_IDLE ) return; // If endpoint is ready 2. The fifo will fill, and then jam unless there is a check for size: if ( OUT2_FIFO_loaded && (TXcount < (TXBUFSIZE-EP2_OUT_PACKET_SIZE)) ) // FIFO has data?{ OUT2_FIFO_loaded = FALSE; #2 also is a bug in the standard CDC implementation. -Erik IP: Logged |
egawtry |
posted December 30, 2008 09:22 AM Question: How is stall handled? The reason I ask is I am having serious FIFO overruns on the USB. If the packet is not retrieved from the 34x's FIFO in time, it seems like another is stuffed by the host into the FIFO and lost. If I enable RTS/CTS on the host end, then it doesn't lose anything, but it also destablizes the host serial port within a few hundred bytes and starts randomly jumping around in the FIFO. HID works great. Thanks, IP: Logged |
egawtry |
posted January 03, 2009 11:45 AM Well, got it fixed. I moved the loaded flag to inside the size check so that the routine will call again if the size is too small, and I also added an else to send a stall.
void CDC_Handle_Bulk_HostOUT( void ){static BYTE FIFO_Cnt, first_cnt, second_cnt; static Ttxcnt pos; bit turnover;static BYTE ControlReg; // Temporary storage for EP control register if ( (Ep_StatusOUT2 == EP_IDLE) ) // If endpoint is ready{ if ( OUT2_FIFO_loaded ) // FIFO has packet? {EIE1 &= ~0x02; // disable USB interruptPOLL_WRITE_BYTE(INDEX, 2); // Set index to endpoint 2 registersPOLL_READ_BYTE(EOUTCNTL, FIFO_Cnt); // read out number of bytes on the FIFOpos = (TXBUFSIZE - TXcount); if( pos > 8 ) pos -= 8;if( pos >= FIFO_Cnt ) // if any room on the buffer to read out the FIFO{ OUT2_FIFO_loaded = FALSE; // total - offsetpos = TXBUFSIZE - TXWTIdx; // consider on wrap around of ring bufferif ( FIFO_Cnt < pos ) { first_cnt = FIFO_Cnt; second_cnt = 0;turnover = FALSE; } else { first_cnt = (BYTE)pos;second_cnt = FIFO_Cnt - first_cnt; turnover = TRUE; }FIFO_READ_FUNC( FIFO_EP2, first_cnt, &TXBuffer[ TXWTIdx ] ); // read bytes from FIFOif ( second_cnt != 0 ) FIFO_READ_FUNC( FIFO_EP2, second_cnt, TXBuffer );POLL_WRITE_BYTE(EOUTCSRL, 0); // Clear Out Packet ready and stalled bitsif ( turnover ) // maintainance of buffer parametersTXWTIdx = second_cnt; else TXWTIdx += FIFO_Cnt;TXcount += FIFO_Cnt; TXReady = (TXcount > 0); } // Not enough space to remove packet from hardware FIFO else {POLL_READ_BYTE(EOUTCSRL, ControlReg); // Read control register // stalled? if( !(ControlReg&rbOutSDSTL) ) { // Set the stall to prevent extra packets ControlReg |= rbOutSDSTL;} // Clear the Stall int flag ControlReg &= ~rbOutSTSTL;POLL_WRITE_BYTE(EOUTCSRL, ControlReg); }TXFull = (TXcount >= TXBUFSIZE-1);EIE1 |= 0x02; // enable USB interrupt } }} -Erik
[This message has been edited by egawtry (edited January 05, 2009).] IP: Logged |
egawtry |
posted January 26, 2009 09:52 AM Does anyone have INF files for Vista 64? The Vista 32 ones don't work. Since the CDC/HID uses built in drivers, there shouldn't be a driver certification problem... -Erik IP: Logged |
Patryk |
posted January 26, 2009 02:42 PM There was some post recently (about VCP driver I think). Vista 64 allows only signed drivers. Need to disable "driver security" (if I remember correctly) to overcome this. IP: Logged |
charlie8 |
posted January 26, 2009 11:46 PM Hi Tsuneo and all, I have implemented two single interface HID devices(one Mouse and one Keyboard)and tested it with XP-SP3. Individually they work fine. When I combine them as a composite device, only the first interface works. Windows recognizes it as composite device with two HID interfaces but indicates the second HID running into error while binding. If the first one is Mouse, then Keyboard fails; if the first one is Keyboard, then Mouse fails. USB bus analyzer shows that Get Descriptor for HID class request fails for the second interface - Windows sends out a SETUP token but no IN token to follow; after three times, it stops. Any help or ideas are highly appreciated. Thanks IP: Logged |
egawtry |
posted January 28, 2009 11:05 AM Charlie, Sounds familiar. Do you have the MI part of the PID/VID in place? If not, add "&MI_00" to the end of the MYDEV000 string. =========================== Patryk, Since we are using the built-in Vista drivers, signing shouldn't be a problem. =========================== -Erik [This message has been edited by egawtry (edited January 28, 2009).] IP: Logged |
Patryk |
posted January 29, 2009 07:02 AM Erik - remember that driver and it's INF file are integral parts of driver package that is being signed. Since there is no default INF file for CDC driver (signed together), you must provide one, and I'm sure it's not signed yet :-) IP: Logged |
egawtry |
posted January 29, 2009 10:30 AM So you are saying that we need to pay MS to certify their own drivers? Man, what a racket. -Erik IP: Logged |
WITTROCK |
posted January 29, 2009 11:26 AM So you are saying that we need to pay MS to certify their own drivers? Man, what a racket. Hey, I thought all this was going to change once Grand Pupa Bill Gates left! I guess not. -WITTROCK IP: Logged |
Patryk |
posted January 30, 2009 01:58 AM Erik - partially true: MS driver (binary) plus your's INF file. IP: Logged |
egawtry |
posted February 06, 2009 07:03 PM Workaround: 1. Boot Vista64 with driver signing disabled. ====================================== [Version] [Manufacturer] [MYCORP] [MYCORP.NTamd64] [DestinationDirs] [DEV000.NT] [DEV000.NTamd64] [DEV000.NT.HW] [DEV000.NTamd64.HW] [DEV000.NT.AddReg] [DEV000.NTamd64.AddReg] [DEV000.NT.HW.AddReg] [DEV000.NTamd64.HW.AddReg] ;-------------- Service installation [DEV000.NTamd64.Services] ; -------------- Serial Port Driver install sections ; -------------- Serenum Driver install section [Strings] Serenum.SVCDESC = "Serenum Filter Driver" -Erik
[This message has been edited by egawtry (edited February 06, 2009).] IP: Logged |
egawtry |
posted April 16, 2009 10:02 AM I am getting a strange problem on a customer's machine (Windows XP SP2). Everything installs great, they see the COM port, but nothing goes in or out of the PC. The HID section works just fine. The hardware works on several other computers. I have removed, manually deleted the OEMXX.INF in the Windows/INF folder and reinstalled, still no dice. Anyone with any ideas? Thanks, IP: Logged |
ferika |
posted July 21, 2011 05:50 AM BOARD: C8051F320DK ------------------- If i had error in USB_Type.h file: //#include then the communication working ok! But with the right setting: #include had no communication to the virtual COM. Any idea? IP: Logged |
egawtry |
posted July 21, 2011 11:25 AM Please repost with fixed <>. IP: Logged |
arunj123 |
posted November 25, 2011 10:56 PM COM port number for usb serial can be found by using wmi services. Here is an example. http://collectns.blogspot.com/2011/11/vbscript-for-detecting-usb-serial-com.html ------------------ IP: Logged |
Tsuneo |
posted November 25, 2011 11:49 PM For COM port number scan using WMI, this one is simpler. http://www.microchip.com/forums/fb.ashx?m=560699 Tsuneo |
egawtry Member |
posted April 27, 2009 07:55 PM
This is because the USB Composite Device thread is getting too long. IP: Logged |
egawtry Member |
posted April 27, 2009 08:01 PM
I am having issues with XPSP2 and CDC ports. The HID works great, but the CDC only sends the class messages, it will not send any data. Updating to XPSP3 fixes the issue, but requiring customers to do that is not an option. Anyone know what the problem is? Thanks, IP: Logged |
ReneK Member |
posted April 28, 2009 02:52 AM
This is a bug that got fixed with SP3. If SP3 is not an option, you need to drop usbser.sys and make your own driver. See: The Usbser.sys driver may not load when a USB device uses an IAD to define a function that has multiple interfaces, and this function uses the Usbser.sys driver file in Windows XP IP: Logged |
xiaofan Member |
posted April 28, 2009 04:14 AM
The hot fixes from Microsoft are necessary if you run XP SP2. They are not necessary if you run Vista or XP SP3. http://support.microsoft.com/kb/918365/en-us http://support.microsoft.com/kb/935892/en-us IP: Logged |
egawtry Member |
posted April 28, 2009 09:24 AM
Wow! Thanks Rene and Xaiofan! I'll try 'em out. -Erik [This message has been edited by egawtry (edited April 28, 2009).] IP: Logged |
egawtry Member |
posted April 29, 2009 10:03 AM
The bug mentioned in the knowledge base was exactly the issue I see, but the hotfix didn't fix it. Any other ideas? Thanks, IP: Logged |
xiaofan Member |
posted May 02, 2009 09:38 AM
I believe you need two hot fixes for XP SP2. Last time I tried it and it worked for me. IP: Logged |
xiaofan Member |
posted May 02, 2009 09:39 AM
I mean you need both hot fixes in the two links I posted. IP: Logged |
egawtry Member |
posted May 02, 2009 02:23 PM
The second hotfix you posted has to do with hibernation on a Tablet PC. Are you sure about the number? Thanks, IP: Logged |
xiaofan Member |
posted May 02, 2009 11:43 PM
Yes. This is according to the past posts in usb.org. IP: Logged |
xiaofan Member |
posted May 02, 2009 11:46 PM
Usbccgp.sys is very important file for USB Composite device. IP: Logged |
xiaofan Member |
posted May 03, 2009 08:00 AM
Faq from lvr.com http://www.lvr.com/serport.htm IP: Logged |
egawtry Member |
posted May 04, 2009 12:08 PM
Wow, with that second hotfix, it worked! Thanks to all. -Erik [This message has been edited by egawtry (edited May 04, 2009).] |
http://www.cygnal.org/ubb/Forum9/HTML/001050.html
http://www.cygnal.org/ubb/Forum9/HTML/001816.html