USB issues with SCM20260D

Hello, I am new to the TinyCLR OS, but am having some issues with getting the USB to work. When mounting a USB drive (that is formated in FAT32, MBR) I get an exception. I have tried a lot of things but nothing has worked. I get the same result on the DEV board as well as our own device. Please Help.

Code:
public bool usbA_En_Dis(char E_D)
{
var _Enable = GpioController.GetDefault().OpenPin(SC20260.GpioPin.PB10);
_Enable.SetDriveMode(GpioPinDriveMode.Output);

        if (E_D == 'E')
        {
            _Enable.Write(GpioPinValue.Low); return true;
        }
        _Enable.Write(GpioPinValue.High); return false;
    }

    public void usbHostController()
    {
        var host = UsbHostController.GetDefault();
        host.OnConnectionChangedEvent += USB_Connection_Event;
        host.Enable();
    }

    private static void USB_Connection_Event(UsbHostController Sender, DeviceConnectionEventArgs eve)
    {
        Debug.WriteLine("eve.Id = " + eve.Id + " \n");
        Debug.WriteLine("eve.InterfaceIndex = " + eve.InterfaceIndex + " \n");
        Debug.WriteLine("eve.PortNumber = " + eve.PortNumber + " \n");
        Debug.WriteLine("eve.Type = " + ((object)(eve.Type)).ToString() + " \n");
        Debug.WriteLine("eve.VendorId = " + eve.VendorId + " \n");
        Debug.WriteLine("eve.ProductId = " + eve.ProductId + " \n" + " \n" + " \n");

        if(eve.DeviceStatus == DeviceConnectionStatus.Connected && eve.Type == BaseDevice.DeviceType.MassStorage)
        {
            try
            {
                var storageController   = StorageController.FromName(SC20260.StorageController.UsbHostMassStorage);
                var driver              = FileSystem.Mount(storageController.Hdc);
                var driveInfo           = new DriveInfo(driver.Name);
            }
            catch(Exception exe)
            {
                Debug.WriteLine("Exception Thrown");
            }
        }           
    }

Output:
eve.Id = 604376448

eve.InterfaceIndex = 0

eve.PortNumber = 0

eve.Type = 6

eve.VendorId = 6509

eve.ProductId = 513

#### Exception System.InvalidOperationException - CLR_E_INVALID_OPERATION (3) ####
#### Message: 
#### GHIElectronics.TinyCLR.IO.FileSystem::Initialize [IP: 0000] ####
#### GHIElectronics.TinyCLR.IO.FileSystem::Mount [IP: 0024] ####
#### USB_Proto.FLP200::USB_Connection_Event [IP: 00b2] ####
#### GHIElectronics.TinyCLR.Devices.UsbHost.UsbHostController::OnConnectionChangedCallBack [IP: 0019] ####
#### GHIElectronics.TinyCLR.Devices.UsbHost.Provider.UsbHostControllerApiWrapper::<.ctor>b__6_0 [IP: 0042] ####

Exception thrown: ‘System.InvalidOperationException’ in GHIElectronics.TinyCLR.IO.dll

Thank you in advance.

Looks like your enable pin is getting GC’d. Save a reference to it.

I’ll try that. Thank you.

No dice, the enable pin is turning power on to the USB, which the system would not detect the device if it didn’t stay on, which it is detecting it meaning the pin is staying low. I did reference it better to ensure this isn’t the problem just in case but it still gives an exception when trying to mount the drive.

have you tried it with a different SD card?

its a usb flash not SD, but I could try another.

Again, no change.

I have also tried the GHI code (found here: USBHost fails) and it still throughs an exception when mounting, I am truly lost as to what could be causing this.

Exception thrown: ‘System.InvalidOperationException’ in GHIElectronics.TinyCLR.IO.dll

I am not at a location to check the schematic. Why are you enabling a pin?

Is this a custom board?

Yes, it is a custom board, we enable a relay to make the USB active. This part I know is working because if I do not enable the pin it won’t detect a usb drive connected/disconnected (the connect and disconnect events are working)

I have also tried on the dev board without this part, same issue.

It is on this line “var driver = FileSystem.Mount(storageController.Hdc);” that throws the exception on both boards.

Have you tried with a powered usb hub?

The system is powered by a external power supply, so power shouldn’t be the issue, First thing I did was check power in the system (great minds think alike), gets 5V with 2A available. I do not have a powered USB hub readily available but will have to give it a try.

The powered hub addresses a power issue, which you appear to have addressed.

Could you post a complete minimal program so I can run it on a board I have?

I would also try two things (no particular order) :

  • FAT16 format
  • A delay before trying to mount the drive

