USB Host Failed on raptor

Using VS2013, netmf 4.3.4.0. working with a CerbuinoNet and connecting a USB HID to the host the device is recognized as unknown device of type 2 (I assume that’s a HID) and can get a device descriptor and working as expected.

But using pretty much the same code on a raptor the same device returns into a failed connect.

I have no explanation why the raptor reacts differently as the Cerbuinos ?

Anyone with an idea.

First the working CerbuinoNet code:


using System;
using Microsoft.SPOT;

// Added namespaces
using GHI.Usb.Host;
using System.Threading;

namespace cerbHID
{
    public class Program
    {
        private static RawDevice raw;

        public static void Main()
        {
            Controller.DeviceConnectFailed += Controller_DeviceConnectFailed;
            Controller.JoystickConnected += Controller_JoystickConnected;
            Controller.KeyboardConnected += Controller_KeyboardConnected;
            Controller.MassStorageConnected += Controller_MassStorageConnected;
            Controller.MouseConnected += Controller_MouseConnected;
            Controller.UnknownDeviceConnected += Controller_UnknownDeviceConnected;
            Controller.UsbSerialConnected += Controller_UsbSerialConnected;
            Controller.WebcamConnected += Controller_WebcamConnected;
            
            Controller.Start();

            BaseDevice[] allDevs = Controller.GetConnectedDevices();
            foreach (BaseDevice usbDev in allDevs)
            {
                Debug.Print("VID:" + usbDev.VendorId.ToString("X4"));
                Debug.Print("PID:" + usbDev.ProductId.ToString("X4"));
            }

            Thread.Sleep(Timeout.Infinite);
        }

        static void Controller_WebcamConnected(object sender, Webcam webcam)
        {
            Debug.Print("Webcam connected.");

            webcam.Disconnected += webcam_Disconnected;
        }

        static void webcam_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Webcam disconnected.");
        }

        static void Controller_MouseConnected(object sender, Mouse mouse)
        {
            Debug.Print("Mouse connected.");

            mouse.Disconnected += mouse_Disconnected;
        }

        static void mouse_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Mouse disconnected.");
        }

        static void Controller_MassStorageConnected(object sender, MassStorage storage)
        {
            Debug.Print("Mass storage connected.");

            storage.Disconnected += storage_Disconnected;
        }

        static void storage_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Mass storage disconnected.");
        }

        static void Controller_JoystickConnected(object sender, Joystick joystick)
        {
            Debug.Print("Joystick connected.");

            joystick.Disconnected += joystick_Disconnected;
        }

        static void joystick_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Joystick connected.");
        }

        static void Controller_UsbSerialConnected(object sender, UsbSerial usbserial)
        {
            Debug.Print("Usb Serial connected.");

            usbserial.Disconnected += usbserial_Disconnected;
        }

        static void usbserial_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Usb serial disconnected.");
        }

        static void Controller_UnknownDeviceConnected(object sender, Controller.UnknownDeviceConnectedEventArgs unknowndevice)
        {
        
            Debug.Print("Unknown Device connected.");
            Debug.Print("   ID   = " + unknowndevice.Id.ToString("X4"));
            Debug.Print("   Port = " + unknowndevice.PortNumber);
            Debug.Print("   VID  = " + unknowndevice.VendorId.ToString("X4"));
            Debug.Print("   PID  = " + unknowndevice.ProductId.ToString("X4"));
            Debug.Print("   Type = " + (BaseDevice.DeviceType)unknowndevice.Type);

            raw = new RawDevice(unknowndevice.Id, 
                                    unknowndevice.InterfaceIndex,
                                    unknowndevice.VendorId,
                                    unknowndevice.ProductId, 
                                    unknowndevice.PortNumber, 
                                    BaseDevice.DeviceType.HID);

            raw.Disconnected += raw_Disconnected;
            GHI.Usb.Descriptors.Device devdesc = raw.GetDeviceDescriptor();
            
            Debug.Print(devdesc.ToString());

        }

        static void raw_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Raw device disconnected");
        }

        private static void Controller_DeviceConnectFailed(object sender, EventArgs e)
        {
            Debug.Print("Failed.");
        }

        private static void Controller_KeyboardConnected(object sender, Keyboard keyboard)
        {
            Debug.Print("Keyboard connected.");

            keyboard.Disconnected += keyboard_Disconnected;
        }

        private static void keyboard_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Keyboard disconnected.");
        }
    }
}


