Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

SD Card and other SPI devices


Best Answer ShVerni, 03 July 2013 - 06:40 PM

Hi Dennis,

 

It's actually relatively easy to use, really, as many SPI devices as you want. From a hardware perspective, you of course need to hook them all up to the correct MISO, MOSI, and SCLK pins. After that, you need to hook up each device to its own CS pin.

 

The important thing is to give each deivce it's own configuration, and then swap out the configurations of the devices. This wiki page has some good examples: http://wiki.netduino.com/SPI.ashx

 

I could be mistaken, but when using an SD card, you don't need to swap the configuration, as the framework does that for you whenever you try to access the SD card, but you will need to swap out the configuration for using other attached devices, like so:

class Program
{
        private static SPI spi;

        public static void Main()
        {
            StorageDevice.MountSD("SD", SPI.SPI_module.SPI1, Pins.GPIO_PIN_D10, Pins.GPIO_NONE);
            
            //Use this to initialize the SPI module, the conif doesn't really matter since we'll change it anyway
            SPI.Configuration config = new SPI.Configuration(
                SPI_mod: SPI.SPI_module.SPI1,
                ChipSelect_Port: Pins.GPIO_NONE,
                ChipSelect_ActiveState: false,
                ChipSelect_SetupTime: 0,
                ChipSelect_HoldTime: 0,
                Clock_IdleState: false,
                Clock_Edge: true,
                Clock_RateKHz: 1000);
            spi = new SPI(config);

            //Test the SD card
            using (StreamWriter sw = new StreamWriter(@"SDTest.txt", true))
            {
                sw.WriteLine("This is test one");
            }

            //Write to device one
            writeByteToOne(new byte[] { 255 });

            //Write to device two
            writeByteToTwo(new byte[] { 128 });

            //Test the SD card again
            using (StreamWriter sw = new StreamWriter(@"SDTest.txt", true))
            {
                sw.WriteLine("This is test two");
            }
        }

        private static void writeByteToOne(byte[] data)
        {
            //Set the configuration of device one
            SPI.Configuration config = new SPI.Configuration(
                SPI_mod: SPI.SPI_module.SPI1,
                ChipSelect_Port: Pins.GPIO_PIN_D0,
                ChipSelect_ActiveState: false,
                ChipSelect_SetupTime: 0,
                ChipSelect_HoldTime: 0,
                Clock_IdleState: false,
                Clock_Edge: true,
                Clock_RateKHz: 40000);

            //Set the config of the SPI module
            spi.Config = config;
            spi.Write(data);
        }        

        private static void writeByteToTwo(byte[] data)
        {
            //Set the configuration of device two
            SPI.Configuration config = new SPI.Configuration(
                SPI_mod: SPI.SPI_module.SPI1,
                ChipSelect_Port: Pins.GPIO_PIN_D1,
                ChipSelect_ActiveState: false,
                ChipSelect_SetupTime: 0,
                ChipSelect_HoldTime: 0,
                Clock_IdleState: false,
                Clock_Edge: true,
                Clock_RateKHz: 5000);

            //Set the config of the SPI module
            spi.Config = config;
            spi.Write(data);
        }
        //Add more devices if you want. Better, put each device in its own class.
}

This is just a quick and dirty unoptomized example, and assumes the CS pin of the SD card is D10, and that you're not using the CD pin. You could improve things by putting each device it its own class with a configuration that gets swapped in whenever you call a write or read from the device class, for instance.

 

Also, the venerable Stefan has created a MultiSPI class as part of his excellent .NET ToolBox, which you can find here: http://netmftoolbox....rdware.MultiSPI

 

I hope that helps!

Go to the full post


  • Please log in to reply
7 replies to this topic

#1 Nighthawk

Nighthawk

    Member

  • Members
  • PipPip
  • 21 posts

Posted 03 July 2013 - 07:41 AM

Hi all,

 

Bit of a newbie question on SD cards and SPI.

 

I have an SD Card shield which works brilliantly.

Mount the SD, read/write, unmount. All good.

 

But how would I go about attaching other devices to the SPI bus?

 

In theory the netmf toolbox MultiSPI would suit me well but the SD card is not a normal SPI configuration from what i can see (you pass slave select pin and spi device in mountSD not through a normal SPI config). So how would I switch SPI configs?

 

Anyone ever dealt with this?

 

Thanks, 

Dennis



#2 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 138 posts
  • LocationNew York, New York

Posted 03 July 2013 - 06:40 PM   Best Answer

Hi Dennis,

 

It's actually relatively easy to use, really, as many SPI devices as you want. From a hardware perspective, you of course need to hook them all up to the correct MISO, MOSI, and SCLK pins. After that, you need to hook up each device to its own CS pin.

 

The important thing is to give each deivce it's own configuration, and then swap out the configurations of the devices. This wiki page has some good examples: http://wiki.netduino.com/SPI.ashx

 

I could be mistaken, but when using an SD card, you don't need to swap the configuration, as the framework does that for you whenever you try to access the SD card, but you will need to swap out the configuration for using other attached devices, like so:

class Program
{
        private static SPI spi;