#region System
using System;
//using System.Collections;
//using System.ComponentModel;
using System.Diagnostics;
//using System.Drawing;
//using System.Globalization;
using System.IO;
//using System.Net;
//using System.Reflection;
//using System.Resources;
//using System.Runtime;
//using System.Security;
//using System.Text;
//using System.Threading;
#endregion
#region IO
using GHIElectronics.TinyCLR.IO;
//using GHIElectronics.TinyCLR.IO.TinyFileSystem;
#endregion
#region Data
//using GHIElectronics.TinyCLR.Data;
//using GHIElectronics.TinyCLR.Data.Json;
//using GHIElectronics.TinyCLR.Data.SQLite;
//using GHIElectronics.TinyCLR.Data.Xml;
#endregion
#region Pins
using GHIElectronics.TinyCLR.Pins;
#endregion
#region Native
//using GHIElectronics.TinyCLR.Native;
#endregion
#region Networking
//using GHIElectronics.TinyCLR.Networking;
//using GHIElectronics.TinyCLR.Networking.Mqtt;
#endregion
#region UI
//using GHIElectronics.TinyCLR.UI;
//using GHIElectronics.TinyCLR.UI.Controls;
//using GHIElectronics.TinyCLR.UI.Input;
//using GHIElectronics.TinyCLR.UI.Media;
//using GHIElectronics.TinyCLR.UI.Shapes;
//using GHIElectronics.TinyCLR.UI.Threading;
#endregion
#region Update
//using GHIElectronics.TinyCLR.Update;
#endregion
#region Cryptography
//using GHIElectronics.TinyCLR.Cryptography;
//using GHIElectronics.TinyCLR.Cryptography.CryptoServiceProvider;
//using GHIElectronics.TinyCLR.Cryptography.Provider;
#endregion
#region Devices
//using GHIElectronics.TinyCLR.Devices;
//using GHIElectronics.TinyCLR.Devices.Adc;
//using GHIElectronics.TinyCLR.Devices.Can;
//using GHIElectronics.TinyCLR.Devices.Dac;
//using GHIElectronics.TinyCLR.Devices.Display;
using GHIElectronics.TinyCLR.Devices.Gpio;
//using GHIElectronics.TinyCLR.Devices.I2c;
//using GHIElectronics.TinyCLR.Devices.Modbus;
//using GHIElectronics.TinyCLR.Devices.Network;
//using GHIElectronics.TinyCLR.Devices.Onewire;
//using GHIElectronics.TinyCLR.Devices.Pwm;
//using GHIElectronics.TinyCLR.Devices.Rtc;
//using GHIElectronics.TinyCLR.Devices.SecureStorage;
//using GHIElectronics.TinyCLR.Devices.Signals;
//using GHIElectronics.TinyCLR.Devices.Spi;
using GHIElectronics.TinyCLR.Devices.Storage;
//using GHIElectronics.TinyCLR.Devices.Uart;
//using GHIElectronics.TinyCLR.Devices.UsbClient;
using GHIElectronics.TinyCLR.Devices.UsbHost;
//using GHIElectronics.TinyCLR.Devices.Watchdog;
#endregion

namespace USB_Proto
{
class FLP200 : IFLP
{
private GpioPin _Enable;

    public bool usbA_En_Dis(char E_D)
    {
        _Enable = GpioController.GetDefault().OpenPin(SC20260.GpioPin.PB10);
        _Enable.SetDriveMode(GpioPinDriveMode.Output);

        if (E_D == 'E')
        {
            _Enable.Write(GpioPinValue.Low); return true;
        }
        _Enable.Write(GpioPinValue.High); return false;
    }

    public void usbHostController()
    {
        var host = UsbHostController.GetDefault();
        host.OnConnectionChangedEvent += USB_Connection_Event;
        host.Enable();
    }

    private static void USB_Connection_Event(UsbHostController Sender, DeviceConnectionEventArgs eve)
    {
        Debug.WriteLine("eve.Id = " + eve.Id + " \n");
        Debug.WriteLine("eve.InterfaceIndex = " + eve.InterfaceIndex + " \n");
        Debug.WriteLine("eve.PortNumber = " + eve.PortNumber + " \n");
        Debug.WriteLine("eve.Type = " + ((object)(eve.Type)).ToString() + " \n");
        Debug.WriteLine("eve.VendorId = " + eve.VendorId + " \n");
        Debug.WriteLine("eve.ProductId = " + eve.ProductId + " \n" + " \n" + " \n");

        if(eve.DeviceStatus == DeviceConnectionStatus.Connected && eve.Type == BaseDevice.DeviceType.MassStorage)
        {
            try
            {
                var storageController   = StorageController.FromName(SC20260.StorageController.UsbHostMassStorage);
                var driver              = FileSystem.Mount(storageController.Hdc);
                var driveInfo           = new DriveInfo(driver.Name);
            }
            catch(Exception exe)
            {
                Debug.WriteLine("Exception Thrown");
            }
        }

       
    }
}

}

using System;
using System.Collections;
using System.Text;
using System.Threading;
using GHIElectronics.TinyCLR.Pins;
using GHIElectronics.TinyCLR.IO;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Devices.UsbHost;
using System.Diagnostics;

namespace USB_Proto
{
public interface IFLP
{
bool usbA_En_Dis(char E_D);

    void usbHostController();

}

}

using System;
using System.Collections;
using System.Text;
using System.Threading;
using GHIElectronics.TinyCLR.Pins;
using GHIElectronics.TinyCLR.IO;
using GHIElectronics.TinyCLR.Devices.Gpio;
using GHIElectronics.TinyCLR.Devices.UsbHost;
using System.Diagnostics;

namespace USB_Proto
{
public class Program
{
static IFLP usbDevice = new FLP200();

    static void Main()
    {
        try
        {
            usbDevice.usbA_En_Dis('E'); //Enable Power to USB port.
            usbDevice.usbHostController();
            while (true) { }
        }
        catch(Exception exc)
        {
            Debug.WriteLine(exc.ToString());
        }
    }


}

}

I figured it out, the drive I reformatted to MBR, but did not setup a simple volume on it so it was not accessible. In disk manager setup a simplevolume and no more exception. Thank you for the help.

Great!

I noticed While (true) {} in your Main. Not a good practice if you are doing any threading or event handling. Better to use Thread.Sleep(Timeout.Infinite);

You don’t want your main thread to be competing for resources with your other threads.

Good advice, I normally don’t but you are absolutely correct. (Coding is more of a secondary skill for me, I do more hardware design lol)