and the Output:


The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Unknown Device connected.
   ID   = 200126E4
   Port = 0
   VID  = 0FDE
   PID  = CA01
   Type = 2
GHI.Usb.Descriptors.Device

Second the raptor code:



using System;
using Microsoft.SPOT;

// Added namespaces
using GHI.Usb.Host;
using System.Threading;
using Microsoft.SPOT.Hardware;
using Gadgeteer;
using GTM = Gadgeteer.Modules;

namespace raptorHID
{
    public class Program
    {
        private Gadgeteer.Modules.GHIElectronics.USBHost usbHost = new GTM.GHIElectronics.USBHost(7);
        private static RawDevice raw;

        public static void Main()
        {
            Controller.DeviceConnectFailed += Controller_DeviceConnectFailed;
            Controller.JoystickConnected += Controller_JoystickConnected;
            Controller.KeyboardConnected += Controller_KeyboardConnected;
            Controller.MassStorageConnected += Controller_MassStorageConnected;
            Controller.MouseConnected += Controller_MouseConnected;
            Controller.UnknownDeviceConnected += Controller_UnknownDeviceConnected;
            Controller.UsbSerialConnected += Controller_UsbSerialConnected;
            Controller.WebcamConnected += Controller_WebcamConnected;

            Controller.Start();

            BaseDevice[] allDevs = Controller.GetConnectedDevices();
            foreach (BaseDevice usbDev in allDevs)
            {
                Debug.Print("VID:" + usbDev.VendorId.ToString("X4"));
                Debug.Print("PID:" + usbDev.ProductId.ToString("X4"));
            }

            Thread.Sleep(Timeout.Infinite);
        }


        static void Controller_WebcamConnected(object sender, Webcam webcam)
        {
            Debug.Print("Webcam connected.");

            webcam.Disconnected += webcam_Disconnected;
        }

        static void webcam_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Webcam disconnected.");
        }

        static void Controller_MouseConnected(object sender, Mouse mouse)
        {
            Debug.Print("Mouse connected.");

            mouse.Disconnected += mouse_Disconnected;
        }

        static void mouse_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Mouse disconnected.");
        }

        static void Controller_MassStorageConnected(object sender, MassStorage storage)
        {
            Debug.Print("Mass storage connected.");

            storage.Disconnected += storage_Disconnected;
        }

        static void storage_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Mass storage disconnected.");
        }

        static void Controller_JoystickConnected(object sender, Joystick joystick)
        {
            Debug.Print("Joystick connected.");

            joystick.Disconnected += joystick_Disconnected;
        }

        static void joystick_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Joystick connected.");
        }

        static void Controller_UsbSerialConnected(object sender, UsbSerial usbserial)
        {
            Debug.Print("Usb Serial connected.");

            usbserial.Disconnected += usbserial_Disconnected;
        }

        static void usbserial_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Usb serial disconnected.");
        }

        static void Controller_UnknownDeviceConnected(object sender, Controller.UnknownDeviceConnectedEventArgs unknowndevice)
        {
            Debug.Print("Unknown Device connected.");
            Debug.Print("   ID   = " + unknowndevice.Id.ToString("X4"));
            Debug.Print("   Port = " + unknowndevice.PortNumber);
            Debug.Print("   VID  = " + unknowndevice.VendorId.ToString("X4"));
            Debug.Print("   PID  = " + unknowndevice.ProductId.ToString("X4"));
            Debug.Print("   Type = " + (BaseDevice.DeviceType)unknowndevice.Type);

            raw = new RawDevice(unknowndevice.Id,
                                    unknowndevice.InterfaceIndex,
                                    unknowndevice.VendorId,
                                    unknowndevice.ProductId,
                                    unknowndevice.PortNumber,
                                    BaseDevice.DeviceType.HID);

            raw.Disconnected += raw_Disconnected;
            GHI.Usb.Descriptors.Device devdesc = raw.GetDeviceDescriptor();

            Debug.Print(devdesc.ToString());

        }

        static void raw_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Raw device disconnected");
        }

        private static void Controller_DeviceConnectFailed(object sender, EventArgs e)
        {
            Debug.Print("Failed.");
        }

        private static void Controller_KeyboardConnected(object sender, Keyboard keyboard)
        {
            Debug.Print("Keyboard connected.");

            keyboard.Disconnected += keyboard_Disconnected;
        }

        private static void keyboard_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Keyboard disconnected.");
        }

    }
}