        public static void Main()
        {
            StorageDevice.MountSD("SD", SPI.SPI_module.SPI1, Pins.GPIO_PIN_D10, Pins.GPIO_NONE);
            
            //Use this to initialize the SPI module, the conif doesn't really matter since we'll change it anyway
            SPI.Configuration config = new SPI.Configuration(
                SPI_mod: SPI.SPI_module.SPI1,
                ChipSelect_Port: Pins.GPIO_NONE,
                ChipSelect_ActiveState: false,
                ChipSelect_SetupTime: 0,
                ChipSelect_HoldTime: 0,
                Clock_IdleState: false,
                Clock_Edge: true,
                Clock_RateKHz: 1000);
            spi = new SPI(config);

            //Test the SD card
            using (StreamWriter sw = new StreamWriter(@"SDTest.txt", true))
            {
                sw.WriteLine("This is test one");
            }

            //Write to device one
            writeByteToOne(new byte[] { 255 });

            //Write to device two
            writeByteToTwo(new byte[] { 128 });

            //Test the SD card again
            using (StreamWriter sw = new StreamWriter(@"SDTest.txt", true))
            {
                sw.WriteLine("This is test two");
            }
        }

        private static void writeByteToOne(byte[] data)
        {
            //Set the configuration of device one
            SPI.Configuration config = new SPI.Configuration(
                SPI_mod: SPI.SPI_module.SPI1,
                ChipSelect_Port: Pins.GPIO_PIN_D0,
                ChipSelect_ActiveState: false,
                ChipSelect_SetupTime: 0,
                ChipSelect_HoldTime: 0,
                Clock_IdleState: false,
                Clock_Edge: true,
                Clock_RateKHz: 40000);

            //Set the config of the SPI module
            spi.Config = config;
            spi.Write(data);
        }        

        private static void writeByteToTwo(byte[] data)
        {
            //Set the configuration of device two
            SPI.Configuration config = new SPI.Configuration(
                SPI_mod: SPI.SPI_module.SPI1,
                ChipSelect_Port: Pins.GPIO_PIN_D1,
                ChipSelect_ActiveState: false,
                ChipSelect_SetupTime: 0,
                ChipSelect_HoldTime: 0,
                Clock_IdleState: false,
                Clock_Edge: true,
                Clock_RateKHz: 5000);

            //Set the config of the SPI module
            spi.Config = config;
            spi.Write(data);
        }
        //Add more devices if you want. Better, put each device in its own class.
}

This is just a quick and dirty unoptomized example, and assumes the CS pin of the SD card is D10, and that you're not using the CD pin. You could improve things by putting each device it its own class with a configuration that gets swapped in whenever you call a write or read from the device class, for instance.

 

Also, the venerable Stefan has created a MultiSPI class as part of his excellent .NET ToolBox, which you can find here: http://netmftoolbox....rdware.MultiSPI

 

I hope that helps!



#3 Nighthawk

Nighthawk

    Member

  • Members
  • PipPip
  • 21 posts

Posted 03 July 2013 - 07:32 PM

Thanks!!!

 

Yes I am aware of the .NET MF Toolbox. I'm using many bits of it already! :D 

 

Just wasn't sure of how I would swap the SPI config in and out for the SD card.

I will try out your example in my project and will report back.

 

Thanks again for taking the time to help  :)



#4 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 138 posts
  • LocationNew York, New York

Posted 03 July 2013 - 09:13 PM

You're very welcome!

 

I admit, I didn't actually test the code I posted here, but I have used an SD card with other SPI devices, and I've only had to swap the configs when using more than one other device (besides the SD). So if you're using just the SD and one other device, you might not need to swap any configs at all (the framework is pretty slick that way).

 

I look forward to hearing how it goes!



#5 Nighthawk

Nighthawk

    Member

  • Members
  • PipPip
  • 21 posts

Posted 05 July 2013 - 06:42 AM

Welll I set everything up and it all worked just like you said. I didn't even have to switch SPI configs as all I have is one SPI device (shift register) attached to the bus other than the SD card.

 

I did feel the SD card implementation is a bit... shaky, though I've seen other users with some issues with the SD card... such as not writing the file to the card unless Unmount is called and stuff like that, so I know I'm probably not alone. Mine did write without calling Unmount..... sometimes. Other times not but it might have been user error. I didn't spend much time looking at this though (it got late for my bedtime :D) so I am still blaming myself for now!

 

Thanks!

Dennis



#6 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 138 posts
  • LocationNew York, New York

Posted 05 July 2013 - 09:50 PM

Glad to hear it!

 

I've also seen those posts about problems with writing to the SD card, but haven't had them myself. Using the card detect pin might make things more reliable, but I've never played around with that. That's the thing about the framework, it makes things easy, but sometimes it hides things too well when there are problems.

 

Anyway, good luck with everything!



#7 Nighthawk

Nighthawk

    Member

  • Members
  • PipPip
  • 21 posts

Posted 08 July 2013 - 06:37 AM

Well, just as I suspected, the problem with writing to the SD card was totally caused by me  :lol: . It all works perfectly now. Just need to treat it with care. I implemented a Queue which everything writes to, then a dedicated SD card thread simply processes that queue at its leisure at regular intervals.

 

Having everything try to write to the SD card (even in different files) just like it always worked on desktop hard disks just didn't give the sort of reliable results that I could feel comfortable with.



#8 ShVerni

ShVerni

    Advanced Member

  • Members
  • PipPipPip
  • 138 posts
  • LocationNew York, New York

Posted 08 July 2013 - 03:31 PM

That's good info; it means that we have to make sure writing to the SD card is extremely thread safe. I wonder if the card can handle multiple simultaneous reads or a read at the same time as a write... I sense a lot of experimentation in the future!






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.