1-wire EEPROM DS2431GA - unlock or factory reset

Hi,

I have Maxim DS2431GA chips where is record the printer's toner status:
https://datasheets.maximintegrated.com/en/ds/DS2431.pdf

I use this script and there is no problem to read and write the data,
but only if the toner level on the chip is more than 0%:
Source: https://www.instructables.com/Message-in-a-Chip/

If the toner is completely used, the chip is locked by the printer and can only be read.

According to the datasheet, the chip will be locked at addresses 0080h - 0084h, probably by programming AAh or 55h.

Is this really an irreversible condition? Can't it be unlocked or reset to factory reset?

Thank you

int groundPin = A5;
int signalPin = A4;
int supplyPin = A3;
int blink = 0;

#include <OneWire.h>

OneWire  ds(signalPin);    // 1-wire on pin 2
byte     addr[8];  // Contains the eeprom unique ID

void setup(void){
  Serial.begin(9600);

  pinMode(groundPin, OUTPUT);
  digitalWrite(groundPin, LOW);

  pinMode(supplyPin, OUTPUT);
  digitalWrite(supplyPin, HIGH);

  pinMode(13, OUTPUT);
  menu();
}


void menu(void){
  Serial.println("Menu:");
  Serial.println("  e - erase memory");
  Serial.println("  h - read memory as hexidecimal");
  Serial.println("  b - read memory as binary");
  Serial.println("  s - read memory as chars");
  Serial.println("  w - write bitmap");
  Serial.println("  c - write chars");
  Serial.println("  m - print menu\n");
}
  
  

// Must be less than 128 characters  
char myString[] = "Roses   "
                  "are red,"
                  "violets "
                  "are blue"
                  "bits are"
                  "awesome,"
                  "and     "
                  "bytes   "                  
                  "are     "
                  "too!    ";                  
                  
                  

boolean bitMap[] = {
  0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,
  0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,
  0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,
  0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
  0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
  0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
  0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
  0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
  0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
  0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
  0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,
  0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
  0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
  0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,
  0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,
  0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,
  0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,
  0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,
  0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,
  0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,
  0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};


void loop(void){
  digitalWrite(13, HIGH);
  delay(100);
  digitalWrite(13, LOW);
  delay(blink);
}


void loop2(void) {
  delay(100);

  byte dat[13];
  if(SearchAddress(addr)){
    
    // Example to write 8 bytes to row 0
    dat[0] = 0xFF;
    dat[1] = 0x00;
    dat[2] = 0xFF;
    dat[3] = 0x00;
    dat[4] = 0xFF;
    dat[5] = 0x00;
    dat[6] = 0xFF;
    dat[7] = 0x00;  
    //WriteRow(0, dat);
    ReadAllMemHex();    //print memory content as hex

    // Example to write string to memory
    //writeString();
    
    //erase();
    //ReadAllMemBytes();  //print memory content as chars

    // Example to write a 32x32 bitmap to memory
    //writeBitMap(bitMap);
    //ReadAllMemBits();     // print memory as bitmap
    blink = 0; // solid indicates sucsess
  }
  delay(500);
  while(1){ // blink if unsucessful

  }
}


void writeString(){
  Serial.print("Writing chars to EEPROM ");
  int i = 0;
  byte dat[13];
  for(int row=0; row<16; row++){ // EEPROM has 16 rows of 8 bytes
    for(int B=0; B<8; B++){      // load eight bytes at a tim6; row++){

      if (i < (sizeof(myString) - 1)){
        dat[B] = myString[i];
      }
      else{
        dat[B] = 0;
      }
      i++;
    }      
    Serial.print(".");
    WriteRow(row, dat);          // write the bytes out to EEPROM
    delay(100);
  }
  Serial.println("\nDone");
}


void writeBitMap(boolean bitMap[]){ // write 32x32 bitmap to EEPROM
  Serial.print("Writing bits to EEPROM ");
  int i = 0;                     // bitMap index
  byte dat[13];                  // data to write to EEPROM
  byte mask;
  for(int row=0; row<16; row++){ // EEPROM has 16 rows of 8 bytes
    for(int B=0; B<8; B++){      // load eight bytes at a time
      dat[B] = 0;
      mask = B10000000;
      for(int b=0; b<8; b++){    // load byte with eight bits from map
        if(bitMap[i]){
        dat[B] = dat[B] + mask;
        }
        i++;                     // increment bitMap index
        mask = mask >> 1;               // shift the bit mask for next bit
      }
    }
    Serial.print(".");
    WriteRow(row, dat);          // write the bytes out to EEPROM
    delay(100);
  }
  Serial.print("\nDone");  
}


