File System to UART

I am trying to read files off of the SD card and send them through the UART (COM1) of my Panda II.

I have been working with the Serial PC to UART example and the File system examples, but I just cant get the code right.

So far, this is what I have:

public static void Main()
        {
            SerialPort UART = new SerialPort("COM1", 9600);

            int counter = 0;
            UART.Open();

           // ...
            // SD Card is inserted
            // Create a new storage device
            PersistentStorage sdPS = new PersistentStorage("SD");
 
            // Mount the file system
            sdPS.MountFileSystem();
 
 
            // Assume one storage device is available, access it through 
            // Micro Framework and display available files and folders:
            Debug.Print("Getting files and folders:");
            if (VolumeInfo.GetVolumes()[0].IsFormatted)
            {
                string rootDirectory = 
                    VolumeInfo.GetVolumes()[0].RootDirectory;
                string[] files = Directory.GetFiles(rootDirectory);
                
 
                Debug.Print("Files available on " + rootDirectory + ":");
                for (int i = 0; i < files.Length; i++)
                    Debug.Print(files[i]);
 
                
            }

Thank you for the help in advance!

Great to see you’re stepping through the learning process.

What would help us here is figuring out WHAT doesn’t work, you haven’t told us anything!

Your code looks incomplete - is that your issue?

Now you need to send the file - first open the file and read a bit in, then send through UART, then read more in, then send more through UART, and stop when you have no more left.

What are you expecting to do with the data at the other end?

@ Brett - Yeah I’ve been taking a lot in this past couple of days!

Yes my code is incomplete, I have been trying and deleting things. I have the COM1 port open and that’s about it.

First, I just want to see the ray bytes from TeraTerm. Then from there I have buddy working on inturpriting the data.

I have tried using something along the lines of the code below:

byte[] buffer = Encoding.UTF8.GetBytes(rootDirectory);
                // send the bytes on the serial port
                UART.Write(buffer, 0, buffer.Length);
                // increment the counter;
                counter++;
                //wait...

While you’re troubleshooting this, create a text file to play with, call it readme.txt, put in there some text that says hello world. Then try to open the file and make sure you get the file’s contents in whatever buffer you’re going to do. That code just opens “the root directory” and I don’t know what that actually would do! It’s not what you want to achieve anyhow.

I think the next example you should look at is one that uses a filestream. Here’s one that implements this in a class but you can see the building blocks… http://www.tinyclr.com/codeshare/entry/348

@ Brett - Ok Thanks. What would make sense to me is that in the code above, this UART.Write takes place instead of the Debug.Print. But it is never that easy is it! (like shown below)

 string rootDirectory = 
                    VolumeInfo.GetVolumes()[0].RootDirectory;
                string[] files = Directory.GetFiles(rootDirectory);
                
 
                UART.Write("Files available on " + rootDirectory + ":");
                for (int i = 0; i < files.Length; i++)
                    UART.Write(files[i]);

Actually, it IS that simple.

The only curveball is that you need and get STRINGs for directory and file lists, but you need BYTEs for the UART. So a quick UTF8 conversion will help.

            Debug.Print("Getting files and folders:");
            if (VolumeInfo.GetVolumes()[0].IsFormatted)
            {
                string rootDirectory =
                    VolumeInfo.GetVolumes()[0].RootDirectory;
                string outstr="Files in "+rootDirectory+"\r\n";
                string[] files = Directory.GetFiles(rootDirectory);
                UART.Write(UTF8Encoding.UTF8.GetBytes(outstr),0,outstr.Length);

                Debug.Print("Files available on " + rootDirectory + ":");
                for (int i = 0; i < files.Length; i++)
                {
                    Debug.Print(files[i]);
                    outstr=files[i]+"\r\n";
                    UART.Write(UTF8Encoding.UTF8.GetBytes(outstr), 0, outstr.Length);
                }

            }

@ Brett - Oh I see! Cool, that worked good!

Thanks for the help again Brett!

So now I’m so close to getting to my final goal. Ultimately, I want to have the Panda appear as a MSD and then when I push the LDR button, it will disable MSD, so I can access the files and send them through UART.

So far, I tried to implement your code and Instead of listing files names on the SD, TeraTerm outputs this…

[quote]#### Exception System.Exception - 0xffffffff (3) ####
#### Message:
#### GHIElectronics.NETMF.USBClient.USBC_MassStorage::DisableLun [IP: 0000] ####
#### FEZ_Panda_II_Application1.Program::IntButton_OnInterrupt [IP: 0008] ####
Uncaught exception[/quote]

It worked in a standalone program to see the files in TeraTerm, but not after disabling MSD. I’ll post my code as well.

namespace FEZ_Panda_II_Application1
{
    public class Program
    {

        static PersistentStorage sdCard;
        static USBC_MassStorage sdStorage;
        public static void Main()
        {
            InterruptPort IntButton = new InterruptPort((Cpu.Pin)FEZ_Pin.Digital.LDR, false,
                                                        Port.ResistorMode.PullUp,
                                                        Port.InterruptMode.InterruptEdgeLow);

            IntButton.OnInterrupt += new NativeEventHandler(IntButton_OnInterrupt);

            //"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""

            sdCard = new PersistentStorage("SD");

            sdStorage = USBClientController.StandardDevices.StartMassStorage();

            sdStorage.AttachLun(0, sdCard, " ", " ");

            sdStorage.EnableLun(0);

            Thread.Sleep(Timeout.Infinite);
        }

        static void IntButton_OnInterrupt(uint port, uint state, DateTime time)
        {
            sdStorage.DisableLun(0);

            SerialPort UART = new SerialPort("COM1", 2400);

            int counter = 0;
            UART.Open();

            // ...
            // SD Card is inserted
            // Create a new storage device
            PersistentStorage sdPS = new PersistentStorage("SD");

            // Mount the file system
            sdPS.MountFileSystem();


            // Assume one storage device is available, access it through 
            // Micro Framework and display available files and folders:
            Debug.Print("Getting files and folders:");
            if (VolumeInfo.GetVolumes()[0].IsFormatted)
            {
                string rootDirectory =
                    VolumeInfo.GetVolumes()[0].RootDirectory;
                string outstr = "Files in " + rootDirectory + "\r\n";
                string[] files = Directory.GetFiles(rootDirectory);
                UART.Write(UTF8Encoding.UTF8.GetBytes(outstr), 0, outstr.Length);

                Debug.Print("Files available on " + rootDirectory + ":");
                for (int i = 0; i < files.Length; i++)
                {
                    Debug.Print(files[i]);
                    outstr = files[i] + "\r\n";
                    UART.Write(UTF8Encoding.UTF8.GetBytes(outstr), 0, outstr.Length);


                }

            }
        }
    }
}



After disabling MSD, it seems you might leave the SD storage in an unaccessible state. Or the opposite, when the code is called to disable the MSD it is failing. You really need to post your code (what you posted seems to be what I posted? No MSD activity that’s for sure!) and you need to use breakpoints to step into your code and see where the exception is thrown.

@ Brett - Woops I did post the wrong code! I just edited it above. And yes I believe that is true, because the removable disk drive still appears in my computer, but cant be accessed after disablelun()

Also, what would actually be needed to instead of sending the file names though UART, to actually open the file and send the contents; Even if it appears as Hex. I have been reading up on FileStreaming but it seems to be different from the approach on things?

Have you checked the USBC_MassStorage documentation to see if there’s a StopMasStorage or equivalent?

To send the file over UART, you need to open the file, read a byte, send it, repeat until EOF. One of the reasons I suggested earlier that you test this on a text file is you can easily see if the contents gets to you as it was expected with just using TeraTerm.

I have been looking but no luck on implementing anything.

Also, yes I am testing with a .txt file with just Hello world written in it. Let me see if I see implement how to open the file, read a byte, send it, repeat until EOF like you stated.

Thanks!

@ jkane121 - Have a squizz here: http://www.tinyclr.com/codeshare/entry/59

@ Justin - Interesting, but that involves creating the file to open the file from correct? I just want to open all available files on the SD

@ jkane121 - You can loop thru the files with your existing code and use this part to read the contents of each file

 /// <summary>
        /// Get the contents of a file by path
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        private static string fileGetContents(string path)
        {
            // Create a file stream object
            FileStream fHandle = new FileStream(path, FileMode.Open, FileAccess.Read);
 
            // Create the byte array to hold the data
            byte[] data = new byte[fHandle.Length];
 
            // Copy the file data to the byte array
            fHandle.Read(data, 0, data.Length);
 
            // We're done.
            fHandle.Close();
 
            // Convert the bytes to string and return
            return bytesToString(data);
        }

@ Justin - Ok I see. And after the files are copied to the byte array I can send the data through UART? Thanks for helping out

@ jkane121 - Yup :slight_smile:

@ Justin - Cool! Im having trouble setting it up though, would I be doing this?

 UART.Write(UTF8Encoding.UTF8.GetBytes(data), 0, data.Length);

Indeedie

byte[] buffer = Encoding.UTF8.GetBytes(data);
            UART.Write(buffer, 0, buffer.Length);
            UART.Flush();

@ Justin - Nice! Thanks for the help!