[fpc-pascal] FPC/Lazarus on RPi4 - How to read/write I2C connected EEPROM?

Bo Berglund bo.berglund at gmail.com
Wed Apr 5 12:42:52 CEST 2023


On Wed, 5 Apr 2023 11:40:09 +0200, Christo Crause via fpc-pascal
<fpc-pascal at lists.freepascal.org> wrote:
>Looking at the datasheet for CAT24C128, Fig. 6 Byte Write Sequence, shows
>no repeated start condition between register address and data bytes. I
>suspect that the second i2c message should contain the I2C_M_NOSTART flag,
>else the address and data parts of the transaction will be separated by a
>repeated start signal. I have modified the WriteBytesToReg methods in
>i2c.pas, please feel free to pull from Github and test this again.

Thanks, I did so and used it in my code but it still does not write the
EEPROM...

Here is the code I use to test (in a command line program), maybe you can see a
usage problem?

var
  i2cbus,
  dev_addr,
  reg_addr,
  data_cnt: integer;
  indata: TBytes;

procedure main_12c_write(); //This is the main application procedure
var
  i: integer;
  num: uint16;
  i2cEeprom: TI2c_eeprom;
begin
  processInputs; //Read command line and write to variables
  //Now process the data towards the EEPROM
  i2cEeprom := TI2c_eeprom.Create; //Defaults are set for my EEPROM
  try
    num := i2cEeprom.WriteData(reg_addr, data_cnt, indata);
    Writeln('Wrote ' + IntToStr(num) + ' bytes to address $' +
IntToHex(reg_addr,4) );
  finally
    i2cEeprom.Free;
  end;

function TI2c_eeprom.WriteData(StartAddress, NumBytes: uint16; Source: TBytes):
uint16;
var
  endpos, capacity, addr: uint16;
  i2cMaster: TI2cMaster;
  i2cbus: TI2CBus;
  sourcelen, i, j: integer;
  pSource: PByte;
begin
  Result := 0;
  //Check valid indata:
  //snip....
  //Prepare the handler for action...
  i2cbus := TI2CBus(FI2cBusNo);
  i2cMaster := TI2cMaster.Create;
  try
    if not i2cMaster.Initialize(i2cbus) then
    begin
      writeln('Error opening i2c device: ', FI2cBusNo);
      exit;
    end;

    //Check if data will fit into a single page start at given address:
    if ((StartAddress and $ffc0) = (endpos and  $ffc0)) then //Fits in page
    begin
      //Perform a single write cycle into the buffer
      pSource := @source[0];
      if not i2cMaster.WriteBytesToReg(FEEPROMAddr, startaddress, pSource,
NumBytes) then
      begin
        Writeln('Error: Could not write to I2C device!');
        exit;
      end
      else
        Result := NumBytes;
    end
    else  //We need to split data over several commands
    begin
      Writeln('Not yet implmented data split into several writes');
    end;
  finally
    i2cMaster.Free;
  end;


-- 
Bo Berglund
Developer in Sweden



More information about the fpc-pascal mailing list