boolean SearchAddress(byte* address){ //Search for address and confirm it
  int i;
  if ( !ds.search(address)){
    //Serial.println("trying again");
    if ( !ds.search(address)){     
      Serial.print("No device found.\n");
      ds.reset_search();
      delay(250);
      return false;
    }
  }
  
  Serial.print("\nADDR= ");
  for( i = 0; i < 8; i++){
    Serial.print(address[i], HEX);
    Serial.print(" ");
  }

  if ( OneWire::crc8( address, 7) != address[7])  {
      Serial.print("CRC is not valid, address is corrupted\n");
      return false;
  }
  
  if ( address[0] != 0x2D){
      Serial.print("Device is not a 1-wire Eeprom.\n");
      return false;
  }
 
  Serial.println();
  return true;
}


void WriteReadScratchPad(byte TA1, byte TA2, byte* data){
  int i;
  ds.reset();
  ds.select(addr);
  ds.write(0x0F, 1);  // Write ScratchPad
  ds.write(TA1, 1); 
  ds.write(TA2, 1); 
  for ( i = 0; i < 8; i++)
    ds.write(data[i], 1);  
  
  ds.reset();
  ds.select(addr);    
  ds.write(0xAA);         // Read Scratchpad
  
  for ( i = 0; i < 13; i++)     
    data[i] = ds.read();
}


void CopyScratchPad(byte* data){
  ds.reset();
  ds.select(addr);
  ds.write(0x55, 1);     // Copy ScratchPad
  ds.write(data[0], 1); 
  ds.write(data[1], 1);  // Send TA1 TA2 and ES for copy authorization
  ds.write(data[2], 1); 
  delay(25);             // Waiting for copy completion
}


void ReadAllMemBits(){
  Serial.println("Reading from EEPROM as bits");
  ds.reset();
  ds.select(addr);
  ds.write(0xF0, 1);  // Read Memory
  ds.write(0x00, 1);  // Read Offset 0000h
  ds.write(0x00, 1);
  for(int row=0; row<32; row++){ // EEPROM has 16 rows of 8 bytes
    Serial.print(row);
    if(row < 10){
      Serial.print("  ");
    }
    else {
      Serial.print(" ");
    }
    for(int B=0; B<4; B++){      // load eight bytes at a time
      print_binary(ds.read(), 8);
    }
    Serial.println();
  }
}


void ReadAllMemBytes(){
  Serial.println("Reading from EEPROM as chars");
  ds.reset();
  ds.select(addr);
  ds.write(0xF0, 1);  // Read Memory
  ds.write(0x00, 1);  // Read Offset 0000h
  ds.write(0x00, 1);
  for(int row=0; row<16; row++){ // EEPROM has 16 rows of 8 bytes
    Serial.print(row);
    if(row < 10){
      Serial.print("  ");
    }
    else {
      Serial.print(" ");
    }
    for(int B=0; B<8; B++){      // load eight bytes at a time
      byte c = ds.read();
      if (c > 32){
        Serial.print(char(c));
      }
      else {
        Serial.print(" ");
      }
    }
    Serial.println();
  }
}


void ReadAllMemHex(){
  Serial.println("Reading from EEPROM as HEX");
  ds.reset();
  ds.select(addr);
  ds.write(0xF0, 1);  // Read Memory
  ds.write(0x00, 1);  // Read Offset 0000h
  ds.write(0x00, 1);
  for(int row=0; row<16; row++){ // EEPROM has 16 rows of 8 bytes
    Serial.print(row);
    if(row < 10){
      Serial.print("  ");
    }
    else {
      Serial.print(" ");
    }
    for(int B=0; B<8; B++){      // load eight bytes at a time
      print_hex(ds.read(), 8);
      Serial.print(" ");
    }
    Serial.println();
  }
}


