USB Mass storage client issue?

I have an SD card connected to socket 9 on a Raptor board which is mounted at startup and can be read and written without problems.

For external access to the files on the SD card I am exposing it as USB client mass storage by the following method (newest SDK 4.3 2014 R5), which is called in a btn_TapEvent routine after tapping a button on the T43 touch screen:


public static void AttachAsMassStorage()
{      
    if (sdCard.IsCardMounted)
      sdCard.Unmount(); // can't be used as USB client mass storage while mounted for appl. usage
    if (ms == null)
      ms = new MassStorage();
    Controller.ActiveDevice = ms;
    GHI.IO.Storage.SDCard sdAsMSC = new GHI.IO.Storage.SDCard();
    ms.AttachLogicalUnit(sdAsMSC, 0, "", "");
    ms.EnableLogicalUnit(0); // enable external access         
    ModalResult msgBoxResult = Glide.MessageBoxManager.Show("Message", "Title", ModalButtons.Ok);
    // user has finished file access via PC now ->
    // detach mass storage and remount SD card to the application
    ms.DisableLogicalUnit(0);        // after this, drive is shown on PC but can't be accessed
    Controller.ActiveDevice = null;  // should remove the drive completely       
}

Exposing the SD card to an external PC via AttachLogicalUnit() and EnableLogicalUnit() and accessing it from there works fine, DisableLogicalUnit() also works as expected.

My problem is, that I can’t get it managed to detach the USB client mass storage and re-mount the SD card for further use by the application.

Setting Controller.ActiveDevice = null executes without exception and the corresponding drive letter is removed from the PC’s explorer window, but after property assignment it always takes around 10 sec. and the Raptor does an unintended reset.

It doesn’t make a difference, if I place the above codelines there or, maybe more favourably, in the sdCard_Unmounted event:
The device is always resetted around 10 sec. later as a result of the Controller.ActiveDevice = null property assignment, so I don’t have the chance to sdCard.Mount() again. If I try to re-mount the card without nulling the Controller.ActiveDevice property, #### GHI.IO.Storage.SDCard::NativeConstructor [IP: 0000] #### exception is thrown.

I am not sure whether it’s maybe a similar issue as stated in #9 in https://www.ghielectronics.com/community/forum/topic?id=17121&page=1 or if I’m just doing something wrong. Any working approach for detaching USB mass storage client and remounting the SD card to the application would be very welcome.

[em]Addition:[/em] I found that setting the Controller.ActiveDevice to a new CDC() (instead of detaching the MSC by nulling it) works as a temporary workaround. After subsequent disposal of the GHI.IO.Storage.SDCard object (sdAsMSC) I then can remount the SD Card to the application (w/ sdCard.Mount) and repeat the procedure as often as necessary without any issue.

But the “reboot problem”, triggered by setting Controller.ActiveDevice = null remains, independently of VS 2012 Debug or Release mode or running as Release w/out VS.

@ Harald - Can you try to create a new and minimum example that just works with the USB client mass storage and see if that fails?

@ John - Good idea, I’ll do this and post the results as soon as possible …

@ John - I have built the following bare Gadgeteer Raptor test application, only SD card and USB DP in “Program.generated.cs”, no display, but the problem is similar:

private void InitializeModules() {
this.usbClientDP = new GTM.GHIElectronics.USBClientDP(8);
this.sdCard = new GTM.GHIElectronics.SDCard(9);
}



using System;
using System.Threading;
using Microsoft.SPOT;

using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using Gadgeteer.Modules.GHIElectronics;

using GHI.Usb.Client;
using GHI.Processor;

namespace MSCTest
{
  public partial class Program
  {
    private static MassStorage ms;
    private static GHI.IO.Storage.SDCard sdAsMSC;

    void ProgramStarted()
    {     
      Debug.Print("Program Started");

      if (GHI.Processor.Display.Disable()) // if it returns true, a reboot is needed
      {
        Debug.Print("Reboot required due to disabling display");
        Microsoft.SPOT.Hardware.PowerState.RebootDevice(false);
      }
      sdCard.Mounted += sdCard_Mounted;
      sdCard.Unmounted += sdCard_Unmounted;
    }

    void sdCard_Mounted(SDCard sender, GT.StorageDevice device)
    {
      Debug.Print("Dispatcher running, SD card mounted");
      sdCard.Unmount();
    }

    void sdCard_Unmounted(SDCard sender, EventArgs e)
    {
      Debug.Print("SD card unmounted");
      
      if (ms == null)
        ms = new MassStorage();
      
      Controller.ActiveDevice = ms;
      
      if (sdAsMSC == null)
        sdAsMSC = new GHI.IO.Storage.SDCard();
      
      ms.AttachLogicalUnit(sdAsMSC, 0, "Vendor", "MSCTest" );
      ms.EnableLogicalUnit(0); // enable host access   
      Thread.Sleep(5000);      // just because there's no button, set a breakpoint here and continue debugging
      ms.DisableLogicalUnit(0);
      Controller.ActiveDevice = null;
      
      if (sdAsMSC != null)
      {                  
        sdAsMSC.Dispose();
      }      
      sdCard.Mount(); // remount SD card for renewed usage in application      
    }
  }
}

