mcp24lc515_i2c_eeprom.c - PIC24 uC in Master mode to Microchip 24LC515 EEPROM using I2CΒΆ

I2C Example: Demonstrates I2C functions by reading/writing from a Microchip 24LC515 serial EEPROM.

 
#include "pic24_all.h"

#define EEPROM 0xA0   //LC515 address assuming both address pins tied low.
#define BLKSIZE (64)

//Assumes WDT is configured for longer than EEPROM write time
void waitForWriteCompletion(uint8_t u8_i2cAddr) {
  uint8_t u8_ack, u8_savedSWDTEN;
  u8_savedSWDTEN = _SWDTEN;
  _SWDTEN = 1; //enable WDT so that do not get stuck in infinite loop!
  u8_i2cAddr = I2C_WADDR(u8_i2cAddr);  //write operation, R/W# = 0;
  do {
    startI2C1();
    u8_ack = putNoAckCheckI2C1(u8_i2cAddr);
    stopI2C1();
  } while (u8_ack == I2C_NAK);
  _SWDTEN = u8_savedSWDTEN;  //restore WDT to original state
}

void memWriteLC515(uint8_t u8_i2cAddr,  uint16_t u16_MemAddr, uint8_t *pu8_buf) {
  uint8_t u8_AddrLo, u8_AddrHi;

  u8_AddrLo = u16_MemAddr & 0x00FF;
  u8_AddrHi = (u16_MemAddr >> 8);
  pu8_buf[0] = u8_AddrHi;   //place address into buffer
  pu8_buf[1] = u8_AddrLo;

  if (u16_MemAddr & 0x8000) {

if MSB set , set block select bit

    u8_i2cAddr = u8_i2cAddr | 0x08;
  }
  waitForWriteCompletion(u8_i2cAddr);
  writeNI2C1(u8_i2cAddr,pu8_buf,BLKSIZE+2);
}

void memReadLC515(uint8_t u8_i2cAddr,  uint16_t u16_MemAddr, uint8_t *pu8_buf) {

  uint8_t u8_AddrLo, u8_AddrHi;

  u8_AddrLo = u16_MemAddr & 0x00FF;
  u8_AddrHi = (u16_MemAddr >> 8);

  if (u16_MemAddr & 0x8000) {

if MSB set , set block select bit

    u8_i2cAddr = u8_i2cAddr | 0x08;
  }
  waitForWriteCompletion(u8_i2cAddr);
  //set address counter
  write2I2C1(u8_i2cAddr,u8_AddrHi, u8_AddrLo);
  //read data
  readNI2C1(u8_i2cAddr,pu8_buf, BLKSIZE);
}


int main (void) {
  uint8_t au8_buf[BLKSIZE+2];  //2 extra bytes for address
  uint16_t u16_MemAddr;
  uint8_t u8_Mode;

  configBasic(HELLO_MSG);
  configI2C1(400);            //configure I2C for 400 KHz
  outString("\nEnter 'w' for write mode, anything else reads: ");
  u8_Mode = inCharEcho();
  outString("\n");
  u16_MemAddr = 0;     //start at location 0 in memory
  while (1) {
    uint8_t u8_i;
    if (u8_Mode == 'w') {
      outString("Enter chars.\n");
      //first two buffer locations reserved for starting address
      for (u8_i = 2; u8_i< BLKSIZE+2; u8_i++) {
        au8_buf[u8_i] = inCharEcho();
      }
      outString("\nDoing Write\n");

write same string twice to check Write Busy polling

      memWriteLC515(EEPROM,u16_MemAddr, au8_buf); // do write
      u16_MemAddr = u16_MemAddr + BLKSIZE;
      memWriteLC515(EEPROM,u16_MemAddr,au8_buf); // do write
      u16_MemAddr = u16_MemAddr + BLKSIZE;
    } else {
      memReadLC515(EEPROM,u16_MemAddr,au8_buf); // do read
      for (u8_i = 0; u8_i< BLKSIZE; u8_i++) outChar(au8_buf[u8_i]);
      outString("\nAny key continues read...\n");
      inChar();
      u16_MemAddr = u16_MemAddr + BLKSIZE;
    }
  }
}