Another possible problem with USBC_Mass_Storage

I’ve noticed that if I plug in the USB cable and wait about 10 seconds, unplug it and wait about 10 seconds and repeat somewhere between the second and 5th time the USB cable is inserted I get a ‘unrecognized hardware error’. Looking up the USB devices in Device Manager shows that indeed Windows has no clue what it is. The short bit of code below will produce the error. I’m not sure how common it would be repeatably plug/unplug a USB device but…

using System;
using System.IO;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Hardware.UsbClient;

using GHIElectronics.NETMF.USBClient;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.Hardware;

namespace USBClientConnectError
{
    public class Program
    {
        public static void Main()
        {
            USBC_MassStorage ms = USBClientController.StandardDevices.StartMassStorage();
            USBClientController.State USBState;

            while (true)
            {
                USBState = USBClientController.GetState();
                Debug.Print("USBState " + USBState.ToString());
                Thread.Sleep(500);
            }
            
        }

    }
}

So once device is not recognized, if you disconnect and reconnect, would it work again?

I think the problem is that when the cable is disconnected I’m not stopping the USBClientController after the cable is disconnected. I tried the code below where the USBClientController is stopped and then restarted 5 seconds later when a cable dissconnect is sensed. This seems to do the tricked.

using System;
using System.IO;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.IO;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Hardware.UsbClient;

using GHIElectronics.NETMF.USBClient;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.Hardware;

namespace USBClientConnectError
{
    public class Program
    {
        public static void Main()
        {
            USBC_MassStorage ms = USBClientController.StandardDevices.StartMassStorage();
            USBClientController.State USBState;
            USBClientController.State lastState = USBClientController.State.Default;

            while (true)
            {
                USBState = USBClientController.GetState();
                Debug.Print("USBState " + USBState.ToString());

                if (USBState == USBClientController.State.Suspended
                    & lastState == USBClientController.State.Running)
                {
                    Debug.Print("Dissconnected");
                    USBClientController.Stop();
                    Thread.Sleep(5000);
                    USBClientController.StandardDevices.StartMassStorage();
                }
                lastState = USBState;
                Thread.Sleep(100);
            }
            
        }

    }
}

You do not have to stop it. We tested unplugging and plugging many times. When Windows not recognize it, try to unplug and plug it again, maybe it will work.

When Windows does not recognize the FEZ it is because the ClientController stays in the ‘Running’ state and never goes back into ‘Suspended’. I suspect since the FEZ is stuck in the wrong state it is not communicating properly with Windows. Once you get the ‘Device not recognized’ error you have to reset the FEZ to be able to connect again.

I’m running another test program now that disconnects the client controller when the the cable is unplugged. If I poll the ClientController.State() at 100ms it will not fail, if I poll at 1000ms intervals it will fail. This makes me think something in the client controller code is timing out? Perhaps you guys did not intend for someone to poll it repeatably to provide an event driven interface?

Polling should not affect it. We will look into this for next release.

I found something interesting this morning. I have been keeping the USB cable plugged into the Domino and plugging/unplugging it into the PC as is is a bit easier that way. With the 100ms polling rate for the USBClientController.State I would see an intermittent change in state from Suspended (normal unplugged state) to Attached. I modified the code so it only did a Debug.Print on state changes so I could see it easier.

If I removed the dangling USB cable from the Domino the state remained rock steady on Suspended, as it should. With a USB cable attached to the Domino the state randomly alternates between Suspended and Attached. My only guess is that the USB cable is acting like an antenna and picking up enough noise to confuse the USB hardware. I’ve tried this with two different good quality USB cables and see the same thing with both. My test code seems to perform quite well if I do not leave the USB cable dangling off the FEZ.

FWIW: Here is a link to my test code: http://soigeneris.com/Documents/USB_Client.zip

I am not a USB expert (Mike is) but I want to point out that windows maybe causing problems not the device. USB, with its hot pluggable feature, can easily cause problems.

I have no doubt that part of the issue could be something funny that Windows is doing, or some strange thing related to a debug build, etc. Generally when troubleshooting I find it helpful to assume that I have done something stupid, as 99.9% of the time that is what happens, sometimes a problem occurs due to an undocumented side effect of a certain function, sometimes it is a software bug, sometimes it is hardware related. Most of the time though it is safe to assume it is my own doing.

It seems a good deal of the problem was with the USB cable left hanging off the Domino and its USB client controller randomly changing states because of it. Again, something silly I was doing that may have been causing the whole trouble. The test code I linked too seems very stable if you plug/unplug the USB cable at the Domino.

Come to think of it I should put a scope on my power adapter and see how noisy it is, perhaps it is the source of the noise causing the problem.