SDCard code strange behavior

Hi
I have finally made my code read from SDCard, so it’s is a succes.
I have seen this code used many places on the forum when working with SDCard


public class Program
{
    // evt is used to avoid the possibility that accesses to the 
    // mounted file system do not occur until mount()
    // is fully done.
    
    private static AutoResetEvent evt = new AutoResetEvent(false);

    //Make sure to set the pin to your sd card detect pin.
    private static InputPort sdCardDetect = new InputPort(GHI.Pins.FEZSpiderII.Socket5.Pin3, false, Port.ResistorMode.Disabled);

    public static void Main()
    {
        RemovableMedia.Insert += new InsertEventHandler(RemovableMedia_Insert);
        RemovableMedia.Eject += new EjectEventHandler(RemovableMedia_Eject);

        // Start auto mounting thread
        new Thread(SDMountThread).Start();
        evt.WaitOne(); // yield here until mounting and initializing is finished

        // Your program goes here
        // ...

    }

    // This event is fired by unmount; not neccesarily by physical ejection of media
    static void RemovableMedia_Eject(object sender, MediaEventArgs e)
    {
        Debug.Print("SD card unmounted, eject event fired");
        // as desired signal other thread(s) in application
        // that unmount occurred
    }

    static void RemovableMedia_Insert(object sender, MediaEventArgs e)
    {
        Debug.Print("Insert event fired; SD card mount is finished.");

        // insert code here for anything the program wants to do immediately
        // after mounting occurs...

        if (e.Volume.IsFormatted)
        {
            Debug.Print("Available folders:");
            string[] strs = Directory.GetDirectories(e.Volume.RootDirectory);
            for (int i = 0; i < strs.Length; i++)
                Debug.Print(strs[i]);

            Debug.Print("Available files:");
            strs = Directory.GetFiles(e.Volume.RootDirectory);
            for (int i = 0; i < strs.Length; i++)
                Debug.Print(strs[i]);
        }
        else
        {
            Debug.Print("SD card is not formatted. Formatting...");

            // VolumeInfo is the class that contains volume information for a specific
            //      media.
            // .GetVolumes()[0] aquires the first volume on the device. Change the 
            //      index for different volumes.
            // .Format("FAT", 0); Selects the "FAT" file system as the format type.
            VolumeInfo.GetVolumes()[0].Format("FAT", 0);
        }
        evt.Set(); // proceed with other processing
    }

    public static void SDMountThread()
    {
        SDCard SD = null;
        const int POLL_TIME = 500; // check every 500 millisecond

        bool sdExists;
        while (true)
        {
            try // If SD card was removed while mounting, it may throw exceptions
            {
                sdExists = sdCardDetect.Read();

                // make sure it is fully inserted and stable
                if (sdExists)
                {
                    Thread.Sleep(50);
                    sdExists = sdCardDetect.Read();
                }

                if (sdExists && SD == null)
                {
                    SD = new SDCard();
                    SD.Mount();
                }
                else if (!sdExists && SD != null)
                {
                    SD.Unmount();
                    SD.Dispose();
                    SD = null;
                }
            }
            catch
            {
                if (SD != null)
                {
                    SD.Dispose();
                    SD = null;
                }
            }

            Thread.Sleep(POLL_TIME);
        }
    }
}

But when i used it on my Spider II board it didn’t work.
The sdCardDetect.Read() returned true when no card was inserted and false when card was inserted… So I reverted the sdExists check and now it works… So why does my Read check return the opposite than others using this code ??

The working SDMountThread code:


 public static void SDMountThread()
    {
        SDCard SD = null;
        const int POLL_TIME = 500; // check every 500 millisecond

        bool sdExists;
        while (true)
        {
            try // If SD card was removed while mounting, it may throw exceptions
            {
                sdExists = sdCardDetect.Read();

                // make sure it is fully inserted and stable
                if (!sdExists)
                {
                    Thread.Sleep(50);
                    sdExists = sdCardDetect.Read();
                }

                if (!sdExists && SD == null)
                {
                    SD = new SDCard();
                    SD.Mount();
                }
                else if (sdExists && SD != null)
                {
                    SD.Unmount();
                    SD.Dispose();
                    SD = null;
                }
            }
            catch
            {
                if (SD != null)
                {
                    SD.Dispose();
                    SD = null;
                }
            }

            Thread.Sleep(POLL_TIME);
        }
    }

@ janfl - If you look at the schematic for the SD card, you will see that there is a pull up resistor connected to the card detect pin. Therefore, you will get a true when there is not a card installed. When you insert a card, the CD pin is pulled to ground, resulting in a false.

Okay but when will the code posted on the forum ever result in other than an error when it says to mount the sdcard when read is true?

I would hope you could never mount a SD without one inserted.

Think you misunderstand me. If you look at the first section of code then the code that mount the sdcard is only run if the Read() return true and according to you and my own investigation that only happen when no card is inserted… :slight_smile:

But nevermind the code is working now :slight_smile:

Mount is only executed if sdExists is NOT true AND SD is null.