This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PGA305: How to write EEPROM Data + CRC Check

Part Number: PGA305

Hello Profesionals

can you please full and correct describe how to write a value to the EEPROM?
It is absolutely not described in the datasheet.

Here's my Code:

void pgaEEPROMspeichern()
{
  delay(20);
  write(0x5, 0x89, 0b00000100); // ERASE_AND_PROGRAMM 
  delay(20);
  pgaEEPROMCalcCRC(); //???
  delay(20);
  write(0x5, 0x8A, 0b00000001); //Calculate CRC
  delay(20);
  Serial.print("CRCOK=");
  Serial.println(read(0x5,0x8C),BIN); //Read CRCOK
}

void pgaEEPROMcacheLaden(uint8_t cellAdresse) //irgendeine Adresse aus dem 8er Block
{
  write(0x0, 0x0C, 0b00000011);
  uint8_t addr;
  addr = cellAdresse >> 3;
  uint8_t startAdresse = addr << 3; //auf 8er block anpassen.
  Serial.print("Startbits = ");
  Serial.print(addr, BIN);
  Serial.print(" = ");
  Serial.println(startAdresse, HEX);
  write(0x5, 0x88, addr); //oberste 4bit der EEPROM Addresse
  for (int i = 0; i < 8; i++)
  {
    Serial.print("CacheAddr = ");
    Serial.print(0x80 + i, HEX);
    Serial.print(" = ");
    Serial.println(read(0x5, startAdresse + i), BIN);
    write(0x5, 0x80 + i, read(0x5, startAdresse + i)); //EEPROM auslesen und in EEPROM Cache laden
  }
  //write(0x5, 0x89,0b00000100); // ERASE_AND_PROGRAMM
}

void pgaEEPROMCalcCRC(){
uint8_t currentCRC8 =  0xFF; // Current value of CRC8
  for (int i = 0; i < 127; i++)
  {
  
    uint8_t C=read(0x5, i);
    uint8_t D=currentCRC8;
    uint8_t nextCRC8=0;
    bitWrite(nextCRC8,0,(bitRead(D,7)^bitRead(D,6)^bitRead(D,0)^bitRead(C,0)^bitRead(C,6)^bitRead(C,7)));
    bitWrite(nextCRC8,1,(bitRead(D,6)^bitRead(D,1)^bitRead(D,0)^bitRead(C,0)^bitRead(C,1)^bitRead(C,6)));
    bitWrite(nextCRC8,2,(bitRead(D,6)^bitRead(D,2)^bitRead(D,1)^bitRead(D,0)^bitRead(C,0)^bitRead(C,1)^bitRead(C,2)^bitRead(C,6)));
    bitWrite(nextCRC8,3,(bitRead(D,7)^bitRead(D,3)^bitRead(D,2)^bitRead(D,1)^bitRead(C,1)^bitRead(C,2)^bitRead(C,3)^bitRead(C,7)));
    bitWrite(nextCRC8,4,(bitRead(D,4)^bitRead(D,3)^bitRead(D,2)^bitRead(C,2)^bitRead(C,3)^bitRead(C,4)));
    bitWrite(nextCRC8,5,(bitRead(D,5)^bitRead(D,4)^bitRead(D,3)^bitRead(C,3)^bitRead(C,4)^bitRead(C,5)));
    bitWrite(nextCRC8,6,(bitRead(D,6)^bitRead(D,5)^bitRead(D,4)^bitRead(C,4)^bitRead(C,5)^bitRead(C,6)));
    bitWrite(nextCRC8,7,(bitRead(D,7)^bitRead(D,6)^bitRead(D,5)^bitRead(C,5)^bitRead(C,6)^bitRead(C,7)));
    currentCRC8=nextCRC8;
  }
Serial.print("Berechneter CRC=");
Serial.println(currentCRC8,BIN);
write(0x5,0x8D,currentCRC8);
Serial.print("gelesener CRC=");
Serial.println(read(0x5,0x8D),BIN);
}

