MCP2210 Library — SPI EEPROM

So far, I have shown examples of using the open source MCP2210 library with MCP2210 GPIO, MCP23S08 and TC77 temperature sensor. In this post, I will show an example of interfacing the chip with an SPI EEPROM using the library.

The chip I am targeting is a 25LC020A 2K SPI bus serial EEPROM. It is also on the MCP2210 evaluation board.

As with the previous examples, Function SPISendReceive is used to send and receive data over the SPI bus. SPISendReceive has an optional parameter which can be used to indicate the returned data length:

SPIDataTransferStatusDef SPISendReceive(hid_device *handle, byte* data, int cmdBufferLength, int dataLength = -1)

This is useful when multiple bytes of data need to be transferred. When this optional parameter is not supplied, it takes the length of the command buffer by default. The following code snippet shows how to write 8 bytes of data into the EEPROM using a single SPI function call. Note that WREN must be enabled prior to any write operations. The 8 bytes of data were then read back with another SPI call to confirm that the write operation was successful. This multi-byte send/receive is demonstrated in the code below.

Pay special attention to BytesPerSPITransfer in SPI transfer setting when reading and writing to the EEPROM. This number equals the totally number of bytes sent and received in a single SPI call. For instance, the write operation sends the two command bytes plus the eight data bytes using:

SPISendReceive(handle, spiCmdBuffer, 10, 1)

and the read operation sends the two command bytes and gets back the data bytes using:

def1 = SPISendReceive(handle, spiCmdBuffer, 2, 9);

The example code for manipulating the 25LC020A EEPROM is listed here:

 
void Test25LC020A(hid_device* handle) {
    ChipSettingsDef chipDef;

    //set GPIO pins to be CS
    chipDef = GetChipSettings(handle);

    for (int i = 0; i < 9; i++) {
        chipDef.GP[i].PinDesignation = GP_PIN_DESIGNATION_CS;
        chipDef.GP[i].GPIODirection = GPIO_DIRECTION_OUTPUT;
        chipDef.GP[i].GPIOOutput = 1;
    }
    int r = SetChipSettings(handle, chipDef);

    //configure SPI
    SPITransferSettingsDef def;
    def = GetSPITransferSettings(handle);

    //chip select is GP0
    def.ActiveChipSelectValue = 0xfffe;
    def.IdleChipSelectValue = 0xffff;
    def.BitRate = 6000000l;
    def.BytesPerSPITransfer = 2;

    r = SetSPITransferSettings(handle, def);

    byte spiCmdBuffer[10];

    //enable write
    spiCmdBuffer[0] = 0x06; //WREN
    SPIDataTransferStatusDef def1 = SPISendReceive(handle, spiCmdBuffer, 1, 1);

    def.BytesPerSPITransfer = 11;
    r = SetSPITransferSettings(handle, def);

    //write 8 bytes
    spiCmdBuffer[0] = 0x02; //0000 0010 write    
    spiCmdBuffer[1] = 0x00; //address 0x00

    for (int i = 1; i <= 8; i++) 
        spiCmdBuffer[i + 1] = i;

    def1 = SPISendReceive(handle, spiCmdBuffer, 10, 1);

    //read 8 bytes
    spiCmdBuffer[0] = 0x03; //0000 0011 read
    spiCmdBuffer[1] = 0x00; //address 0x00

    def1 = SPISendReceive(handle, spiCmdBuffer, 2, 9);

    for (int i = 0; i < 8; i++)
        printf("%d\n", def1.DataReceived[i]);
}

The error handling statements are ignored in the code snippet above for simplicity reasons, the full code listing can be found here.

Be Sociable, Share!

One Comment

  1. Hi Kerry,
    good job, well done, thanks.
    I’m trying to use your library, which I could recompile and test on Ubuntu 14.04.
    My use case is an MCP2210 chip connected to an SPI 23K256 SRAM.
    I can properly activate the CS signal and (apparently) read and write its status register, but I didn’t succeed to read and write actual data to it, using the paradigm, as per the SRAM’s datasheet. Have you got any suggestions here?
    Moreover, since the SRAM is 32 kB wide, I wonder what is the maximum reply length that I can obtain from a single SPISendReceive() call,
    since the reply data field seems to be limited to 60 bytes.

    Thanks & best regards,

    Francesco LANDE
    Electronic Center s.r.l.

Leave a Reply