void WriteRow(byte row, byte* buffer){
  if (row < 0 || row > 15) //There are 16 row of 8 bytes in the main memory
    return;                //The remaining are for the 64 bits register page
    
  WriteReadScratchPad(row*8, 0x00, buffer);
  CopyScratchPad(buffer);
  
}


void print_binary(int v, int num_places) {
  //http://www.phanderson.com/arduino/arduino_display.html
    int mask=0, n;

    for (n=1; n<=num_places; n++) {
        mask = (mask << 1) | 0x0001;
    }
    v = v & mask;  // truncate v to specified number of places

    while(num_places){
        if (v & (0x0001 << num_places-1))        {
             Serial.print("1 ");
        }
        else        {
             Serial.print("  ");
        }
        --num_places;
    }
}


void print_hex(int v, int num_places) {
    int mask=0, n, num_nibbles, digit;

    for (n=1; n<=num_places; n++)  {
        mask = (mask << 1) | 0x0001;
    }
    v = v & mask; // truncate v to specified number of places

    num_nibbles = num_places / 4;
    if ((num_places % 4) != 0) {
        ++num_nibbles;
    }

    do {
        digit = ((v >> (num_nibbles-1) * 4)) & 0x0f;
        Serial.print(digit, HEX);
    } while(--num_nibbles);

}


void erase(){
  Serial.print("Writing zeros EEPROM ");
  int i = 0;
  byte dat[13];
  for(int row=0; row<16; row++){ // EEPROM has 16 rows of 8 bytes
    for(int B=0; B<8; B++){      // load eight bytes at a tim6; row++){
      dat[B] = 0;
      i++;
    }
    Serial.print(".");    
    WriteRow(row, dat);          // write the bytes out to EEPROM
    delay(10);
  }
  Serial.println("\nDone");}


/*
  SerialEvent occurs whenever a new data comes in the
 hardware serial RX.  This routine is run between each
 time loop() runs, so using delay inside loop can delay
 response.  Multiple bytes of data may be available.
 */
void serialEvent() {
  byte inChar;
  while (Serial.available()) {
    // get the new byte:
    inChar = (byte)Serial.read(); 
  }

  if(inChar == 'e' ){
    if(SearchAddress(addr)){
      erase();
      blink = 0;
    }
    else{
      blink = 100;
    }
  }

  if(inChar == 'h' ){
    if(SearchAddress(addr)){
      ReadAllMemHex();
      blink = 0;
    }
    else{
      blink = 100;
    }
  } 
  
  if(inChar == 'b' ){
    if(SearchAddress(addr)){
      ReadAllMemBits();
      blink = 0;
    }
    else{
      blink = 100;
    }
  }
  
  if(inChar == 's' ){
    if(SearchAddress(addr)){
      ReadAllMemBytes();
      blink = 0;
    }
    else{
      blink = 100;
    }
  }
  
  if(inChar == 'w' ){
    if(SearchAddress(addr)){
      writeBitMap(bitMap);
      blink = 0;
    }
    else{
      blink = 100;
    }
  }
  
  if(inChar == 'c' ){
    if(SearchAddress(addr)){
      writeString();
      blink = 0;
    }
    else{
      blink = 100;
    } 
  }
  
  if(inChar == 'm' ){
    menu();
    blink = 0;
  }
}

Can you remove the chip and then reprogram?

Yes, chips can be removed and reprogrammed, but only if the toner level on the chip is more than 0% (value 1% - 100%). It's a protection - the printer will lock the chip in case of the message: toner empty (0%).

Not sure how it locks the chip but copy a chip from a new cartridge then get replacement chips and program them with what you got form the new cartridge chip.

I modified the code, now I will read the registers. Is it possible to reset the values ​​at addresses 80h - 84h?

void ReadAllMemHex(){
  Serial.println("Reading from EEPROM as HEX");
  ds.reset();
  ds.select(addr);
  ds.write(0xF0, 1);  // Read Memory
  ds.write(0x00, 1);  // Read Offset 0000h
  ds.write(0x00, 1);
  for(int row=0; row<17; row++){ // EEPROM has 16 rows of 8 bytes
    Serial.print(row);
    if(row < 10){
      Serial.print("  ");
    }
    else {
      Serial.print(" ");
    }
    for(int B=0; B<8; B++){      // load eight bytes at a time
      print_hex(ds.read(), 8);
      Serial.print(" ");

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.