Netduino home hardware projects downloads community

Jump to content


Photo

SoftwareSPI on ShieldBase demonstration


  • Please log in to reply
1 reply to this topic

#1 DaveRVW

DaveRVW

    Advanced Member

  • Members
  • PipPipPip
  • 37 posts

Posted 22 May 2012 - 03:06 PM

I can access my 64Mbit Flash shield using this SoftwareSpi class I wrote. The sample program below just reads an ID from the Flash chip using SPI. This is going to be a lot slower than hardware based SPI, but useful until that work is finished. You may be able to access other shields using SPI using this class.

I got this working in the first few hours of bringing the Netduino Go home from the Maker Faire Bay Area show. It was nice meeting Chris and getting to hear about Netduino Go's history and specs. Thanks Chris!

-Dave VW
http://techwithdave.blogspot.com/

Posted Image

        public static void Main()
        {
            NetduinoGo.ShieldBase shield = new NetduinoGo.ShieldBase(GoSockets.Socket7);

            SPI.Configuration spi_config = new SPI.Configuration(shield.Pins.GPIO_PIN_D2, false, 1, 1, false, true, 1000, SPI.SPI_module.SPI1);
            SoftwareSpi spi = new SoftwareSpi(spi_config, shield);
            byte[] write_buffer = new byte[1];
            write_buffer[0] = 0x9f; // JEDEC-ID
            byte[] read_buffer = new byte[3];

            int iter = 0;
            while (true)
            {
                string message = "hello " + ++iter + "\r\n";
                Debug.Print(message);

                spi.WriteRead(write_buffer, 0, write_buffer.Length, read_buffer, 0, read_buffer.Length, write_buffer.Length);
                DisplayHex(read_buffer);

                Thread.Sleep(250);
            }
        }

        static void DisplayHex(byte[] src)
        {
            string s = string.Empty;

            foreach (byte data in src)
            {
                for (int bit = 4; bit >= 0; bit -= 4)
                {
                    int nibble = (data >> bit) & 0xF;
                    if (nibble < 10)
                        s += nibble.ToString();
                    else
                    {
                        Char c = (Char)('A' + nibble - 10);
                        s += c.ToString();
                    }
                }
                s += " ";
            }

            Debug.Print(s);
        }
    }

    public class SoftwareSpi
    {
        SPI.Configuration config;
        OutputPort ss;
        OutputPort sck;
        OutputPort so;
        InputPort si;

        public SoftwareSpi(SPI.Configuration config, NetduinoGo.ShieldBase shield)
        {
            this.config = config;
            ss = new OutputPort(config.ChipSelect_Port, !config.ChipSelect_ActiveState);

            if (config.SPI_mod == SPI.SPI_module.SPI1)
            {
                sck = new OutputPort(shield.Pins.GPIO_PIN_D13, config.Clock_IdleState);
                so = new OutputPort(shield.Pins.GPIO_PIN_D11, false);
                si = new InputPort(shield.Pins.GPIO_PIN_D12, false, Port.ResistorMode.PullUp);
            }
            else
                throw new NotImplementedException(config.SPI_mod.ToString());
        }

        public void WriteRead(byte[] write_buffer, int write_offset, int write_buffer_length,
            byte[] read_buffer, int read_offset, int read_buffer_length, int start_read_offset)
        {
            ss.Write(config.ChipSelect_ActiveState);
            Thread.Sleep((int)config.ChipSelect_SetupTime);

            //int total = ((write_buffer_length > read_buffer_length) ? write_buffer_length : read_buffer_length) + start_read_offset;
            int total = (write_buffer_length > read_buffer_length + start_read_offset) ? write_buffer_length : read_buffer_length + start_read_offset;

            for (int i = 0; i < total; ++i)
            {
                int read = 0;
                for (int bit = 7; bit >= 0; --bit)
                {
                    if (i < write_buffer_length)
                        so.Write(((write_buffer[i + write_offset] >> bit) & 0x01) != 0);
                    else
                        so.Write(false);

                    sck.Write(!config.Clock_IdleState);

                    Thread.Sleep(1000 / (int)config.Clock_RateKHz);

                    if (si.Read())
                        read |= (1 << bit);
                    sck.Write(config.Clock_IdleState);

                    Thread.Sleep(1000 / (int)config.Clock_RateKHz);
                }
                if (i >= start_read_offset)
                    read_buffer[i - start_read_offset + read_offset] = (byte)read;
            }

            Thread.Sleep((int)config.ChipSelect_HoldTime);
            ss.Write(!config.ChipSelect_ActiveState);
        }
    }

Edited by DaveRVW, 29 November 2012 - 07:53 AM.


#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7767 posts
  • LocationNew York, NY

Posted 22 May 2012 - 03:58 PM

Hi Dave, Cool. Sometimes I get so wrapped up with super-fast SPI-using-DMA and the such that I forget to recommend bit-banging as a possibility. Adding additional flash in this manner is a slick first project. BTW thanks for stopping by at MakerFaire...good to meet you! Chris




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.