SPIメモリを使ってみよう

23K256 SRAMを使う

32kBのSRAMです。
SI(5)はCPUのMOSIに接続します(P20, PB5)
SO(2)はCPUのMISOに接続します(P10, PB4)
SCK(6)はCPUのSCKに接続します(P12, PB3)
/HOLD(7)は特別なことをしないのでhighに接続します
/CS(1)は選択するためにCPUに接続します。(P16, PB8)


GHI electronicsのフォーラムにあったものを自分用に少し手直ししたものです。
Ser23K256.cs
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHI.OSHW.Hardware;

namespace BoeBotLib
{
    class SRAM
    {
        //hold pin 7 = high
        const uint SRAM_SIZE = 32768;

        enum Command
        {
            Read = 0x03,
            Write = 0x02,
            RDSR = 0x05,
            WRSR = 0x01,
        };

        //hold is disabled
        enum Mode
        {
            Byte = 0x01,
            Page = 0x81,
            Sequential = 0x41,
        };

        SPI _spi;

        public SRAM(SPI _spi)
        {
            this._spi = _spi;
            SetMode(Mode.Sequential);
            CheckStatus();
        }

        //quick check using a couple read/writes
        private void CheckStatus()
        {
            WriteByte(0, 100);
            WriteByte(SRAM_SIZE - 1, 100);
            WriteByte(0, 128);
            WriteByte(SRAM_SIZE - 1, 192);
            byte b1 = ReadByte(0);
            byte b2 = ReadByte(SRAM_SIZE - 1);
            if (b1 == 128 && b2 == 192)
            {
                Debug.Print("SRAM Found");
            }
            else
            {
                for (int i = 0; i < 50; i++)
                {
                    Debug.Print("SRAM Error");
                    Thread.Sleep(100);
                }
            }
        }

        private void SetMode(Mode val)
        {
            byte[] output = new byte[2];
            output[0] = (byte)Command.WRSR;
            output[1] = (byte)val;
            _spi.Write(output);
        }

        public byte WriteByte(uint addr, byte val)
        {
            if (addr > SRAM_SIZE)
            {
                return 0xFF;
            }
            byte[] output = new byte[4];
            output[0] = (byte)Command.Write;
            output[1] = (byte)(addr >> 8);
            output[2] = (byte)(addr & 0xFF);
            output[3] = val;
            _spi.Write(output);
            return 0;
        }

        public byte ReadByte(uint addr)
        {
            if (addr > SRAM_SIZE)
            {
                return 0xFF;
            }
            byte[] output = new byte[3];
            byte[] input = new byte[1];
            output[0] = (byte)Command.Read;
            output[1] = (byte)(addr >> 8);
            output[2] = (byte)(addr & 0xFF);
            _spi.WriteRead(output, 0, 3, input, 0, 1, 3);
            return input[0];
        }

        public byte WriteBuffer(uint addr, byte[] buffer)
        {
            if (addr + buffer.Length >= SRAM_SIZE)
            {
                return 0xFF;
            }
            else
            {
                byte[] output = new byte[3 + buffer.Length];
                output[0] = (byte)Command.Write;
                output[1] = (byte)(addr >> 8);
                output[2] = (byte)(addr & 0xFF);
                Array.Copy(buffer, 0, output, 3, buffer.Length);
                _spi.Write(output);
                return 0;
            }
        }

        public byte[] ReadBuffer(uint addr, int count)
        {
            if (addr + count >= SRAM_SIZE)
            {
                count = (int)(SRAM_SIZE - addr);
            }
            byte[] output = new byte[3];
            byte[] input = new byte[count];
            output[0] = (byte)Command.Read;
            output[1] = (byte)(addr >> 8);
            output[2] = (byte)(addr & 0xFF);
            _spi.WriteRead(output, 0, 3, input, 0, count, 3);
            return input;
        }
    }
}


main.cs



main.cs
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using GHI.OSHW.Hardware;
using BoeBotLib;

namespace SPI23K256test
{
    public partial class Program
    {

        static SPI _spi = new SPI(new SPI.Configuration((Cpu.Pin)GHI.OSHW.Hardware.FEZCerberus.Pin.PB8, false, 0, 0, false, true, 5000, SPI.SPI_module.SPI1));
        static SRAM sram = new SRAM(_spi);

        static long time;
        static long timeLast;

        const int BufferSize = 1024;

        public static void Main()
        {
            byte[] buffer = new byte[BufferSize];
            int n = 32768 / BufferSize;
            byte[] readBuffer = new byte[n];
            int j = 0;
            while (true)
            {
                for (uint i = 0; i < BufferSize; i++)
                {
                    buffer[i] = (byte)((i+j) & 0xFF);
                }
                time = DateTime.Now.Ticks;
                for (uint i = 0; i < 32768; i += BufferSize)
                {
                    sram.WriteBuffer(i, buffer);
                }
                timeLast = (DateTime.Now.Ticks - time) / 10000L;
                Debug.Print("WriteTime=" + timeLast);

                time = DateTime.Now.Ticks;
                
                int k=0;
                for (uint i = 0; i < 32768; i += BufferSize)
                {
                    buffer = sram.ReadBuffer(i, BufferSize);
                    readBuffer[k] = buffer[k];
                    k++;
                }
                
                timeLast = (DateTime.Now.Ticks - time) / 10000L;
                Debug.Print("ReadTime=" + timeLast);
            
                for (uint i = 0; i < n; i++)
                {
                    Debug.Print("Addr=" + i + ", " + readBuffer[i]);
                    Thread.Sleep(100);
                }
                j++;
            }
        }
    }
}


spiフラッシュメモリA25L032を使ってみる

4MBのflashメモリです。
DI(5)はCPUのMOSIに接続します
DO(2)はCPUのMISOに接続します
C(6)はCPUのSCKに接続します
/HOLD(7)は特別なことをしないのでhighに接続します
/S(1)は選択するためにCPUに接続します。
/W(3)は読み書き信号のためにCPUに接続します。


A25L032.h


動作チェックが甘いので、正しく動くか保証はありません。

A25L032.h



A25L032.cpp



A25L032.cpp