FEZ Portal Exception Error on USBHost RawDevice

Hi All.

I´m working with my FEZPortal using the provided sample code for USB Host. All is going fine if I connect a Mouse, a Keyboard or a USB Storage Device. But When I connect a FTDI USB-RS232 cable, Visual Studio isrising the following Exception.

“#### Exception System.InvalidOperationException - CLR_E_INVALID_OPERATION (3) ####
#### Message:
#### GHIElectronics.TinyCLR.Devices.UsbHost.RawDevice+Pipe::NativeTransfer [IP: 0000] ####
#### GHIElectronics.TinyCLR.Devices.UsbHost.RawDevice+Pipe::Transfer [IP: 004c] ####
#### GHIElectronics.TinyCLR.Devices.UsbHost.RawDevice+Pipe::Transfer [IP: 0013] ####
#### Program::UsbHostController_OnConnectionChangedEvent [IP: 0241] ####
#### GHIElectronics.TinyCLR.Devices.UsbHost.UsbHostController::OnConnectionChangedCallBack [IP: 0019] ####
#### GHIElectronics.TinyCLR.Devices.UsbHost.Provider.UsbHostControllerApiWrapper::<.ctor>b__6_0 [IP: 0042] ####
Excepción producida: ‘System.InvalidOperationException’ en GHIElectronics.TinyCLR.Devices.UsbHost.dll
Excepción no controlada del tipo ‘System.InvalidOperationException’ en GHIElectronics.TinyCLR.Devices.UsbHost.dll”

The same Exception is raised if I change FTDI USB-RS232 cable to a Prolific one.

Test code as follows:

using System.IO;
using System.Diagnostics;
using System.Threading;
using GHIElectronics.TinyCLR.Devices.UsbHost;
using GHIElectronics.TinyCLR.Devices.UsbHost.Descriptors;
using GHIElectronics.TinyCLR.Devices.Storage;
using GHIElectronics.TinyCLR.IO;
using GHIElectronics.TinyCLR.Pins;

