Yoiks. This was a bit of a pain to figure out!
I fixed that for you and since you asked, here’s my test program which seems to be working well. Not a ton of comments but I did note things that took me a while to figure out.
You need to set switch 4 (leftmost when looking at the Spider with the button above the switches) to the down position and reboot it for the mass storage stuff to work.
using System.Threading;
using Microsoft.SPOT;
using Gadgeteer;
using Gadgeteer.Modules.GHIElectronics;
using GHIElectronics.NETMF.USBClient;
using GHIElectronics.NETMF.Glide;
using GHIElectronics.NETMF.Glide.UI;
using GHIElectronics.NETMF.Hardware;
using GHIElectronics.NETMF.IO;
namespace UsbMassStorage
{
public partial class Program
{
private USBC_MassStorage mMassStorage;
private Button mButtonPc;
private TextBox mText;
private int mCounter = 0;
private const string GLIDE_XML = "<Glide Version=\"1.0.3\">" +
"<Window Name=\"instance115\" Width=\"320\" Height=\"240\" BackColor=\"FFFFFF\">" +
"<Button Name=\"mButtonPc\" X=\"120\" Y=\"16\" Width=\"80\" Height=\"32\" Alpha=\"255\" Text=\"PC Control\" Font=\"3\" FontColor=\"000000\" DisabledFontColor=\"808080\" TintColor=\"000000\" TintAmount=\"0\"/>" +
"<TextBox Name=\"mText\" X=\"0\" Y=\"80\" Width=\"320\" Height=\"32\" Alpha=\"255\" Text=\"\" TextAlign=\"Left\" Font=\"4\" FontColor=\"000000\"/>" +
"</Window>/Glide>";
void ProgramStarted()
{
mSdCard.DebugPrintEnabled = true;
mSdCard.SDCardMounted += new SDCard.SDCardMountedEventHandler(SdCard_SDCardMounted);
mSdCard.SDCardUnmounted += new SDCard.SDCardUnmountedEventHandler(SdCard_SDCardUnmounted);
GlideTouch.Initialize();
Glide.MainWindow = GlideLoader.LoadWindow(GLIDE_XML);
mText = (TextBox)Glide.MainWindow.GetChildByName("mText");
mButtonPc = (Button)Glide.MainWindow.GetChildByName("mButtonPc");
mButtonPc.TapEvent += new OnTap(ButtonPc_TapEvent);
DisplayCounts();
}
void SdCard_SDCardUnmounted(SDCard sender)
{
Debug.Print("card unmounted");
}
void SdCard_SDCardMounted(SDCard sender, StorageDevice SDCard)
{
Debug.Print("card mounted");
DisplayCounts();
}
private void DisplayCounts()
{
// make sure there's actually a card in there
if (!mSdCard.IsCardInserted)
{
MessageBox("No card!", "Please insert an SD card and try again");
return;
}
// if it's not mounted, try mounting it then wait a little for it to mount
if (!mSdCard.IsCardMounted)
{
mSdCard.MountSDCard();
// also wait for the storage device.. not sure that's 100% needed but
// think i've seen it take a second to come back after the mount
for (int i = 0; i < 100 && (!mSdCard.IsCardMounted || mSdCard.GetStorageDevice() == null); i++)
Thread.Sleep(100);
}
if (!mSdCard.IsCardMounted)
{
MessageBox("Can't mount SD card!", "Unable to mount SD card!");
return;
}
StorageDevice sd = mSdCard.GetStorageDevice();
if (sd == null)
{
// likely are trying to do something without giving time back to the
// dispatcher or .net or something.. once we unwind the stack all the
// way, the storage device will be there
MessageBox("Can't get StorageDevice!", "There's something wrong with your code");
return;
}
mText.Text = "(" + mCounter++.ToString() + ") Volume: '" + sd.Volume.Name +
"', dirs = " + sd.ListDirectories(@ "\").Length.ToString() +
", files = " + sd.ListFiles(@ "\").Length.ToString();
mText.Invalidate();
}
private static void MessageBox(string title, params object []args)
{
MessageBox(title, ModalButtons.Ok, args);
}
private static ModalResult MessageBox(string title, ModalButtons butts, params object[] args)
{
MessageBoxManager mgr = new MessageBoxManager();
string msg = "";
foreach (object arg in args)
{
msg += " " + arg.ToString();
}
return mgr.Show(msg, title, butts);
}
private void ButtonPc_TapEvent(object sender)
{
bool wasMounted = mSdCard.IsCardMounted;
try
{
// can't do mass storage while we have the card mounted
if (wasMounted)
mSdCard.UnmountSDCard();
// can't do mass storage while we're set to use the usb port for debug
if (Configuration.DebugInterface.GetCurrent() == Configuration.DebugInterface.Port.USB1)
{
MessageBox("USB in use", "USB is currently in use for debugging!");
return;
}
try
{
// don't call Start more than once - you'll get exceptions
if (mMassStorage == null)
mMassStorage = USBClientController.StandardDevices.StartMassStorage();
}
catch (System.Exception ex)
{
MessageBox("D'oh! Can't start mass storage", ex.Message);
return;
}
// try getting a PersistantStorage instance for the card
PersistentStorage storage = null;
ModalResult result = ModalResult.Ok;
while (result == ModalResult.Ok)
{
try
{
storage = new PersistentStorage("SD");
break;
}
catch
{
result = MessageBox("SD card not detected", ModalButtons.OkCancel, "Please insert an SD card then press Ok or press Cancel to quit");
}
}
if (result == ModalResult.Ok)
{
// stuff works! pop up a modal so the user can tell us when they're done
mMassStorage.AttachLun(0, storage, " ", " ");
mMassStorage.EnableLun(0);
MessageBox("USB<->SD enabled.", "Click Ok when done.");
}
// disable the connection
mMassStorage.DisableLun(0);
if (storage != null)
{
// toss the PersistantStorage instance
storage.UnmountFileSystem();
Thread.Sleep(2000); // needed? maybe.. dunno
// make sure to dispose of it (or use 'using') so we can use the gadgeteer
// stuff again right away
storage.Dispose();
}
}
finally
{
// remount the card, if it was was mounted before
if (wasMounted)
mSdCard.MountSDCard();
// it's tempting to call DisplayCounts again here but it won't work.. we're
// still on the call stack from the dispatcher and need to unwind that all
// the way before we can use the card here again. Instead, call DisplayCounts
// on the mounted event
}
}
}
}
edit: other bit of the partial:
using Gadgeteer;
using GTM = Gadgeteer.Modules;
namespace UsbMassStorage
{
public partial class Program : Gadgeteer.Program
{
// GTM.Module defintions
Gadgeteer.Modules.GHIElectronics.SDCard mSdCard;
Gadgeteer.Modules.GHIElectronics.UsbClientDP mUsbClient;
Gadgeteer.Modules.GHIElectronics.Display_T35 mDisplay;
public static void Main()
{
//Important to initialize the Mainboard first
Mainboard = new GHIElectronics.Gadgeteer.FEZSpider();
Program program = new Program();
program.InitializeModules();
program.ProgramStarted();
program.Run(); // Starts Dispatcher
}
private void InitializeModules()
{
// Initialize GTM.Modules and event handlers here.
mUsbClient = new GTM.GHIElectronics.UsbClientDP(1);
mSdCard = new GTM.GHIElectronics.SDCard(5);
mDisplay = new GTM.GHIElectronics.Display_T35(14, 13, 12, 10);
}
}
}