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;
}
}