And its outcome:


The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Failed.
Failed.
Failed.

Any help would be much appriciated.

@ PiWi - Are you connecting the device after the device starts up and starts the USB host controller or before?

@ John, program on cerbuino and raptor started first and after that inserted the device.

Reaction as described above. I must note as well that sometimes I have to insert the usb device more than once to get an event triggered…

Having the CerbuinoNet with a USB Host already inserted device and hitting F5 in VS2013 gives no devices at all using main program:


        public static void Main()
        {
            Debug.Print("Program started ...");

            Controller.DeviceConnectFailed += Controller_DeviceConnectFailed;
            Controller.JoystickConnected += Controller_JoystickConnected;
            Controller.KeyboardConnected += Controller_KeyboardConnected;
            Controller.MassStorageConnected += Controller_MassStorageConnected;
            Controller.MouseConnected += Controller_MouseConnected;
            Controller.UnknownDeviceConnected += Controller_UnknownDeviceConnected;
            Controller.UsbSerialConnected += Controller_UsbSerialConnected;
            Controller.WebcamConnected += Controller_WebcamConnected;
            
            Controller.Start();

            BaseDevice[] allDevs = Controller.GetConnectedDevices();
            Debug.Print("Devices connected = " + allDevs.Length);
            if (allDevs.Length > 0)
            {
                foreach (BaseDevice usbDev in allDevs)
                {
                    Debug.Print("  VID: " + usbDev.VendorId.ToString("X4") + (", PID:" + usbDev.ProductId.ToString("X4")));
                }
            }
            
            Debug.Print("Program sleeping forever ...");
            Thread.Sleep(Timeout.Infinite);
        }

With the outcome:


The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Program started ...
Devices connected = 0
Program sleeping forever ...

Than, having the CerbuinoNet with no host device connected, hitting F5 in VS 2013 I did the following:

 1. Connected a thumb drive
 2. Disconnected the thumb drive again
 3. Connected the HID device

got the following with outcome so I’m a little bit further:


The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Program started ...
Devices connected = 0
Program sleeping forever ...
Mass storage connected.
Mass storage disconnected.

Unknown Device connected.
   ID   = 20010CBC
   Port = 0
   VID  = 0FDE
   PID  = CA01
   Type = 2
Number of configurations . . . 1
Max Packet size  . . . . . . . 8
Protocol code  . . . . . . . . 00
Release number . . . . . . . . 302
Serial number index  . . . . . 00
Subclass code  . . . . . . . . 00
USB sepecification number  . . 110
  === Interface ===
  Class: HID
  SubClass: 0
  Number: 0
  Protocol: 0
  Type: 4
   -- Endpoint --
    Attributes: 3
    Address: 129
    Type: 5
    Interval: 1

strange, using exact the same code as in the first post. Firing up with VS2013 and with inserted thumb drive gives the following:


'Microsoft.SPOT.Debugger.CorDebug.12.dll' (Managed): Loaded 'C:\Program Files (x86)\GHI Electronics\GHI .NET Gadgeteer SDK\Modules\USBHost\NETMF 4.3\le\GTM.GHIElectronics.USBHost.dll', Symbols loaded.
'Microsoft.SPOT.Debugger.CorDebug.12.dll' (Managed): Loaded 'C:\Users\Peter\documents\visual studio 2013\Projects\raptorHID\raptorHID\bin\Debug\le\raptorHID.exe', Symbols loaded.
The thread '<No Name>' (0x2) has exited with code 0 (0x0).
Mass storage connected.
Mass storage disconnected.
Failed.
Mass storage connected.

Here I took the thumb drive out, inserted the HID device (failed), disconnected the HID device and inserted the thumb drive again … ???

At least here the raptor detected the device with a little delay after startup, that did not happen on the CerbuinoNet.

@ PiWi - We are taking a look into this, we’ll let you know what we find.

@ John - Thanks

@ PiWi - What HID device are you using?

Oregon Scientific sensor hub, PID/VID in above posts …

Any specific info you’re looking for ?

It basically converts the RF protocol to USB 1.1 http://www.osengr.org/WxShield/Downloads/OregonScientific-RF-Protocols-II.pdf

The windows software used for this sensor hub can be found on http://wmrx00.sourceforge.net/

The device itself is called WMRS200

@ PiWi - We have not been able to reproduce it with anything we have tried. We would be happy to take a look if you sent the HID device to us to investigate.

@ John - Thanks for the helping hand, the address to send to is ?

@ PiWi - Contact Us – GHI Electronics

Wow, full stop …

I already had this made in NetMf 4.1 almost two years back ?? :wall:

Man, I must be getting very old to forget about this …

Found it on an old harddisk somewere hanging in my intranet, it was done as a test console project on a Cobra. I’ll make it again using the Cerberus and than after good working have it done on a Raptor to see if there are still issues …

I never cease to amaze myself … I’ll be back …

Welcome to my world! :open_mouth:

1 Like

@ PiWi - Put it on Codeshare. That way we will never forget. ;D

@ Architect - I’ll do so as soon as I have the VS2013 version up and running …

And this whole time I thought I was the only who suffered this condition.

@ Gary - not enough memory left so end up using ‘memory.Dispose()’ a lot more often. :smiley:

@ Sprigo - ah, so that was the command I have been trying to remember! 8)

First step - Getting to make the USB to work … so far on CerbuinoBee … working is @ 9000+ iteration and still going strong …

… and who mentioned that it couldn’t be done in VS2013 in a gadgeteer project …

Next step is probably a little more difficult, getting the closed protocol analysed and parse and etc. USB spits at 5 secs interval always 8 bytes what ever they may mean at the moment only hex codes to me …

The solution was NOT as usual through a seperate USB class inhereting the RawDevice, that ran into a Controller error 2 directly, so I used a plain old gadgeteer timer of 5 secs, since the station doesn’t allow faster … errors out as well :naughty:

Here a bit of my proto-code:


    public partial class Program
    {
        // USB Host variables used for the WMRS200 weather station
        static RawDevice wmrs;
        static RawDevice.Pipe wmrsPipe;
        private byte[] wmrsData = null;

        static int usbErr = 0;
        static int usbOK = 0;

        // This method is run when the mainboard is powered up or reset.   
        void ProgramStarted()
        {
            GT.Timer timer = new GT.Timer(1000);
            timer.Tick += timer_Tick;
            timer.Start();

            characterDisplay.Clear();
            characterDisplay.Print("OK:000000 ERR:00");

            TimeSpan mytime = new TimeSpan(0, 0, 5);
            multicolorLED.FadeRepeatedly(GT.Color.Red, mytime, GT.Color.Green, mytime);

            Controller.UnknownDeviceConnected += Controller_UnknownDeviceConnected;
            Controller.Start();

            // Use Debug.Print to show messages in Visual Studio's "Output" window during debugging.
            Debug.Print(SystemInfo.OEMString + " " + SystemInfo.Version);
            Debug.Print("Gadgeteer: Main Program Ended");
        }

        static bool blinky = false;
        void timer_Tick(GT.Timer timer)
        {
            characterDisplay.SetCursorPosition(0, 3);
            characterDisplay.Print(usbOK.ToString("G6"));
            characterDisplay.SetCursorPosition(0, 12);
            characterDisplay.Print(usbErr.ToString("G2"));
        }

        void Controller_UnknownDeviceConnected(object sender, Controller.UnknownDeviceConnectedEventArgs e)
        {
            Debug.Print("Unknown Device with VID: " + e.VendorId.ToString("X4") + " and PID: " + e.ProductId.ToString("X4") + " connected");

            wmrs = new RawDevice(e.Id, e.InterfaceIndex, e.VendorId, e.ProductId, e.PortNumber, BaseDevice.DeviceType.HID);
            wmrs.Disconnected += wmrs_Disconnected;
            GHI.Usb.Descriptors.Device devDes = wmrs.GetDeviceDescriptor();

            // 2. Assuming we have only 1, so get the first configuration
            GHI.Usb.Descriptors.Configuration conDes = wmrs.GetConfigurationDescriptor(0);

            // 3. Make an endpoint
            GHI.Usb.Descriptors.Endpoint wmrsEP = null;

            // Loop thru all interfaces 
            for (int i = 0; i < conDes.Interfaces.Length; i++)
            {
                // ? HID is 0x03 ?
                if (conDes.Interfaces[i].ClassCode == 0x03)
                {
                    // Look for input interrupt Endpoint
                    for (int ep = 0; ep < conDes.Interfaces[i].Endpoints.Length; ep++)
                    {
                        // Is it interrupt Endpoint?
                        if (conDes.Interfaces[i].Endpoints[ep].Attributes == 0x03)
                        {
                            // Need to setup interrupt handler to handle data
                            wmrs.SendSetupPacket(0x00, 0x09, conDes.Value, 0x00);

                            // 
                            wmrsEP = conDes.Interfaces[i].Endpoints[ep];   // Set endpoint
                            wmrsPipe = wmrs.OpenPipe(wmrsEP);              // Open pipe
                            wmrsPipe.TransferTimeout = 0;

                            // Init the station
                            byte[] wmrsReset = { 0x20, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00 };
                            wmrs.SendSetupPacket((byte)0x21, (byte)0x09, (ushort)0x0200, (ushort)0x0000, wmrsReset, 0, wmrsReset.Length);

                            // Maximum data in PacketSize
                            wmrsData = new byte[wmrsPipe.Endpoint.MaximumPacketSize];

                            // Set up receiving timer
                            GT.Timer wmrsRecorder = new GT.Timer(5000);
                            wmrsRecorder.Tick += wmrsRecorder_Tick;
                            wmrsRecorder.Start();
                            
                        }
                    }
                }
            }

        }

        void wmrsRecorder_Tick(GT.Timer timer)
        {
            // One moment please
            timer.Stop();

            // Show we are alive
            Mainboard.SetDebugLED(true);

            int count;
            string test = "";

            try
            {
                count = wmrsPipe.Transfer(wmrsData);

                // Reset result string
                test = string.Empty;

                // Let us see what we have received if at all
                for (int i = 0; i < wmrsData.Length; i++)
                {
                    test += wmrsData[i].ToString("X2") + " ";
                }

                Debug.Print(count.ToString("X2") + " : " + test);

                // Arriving here means all went OK, kind of, well, at least no exception
                usbOK++;
            }
            catch (Exception ex)
            {
                // Oops
                usbErr++;
                Debug.Print(ex.ToString());
            }

            // Continue
            Mainboard.SetDebugLED(false);
            timer.Start();
        }

        void wmrs_Disconnected(BaseDevice sender, EventArgs e)
        {
            Debug.Print("Device disconnected");
        }

Any tips and thoughts are welcome … up to part two …