#include <Wire.h>

#define A31301_ADDR 0x6F  // Default I²C address


// Read two bytes from a register
uint8_t read(uint8_t address, uint8_t reg_addr, uint8_t* msb, uint8_t* lsb) {
  Wire.beginTransmission(address);
  Wire.write(reg_addr);
  if (Wire.endTransmission(false) != 0) { Serial.println ("ERROR NACK ?"); return 1; }
  Wire.requestFrom(address, (uint8_t)2);
  if (Wire.available() != 2) { Serial.println("ERROR : Should read 2 bytes"); return 2; }
  *msb = Wire.read();
  *lsb = Wire.read();
  return 0;
}


// Write two bytes to a register
uint8_t write(uint8_t address, uint8_t reg_addr, uint8_t msb, uint8_t lsb) {
  Wire.beginTransmission(address);
  Wire.write(reg_addr);
  Wire.write(msb);
  Wire.write(lsb);
  if (Wire.endTransmission() != 0) { Serial.println ("ERROR NACK ?"); return 1; }
  return 0;
}


void setup() {
  Serial.begin(115200);
  // Secure Power-On Delay Time
  delay (1000);
  Serial.println("\n\n\n ::::: Change EEPROM I²C address :::::");
  Wire.begin();

  
  // 1. Write Access Code
  Serial.println ("1. Write Access Code");
  write (A31301_ADDR, 0x3E, 0x43, 0x55);
  write (A31301_ADDR, 0x3E, 0x53, 0x54);

  // 2. Load EEPROM target address (0x0015 = I2C address location)
  Serial.println ("2. Load the INDIRECT_WR_ADDR parameter with the target extended address.");
  write (A31301_ADDR, 0x02, 0x00, 0x15);
  
  // 3. Load EEPROM data to be written (new I2C address)
  Serial.println ("3. Load the INDIRECT_WR_DATA_MSB and INDIRECT_WR_DATA_LSB registers with the data to be written");
  write (A31301_ADDR, 0x04, 0x00, 0x01);
  write (A31301_ADDR, 0x06, 0x54, 0x00);

  // 4. Invoke extended write
  Serial.println ("4. Invoke the extended access by writing the primary INDIRECT_WR_STATUS register EXW bit with 1.");
  write (A31301_ADDR, 0x08, 0x80, 0x00);
  
  // 5. Wait until write completes (poll WDN bit)
  Serial.println ("5. The WDN bit in the INDIRECT_WR_STATUS register can be polled to determine when the write completes.");
  uint8_t WDN = 0;
  do {
    uint8_t msb, lsb;
    read(A31301_ADDR, 0x08, &msb, &lsb);
    WDN = lsb & 0x01;
  }
  while (!WDN);

  Serial.println("EEPROM write complete. Address changed.");
  Serial.println("Power-cycle the device for the new I2C address to take effect.");

}

void loop() {
}