class Program
{
static void Main()
{
var usbHostController = UsbHostController.GetDefault();

    usbHostController.OnConnectionChangedEvent +=
        UsbHostController_OnConnectionChangedEvent;

    usbHostController.Enable();

    Thread.Sleep(Timeout.Infinite);
}

private static void UsbHostController_OnConnectionChangedEvent
    (UsbHostController sender, DeviceConnectionEventArgs e)
{

    Debug.WriteLine("e.Id = " + e.Id + " \n");
    Debug.WriteLine("e.InterfaceIndex = " + e.InterfaceIndex + " \n");
    Debug.WriteLine("e.PortNumber = " + e.PortNumber);
    Debug.WriteLine("e.Type = " + ((object)(e.Type)).
        ToString() + " \n");

    Debug.WriteLine("e.VendorId = " + e.VendorId + " \n");
    Debug.WriteLine("e.ProductId = " + e.ProductId + " \n");

    switch (e.DeviceStatus)
    {
        case DeviceConnectionStatus.Connected:
            switch (e.Type)
            {
                case BaseDevice.DeviceType.Keyboard:
                    var keyboard = new Keyboard(e.Id, e.InterfaceIndex);
                    keyboard.KeyUp += Keyboard_KeyUp;
                    keyboard.KeyDown += Keyboard_KeyDown;
                    break;

                case BaseDevice.DeviceType.Mouse:
                    var mouse = new Mouse(e.Id, e.InterfaceIndex);
                    mouse.ButtonChanged += Mouse_ButtonChanged;
                    mouse.CursorMoved += Mouse_CursorMoved;
                    break;

                case BaseDevice.DeviceType.Joystick:
                    var joystick = new Joystick(e.Id, e.InterfaceIndex);
                    joystick.CursorMoved += Joystick_CursorMoved;
                    joystick.HatSwitchPressed += Joystick_HatSwitchPressed;
                    joystick.ButtonChanged += Joystick_ButtonChanged;
                    break;

                case BaseDevice.DeviceType.MassStorage:
                    var storageController = StorageController.FromName
                        (SC20260.StorageController.UsbHostMassStorage);
                    var driver = FileSystem.Mount(storageController.Hdc);
                    var driveInfo = new DriveInfo(driver.Name);

                    Debug.WriteLine("Free: " + driveInfo.TotalFreeSpace);
                    Debug.WriteLine("TotalSize: " + driveInfo.TotalSize);
                    Debug.WriteLine("VolumeLabel:" + driveInfo.VolumeLabel);
                    Debug.WriteLine("RootDirectory: " + driveInfo.RootDirectory);
                    Debug.WriteLine("DriveFormat: " + driveInfo.DriveFormat);

                    break;

                default:
                    var rawDevice = new RawDevice(e.Id, e.InterfaceIndex, e.Type);
                    var devDesc = rawDevice.GetDeviceDescriptor();
                    var cfgDesc = rawDevice.GetConfigurationDescriptor(0);
                    var endpointData = new byte[7];

                    endpointData[0] = 7;        //Length in bytes of this descriptor.
                    endpointData[1] = 5;        //Descriptor type (endpoint).
                    endpointData[2] = 0x81;     //Input endpoint address.
                    endpointData[3] = 3;        //Transfer type is interrupt endpoint.
                    endpointData[4] = 8;        //Max packet size LSB.
                    endpointData[5] = 0;        //Max packet size MSB.
                    endpointData[6] = 10;       //Polling interval.

                    var endpoint = new Endpoint(endpointData, 0);

                    var pipe = rawDevice.OpenPipe(endpoint);
                    pipe.TransferTimeout = 10;


                    var data = new byte[8];

                    var read = pipe.Transfer(data);

                    if (read > 0)
                    {
                        Debug.WriteLine("Raw Device has new data "
                            + data[0] + ", " + data[1] + ", " + data[2] + ", " + data[3]);
                    }

                    else if (read == 0)
                    {
                        Debug.WriteLine("No new data");
                    }


                    Thread.Sleep(500);
                    break;
            }
            break;

        case DeviceConnectionStatus.Disconnected:
            Debug.WriteLine("Device Disconnected");
            //Unmount filesystem if it was mounted.
            break;

        case DeviceConnectionStatus.Bad:
            Debug.WriteLine("Bad Device");
            break;
    }
}
private static void Keyboard_KeyDown(Keyboard sender, Keyboard.KeyboardEventArgs args)
{
    Debug.WriteLine("Key pressed: " + ((object)args.Which).ToString());
    Debug.WriteLine("Key pressed ASCII: " +
        ((object)args.ASCII).ToString());
}
private static void Keyboard_KeyUp(Keyboard sender, Keyboard.KeyboardEventArgs args)
{
    Debug.WriteLine("Key released: " + ((object)args.Which).ToString());
    Debug.WriteLine("Key released ASCII: " + ((object)args.ASCII).ToString());
}
private static void Mouse_CursorMoved(Mouse sender, Mouse.CursorMovedEventArgs e)
{
    Debug.WriteLine("Mouse moved to: " + e.NewPosition.X + ", " + e.NewPosition.Y);
}
private static void Mouse_ButtonChanged(Mouse sender, Mouse.ButtonChangedEventArgs args)
{
    Debug.WriteLine("Mouse button changed: " + ((object)args.Which).ToString());
}
private static void Joystick_ButtonChanged(Joystick sender, Joystick.ButtonChangedEventArgs e)
{
    Debug.WriteLine("Joystick button changed  = " + ((object)(e.Which)).ToString());
}
private static void Joystick_HatSwitchPressed(Joystick sender, Joystick.HatSwitchPressedEventArgs e)
{
    Debug.WriteLine("Joystick direction  = " + ((object)(e.Direction)).ToString());
}
private static void Joystick_CursorMoved(Joystick sender, Joystick.CursorMovedEventArgs e)
{
    Debug.WriteLine("Joystick.move  = " + e.NewPosition.X + ", " + e.NewPosition.Y);
}

}

Can somebody help me to solve this issue or provide some guidance?

Best Regards.
Mauricio.

FTDI and prolific are non standard USB devices. They do not conform to a standard class. You can use raw USB to access them but you need deep understanding of USB. If this is a maker project hen it is a fun challenge but if this is a commercial need then reach out directly and we can quote the price to implement such drivers for you please.