I\'m trying to fix a non-responsive USB device that\'s masquerading as a virtual COM port. Manual replugging works, but there may be up to 12 of these units. Is there an API
The device itself may be able to do this (ie, perform a USB disconnect/reconnect sequence).
Have you contacted the device manufacturer, or if you are the manufacturer, the EE's that designed it?
I had to do this when I designed a USB embedded device - programming could be accomplished through USB, but the device had to be able to disconnect and reconnect at several points to complete the process.
Beyond that there's the brute force method of disabling the USB host device in device manager (I assume this can be done in software) and then re-enabling it.
If nothing else, Phidget has USB controlled relay boards which you can use to connect power or the USB lines themselves to hubs or individual devices.
-Adam
We used this to programmable disconnect usb devices.
As Greg Hewgill said, I don't think that it's possible.
Initiation of the whole usb startup is triggered by the usb slave (in your case your device). The usb host (the pc) can send a message to the device to tell it to shut down, but once it's done that it's up to the device to start back up again. The host can't force it to.
To make matters worse you'll quite possibly find that the usb device is detecting the plug being inserted (by detecting the usb voltage on the power lines) to start up. This is particularly true of bus powered devices.
It sounds like there are differences from your situation and the case of trying to unmount/remount usb drives. When the usb drive is unmounted there is no reason that it can't stay enumerated on the pc. You're not actually reseting the usb drive, just making it's filesystem inactive.
You can use the C# Hardware Helper Lib and add the ResetDevice function.
public bool ResetDevice( IntPtr hDevInfo, IntPtr devInfoData )
// Need to add
// public const int DICS_PROPCHANGE = ((0x00000003));
// at the public class Native under //PARMS
int szOfPcp;
IntPtr ptrToPcp;
int szDevInfoData;
IntPtr ptrToDevInfoData;
Native.SP_PROPCHANGE_PARAMS pcp = new Native.SP_PROPCHANGE_PARAMS();
pcp.ClassInstallHeader.cbSize = Marshal.SizeOf(typeof(Native.SP_CLASSINSTALL_HEADER));
pcp.ClassInstallHeader.InstallFunction = Native.DIF_PROPERTYCHANGE;
pcp.StateChange = Native.DICS_PROPCHANGE; // for reset
pcp.Scope = Native.DICS_FLAG_CONFIGSPECIFIC;
pcp.HwProfile = 0;
szOfPcp = Marshal.SizeOf(pcp);
ptrToPcp = Marshal.AllocHGlobal(szOfPcp);
Marshal.StructureToPtr(pcp, ptrToPcp, true);
szDevInfoData = Marshal.SizeOf(devInfoData);
ptrToDevInfoData = Marshal.AllocHGlobal(szDevInfoData);
Marshal.StructureToPtr(devInfoData, ptrToDevInfoData, true);
bool rslt1 = Native.SetupDiSetClassInstallParams(hDevInfo, ptrToDevInfoData, ptrToPcp, Marshal.SizeOf(typeof(Native.SP_PROPCHANGE_PARAMS)));
bool rstl2 = Native.SetupDiCallClassInstaller(Native.DIF_PROPERTYCHANGE, hDevInfo, ptrToDevInfoData);
if (rslt1 && rstl2)
{
return true;
}
return false;
}
I've looked at this for automated tests. The best solution we came up with seems to be the ability of USB hubs to disconnect devices when they draw too much power. From a USB pserspective, it appears the USB host may instruct a hub to do so. With 12 devices, you will have hubs, so I'd suggest to investigate that path.
If you have more than one of these on any particular host machine, you might save some time/frustration by plugging them into their own dedicated USB hub out from the machine - at least it's only one cable to unplug/plug to restart a couple of devices at a time.
You've probably thought of that, of course. :-)