Page 1 of 1

Read/Write the 8K EEPROM on an LPCxpresso LPC1769

Posted: Sun Jun 17, 2012 12:30 pm
by cfbsoftware

Code: Select all

MODULE EEPROM8K;
(* =========================================================================  
   Example Cortex-M3 Oberon Program  
 
   Description:
     Read / Writes a string and an integer to EEPROM via I2C bus
      
   Target: 
     LPC17xx systems with a 8 kbit EEPROM e.g. MicroChip 24LC64
     connected to the I2C bus

   Tested on:
     Embedded Artists LPCXpresso LPC1769
     (I2C1, P0.19 = SDA1, P0.20 = SCL1)
     
   Refs: 
     NXP LPC17xx User Manual UM10360
     MicroChip 24AA64/24LC64/24FC64 Datasheet
     Oberon for Cortex-M3 Microcontrollers
   
   (c) 2010-2012 CFB Software   
   http://www.astrobe.com  
   
   ========================================================================= *)

IMPORT I2C, MCU, Main, Out, SYSTEM;


PROCEDURE Progress(msg: ARRAY OF CHAR; status: INTEGER);
BEGIN
  Out.String(msg); 
  IF status = I2C.OK THEN 
    Out.String(" OK"); Out.Ln()
  ELSE 
    Out.String(" Error "); Out.Int(status, 0); Out.Ln();
    (* Terminate the program *)
    ASSERT(FALSE)
  END
END Progress;


PROCEDURE* SwapLowBytes(word: INTEGER): INTEGER;
BEGIN
  RETURN LSR(LSL(word, 24), 16) + LSR(word, 8)
END SwapLowBytes;


PROCEDURE Read(EepromAddr, addr: INTEGER; VAR data: ARRAY OF SYSTEM.BYTE): INTEGER;
BEGIN
  RETURN I2C.ReadBytes(EepromAddr, addr, 2, data, 0, LEN(data))
END Read;  


PROCEDURE Write(EepromAddr, addr: INTEGER; data: ARRAY OF SYSTEM.BYTE): INTEGER;
BEGIN
  RETURN I2C.WriteBytes(EepromAddr, addr, 2, data, 0, LEN(data))
END Write;  


PROCEDURE Run;
CONST
  (* I2C1, P0.19 = SDA1, P0.20 = SCL1 *) 
  I2CBus = 3;
  (* 7-bit Slave address. Ref: 24LC64 *) 
  EepromAddr = 050H;
VAR 
  id, idRead: ARRAY 8 OF CHAR;
  idAddr, counterAddr : INTEGER;
  status, counter: INTEGER;
BEGIN
  I2C.Init(I2CBus, 400000);
  id := "Astrobe";
  idAddr := 0;
  (* MSB is byte[0], LSB is byte[1] *)
  counterAddr := SwapLowBytes(idAddr + LEN(id));

  status := I2C.OK;
  Progress("EEPROM", status);

  (* Look for the id in the EEPROM to see if it has been written previously *)
  status := Read(EepromAddr, idAddr, idRead);
  Progress("Read ID", status);
  Out.Char(22X); Out.String(idRead); Out.Char(22X); Out.Ln();
  IF idRead # id THEN 
    (* No id yet. Write it and initialise the counter *)
    status := Write(EepromAddr, idAddr, id); 
    Progress("Write ID", status);
    status := I2C.Ready(EepromAddr);
    Progress("Ready", status);
    counter := 0
  ELSE
    Out.String(idRead); Out.Ln();
    status := Read(EepromAddr, counterAddr, counter);
    Progress("Read counter", status)
  END;
  Out.Int(counter, 8); Out.Ln();
  INC(counter);
  status := Write(EepromAddr, counterAddr, counter);
  Progress("Write counter", status)
END Run;

BEGIN
  Run()
END EEPROM8K.
NOTE: You need to link this module with the updated I2C library module included in the attached zip file. This has been enhanced since v4.2 to include support for the alternative I2C1 on pins P0.19 and P0.20. The bus parameter of the I2C.Init procedure can now have values of 0..3:

0 = I2C0
1 = I2C1 on Pins P0.0 and P0.1
2 = I2C2
3 = I2C1 on Pins P0.19 and P0.20