What is the procedure to e.g. write a 0b01000000 to 0x4000000E  (G0_MSB)?
My steps are:
-calc upper 3 bit (with 0x0E >> 3 = 1) and write to (0x5, 0x88)
-read from (0x5, 0x08 to 0x0F) and write to EEPROM Cache (0x5, 0x80 to 0x87)
-write 0b01000000 to (0x5,0x82)

i read all 8 byte and write only 1 because i only want to change 1.

-write(0x5, 0x89, 0b00000100); // ERASE_AND_PROGRAMM


After this i every time get a CRCOK=0, writing back the default values everything is okay?
Is there to do a CRC Calculation by me and how exactly?
On the Datasheet Page 63 the EEPROM_CRC_VALUE Register is all R, so it doesn't look like I'm supposed to be writing data.
i tried to translate the pseudocode to C++ but it is not very specific for which data and when to do.

i tried only for the EEPROM Cache, for the whole EEPROM (0x0 to 0x7F) or without CRC itself (0x0 to 0x7E). before or after ERASE_AND_PROGRAMM. nothing works...

  • Hello,

    There is an I2C transfer example showing how to write to a specific EEPROM Cache byte. However, what is missing is that you also need to set the proper EEPROM cache page before doing this, and fill the entire cache with your changes before programming.This is captured in the EEPROM Programming Procedure section of the datasheet. 

    Since the EEPROM pages are not explicitly listed in the datasheet at the moment, you can determine this by looking at the EEPROM addressed listed in the register map. Each EEPROM page is 8 bytes long and the EEPROM space starts with address 0x40000000 (this would be page 0x0). Page 0x1 starts with 0x40000008, Page 0x2 with 0x40000010, and so on.

    The EEPROM CRC should be written to the last byte of the last page of the EEPROM. To do this you will have to load EEPROM page 0xF and write to the last byte as described above. The EEPROM_CRC_VALUE register is a read only register that will display the value of the last byte written into the EEPROM.

    Regards,

  • Okay thank you.
    Even though you didn't really answer the questions, this helps.

    i am now able to successfully write the EEPROM with CRC.

    Far all how are still searching here my working code:
    unfortunately this is not documented in the data sheet in the required form.

    void pgaEEPROMLoadCache(uint8_t cellAdress) //irgendeine Adresse aus dem 8er Block
    {
      write(0x0, 0x0C, 0b00000011); //Comp Control deakivieren
      uint8_t page = cellAdress >> 3;
      uint8_t startAdress = page << 3; //Startaddresse zurückrechnen
      Serial.print("page = ");
      Serial.print(page, HEX);
      Serial.print(" start= ");
      Serial.println(startAdress, HEX);
      write(0x5, 0x88, page); //EEPROM Page schreiben
      for (int i = 0; i < 8; i++)
      {
        Serial.print("CacheAddr = ");
        Serial.print(0x80 + i, HEX);
        Serial.print(" = ");
        uint8_t readCache = read(0x5, startAdress + i); //EEPROM auslesen
        Serial.println(readCache, BIN);
        write(0x5, 0x80 + i, readCache); //und in EEPROM Cache laden
      }
    }
    
    void pgaEEPROMCalcCRC()
    {
      uint8_t currentCRC8 = 0xFF;   // Startwert
      for (int i = 0; i < 127; i++) //alle Adressen außer CRC selbst
      {
        uint8_t C = read(0x5, i); //EEPROM auslesen
        uint8_t D = currentCRC8;
        uint8_t nextCRC8 = 0;
        bitWrite(nextCRC8, 0, (bitRead(D, 7) ^ bitRead(D, 6) ^ bitRead(D, 0) ^ bitRead(C, 0) ^ bitRead(C, 6) ^ bitRead(C, 7)));
        bitWrite(nextCRC8, 1, (bitRead(D, 6) ^ bitRead(D, 1) ^ bitRead(D, 0) ^ bitRead(C, 0) ^ bitRead(C, 1) ^ bitRead(C, 6)));
        bitWrite(nextCRC8, 2, (bitRead(D, 6) ^ bitRead(D, 2) ^ bitRead(D, 1) ^ bitRead(D, 0) ^ bitRead(C, 0) ^ bitRead(C, 1) ^ bitRead(C, 2) ^ bitRead(C, 6)));
        bitWrite(nextCRC8, 3, (bitRead(D, 7) ^ bitRead(D, 3) ^ bitRead(D, 2) ^ bitRead(D, 1) ^ bitRead(C, 1) ^ bitRead(C, 2) ^ bitRead(C, 3) ^ bitRead(C, 7)));
        bitWrite(nextCRC8, 4, (bitRead(D, 4) ^ bitRead(D, 3) ^ bitRead(D, 2) ^ bitRead(C, 2) ^ bitRead(C, 3) ^ bitRead(C, 4)));
        bitWrite(nextCRC8, 5, (bitRead(D, 5) ^ bitRead(D, 4) ^ bitRead(D, 3) ^ bitRead(C, 3) ^ bitRead(C, 4) ^ bitRead(C, 5)));
        bitWrite(nextCRC8, 6, (bitRead(D, 6) ^ bitRead(D, 5) ^ bitRead(D, 4) ^ bitRead(C, 4) ^ bitRead(C, 5) ^ bitRead(C, 6)));
        bitWrite(nextCRC8, 7, (bitRead(D, 7) ^ bitRead(D, 6) ^ bitRead(D, 5) ^ bitRead(C, 5) ^ bitRead(C, 6) ^ bitRead(C, 7)));
        currentCRC8 = nextCRC8;
      }
      Serial.print("berechneter CRC=");
      Serial.println(currentCRC8, BIN);
    
      pgaEEPROMLoadCache(0x7F);
      write(0x5, 0x87, currentCRC8); //CRC in Cache legen
      pgaEEPROMSave();
    
      write(0x5, 0x8A, 0b00000001); //Calculate CRC (intern zum Vergleich)
      delay(20);
    
      Serial.print("gelesener CRC=");
      Serial.println(read(0x5, 0x8D), BIN);
    
      Serial.print("CRCOK=");
      Serial.println(read(0x5, 0x8C), BIN);
    }
    
    void pgaEEPROMWriteCache(uint8_t originalAdress, uint8_t value)
    {
      uint8_t startAdress = (originalAdress >> 3) << 3;
      uint8_t offset = originalAdress - startAdress;
      write(0x5, 0x80 + offset, value);
    }
    
    void pgaEEPROMSave()
    {
      delay(20);
      write(0x5, 0x89, 0b00000100); // ERASE_AND_PROGRAMM
      delay(20);
    }

    this are the functions, and here a working example to set A0 to B2 filter values for 78Hz cutoff:

    pgaEEPROMLoadCache(0x4A);
    pgaEEPROMWriteCache(0x4B,0x40); //a0
    pgaEEPROMWriteCache(0x4A,0x00);
    
    pgaEEPROMWriteCache(0x4D,0xAA); //a1
    pgaEEPROMWriteCache(0x4C,0xA1);
    
    pgaEEPROMWriteCache(0x4F,0x20); //a2
    pgaEEPROMWriteCache(0x4E,0x60);
    pgaEEPROMSave();
    
    pgaEEPROMLoadCache(0x50);
    pgaEEPROMWriteCache(0x51,0x0B); //b0
    pgaEEPROMWriteCache(0x50,0x01);
    
    pgaEEPROMWriteCache(0x53,0x16); //b1
    pgaEEPROMWriteCache(0x52,0x02);
    
    pgaEEPROMWriteCache(0x55,0x0B); //b2
    pgaEEPROMWriteCache(0x54,0x01);
    pgaEEPROMSave();
    
    pgaEEPROMCalcCRC();