Debug output is as follows:
Using mainboard GHI Electronics FEZ Raptor version 1.0
Program Started
Dispatcher running, SD card mounted
SD card unmounted

Everything works fine (SD card exposed as mass storage to the PC and also correctly disabled, but not detached, thereafter) until it comes to execution of “Controller.ActiveDevice = null;”. This assignment leads to a reboot, sometimes with the exception below and sometimes without:

Exception System.InvalidOperationException - CLR_E_INVALID_OPERATION (1)

#### Message: 
#### GHI.Usb.Client.Controller::NativeStop [IP: 0000] ####
#### GHI.Usb.Client.Controller::set_ActiveDevice [IP: 0008] ####
#### MSCTest.Program::sdCard_Unmounted [IP: 0021] ####
#### Gadgeteer.Modules.GHIElectronics.SDCard::OnUnmounted [IP: 0036] ####
#### System.Reflection.MethodBase::Invoke [IP: 0000] ####
#### Gadgeteer.Program::DoOperation [IP: 001a] ####
#### Microsoft.SPOT.Dispatcher::PushFrameImpl [IP: 0054] ####
#### Microsoft.SPOT.Dispatcher::PushFrame [IP: 001a] ####
#### Microsoft.SPOT.Dispatcher::Run [IP: 0006] ####
#### Gadgeteer.Program::Run [IP: 001d] ####

Error invoking method “Gadgeteer.Modules.GHIElectronics.SDCard” (check arguments to Program.BeginInvoke are correct)
Using mainboard GHI Electronics FEZ Raptor version 1.0
Program Started
Dispatcher running, SD card mounted
SD card unmounted

@ Harald - there is a known issue right now where assigning null to ActiveDevice improperly throws an exception that will be fixed in a coming SDK. The only workaround is to assign another valid device. You also do not want to do all of this work inside the Unmounted event handler, you want to exit from those as quickly as possible.

1 Like

@ John - Many thanks for going into things thoroughly so quickly. I will remain with my workaround for the moment, in expectation of the next SDK.

Thank you also for the tip, not to do too much stuff the event handlers. I gave it another try, doing it in a separate thread, but with the same result :’(

Hi,
I am trying to make Mass Storage with FEZ Raptor, but with no success. I use part of Haralds code:



           MassStorage ms = null;

            try
            {
                if (sdCard.IsCardMounted)
                    sdCard.Unmount(); // can't be used as USB client mass storage while mounted for appl. usage
                if (ms == null)
                    ms = new MassStorage();
                Controller.ActiveDevice = ms;
                GHI.IO.Storage.SDCard sdAsMSC = new GHI.IO.Storage.SDCard();
                ms.AttachLogicalUnit(sdAsMSC, 0, "", "");
                ms.EnableLogicalUnit(0); // enable external access        
                ms.DisableLogicalUnit(0);        // after this, drive is shown on PC but can't be accessed
                Controller.ActiveDevice = null;  // should remove the drive completely    
               
            }
            catch(Exception ex)
            {
                Mainboard.SetDebugLED(true);
            }

when debugging there is always problem when try to Controller.ActiveDevice = ms;

can anyone help me please?

@ Jana - The SDK with the fix described above has yet to be released.

Ok, is there any way to make mass storage from Fez Raptor? Harald said that he can see his SD card in PC as mass storage, I see only G400 connected to PC. Thanks for reply

@ Jana - https://www.ghielectronics.com/docs/20/usb-client#108 should work on the Raptor.

Not working, in debug it always fall on Controller.ActiveDevice = ms; end throw

Exception System.InvalidOperationException - CLR_E_INVALID_OPERATION (1)

#### Message: 
#### GHI.Usb.Client.RawDevice::NativeInitialize [IP: 0000] ####
#### GHI.Usb.Client.RawDevice::Activate [IP: 00f3] ####
#### GHI.Usb.Client.Controller::set_ActiveDevice [IP: 0015] ####
#### Test.MFMassStorage.Raptor.Program::ProgramStarted [IP: 0009] ####
#### Test.MFMassStorage.Raptor.Program::Main [IP: 0015] ####

if not debugging raptor alwasy appaer as G400 in PC.

@ Jana - Are you debugging over USB or serial?

USB

@ Jana - You cannot use USB debugging and USB client at the same time. If you want to use USB client, you must debug over serial.

How can i use Serial debugging, by usb serial module?

and even if you don’t want to debug set the debugging interface as serial…

You just have to manage the MODE PIN (PA25). Please have a look on page 20 of the G400 Manual

I set PA25 to low, but stil canot see raptor as mass storage and when I try to serial debug there is an error : Error 1 Unable to communicate with device Serial:COM7

Edit: Now when I set PA25 to low, I can see USB device but it cannot be recognized on my WIn 8.1 64bit and when I try to install USB driver from GHI, it says that my drivers are up to date. I hope I can get it working on windows 8.1

There is an error message: A request for the USB device descriptor failed.
I have two Raptor board and this isues is on both of them.

Is there anyone with same problem? Or do you know if this can be windows or hardware problem?

@ Jana - What is the device name and type that shows up that does not let you install drivers?

It shows as unknown USB device, windows try to install drivers but always failed and show
A request for the USB device descriptor failed.