Fake DS1302 chips

After wasting many hours trying to set the Trickle Charge parameters on my otherwise-obedient DS1302 chips, I eventually realised that I had counterfeit chips.


I've knocked up an Arduino sketch that will try to set the Trickle Charge byte, reporting back on success or failure - users of other hardware can still get the gist:

//written for Uno R3
//Tests whether a DS1302 will process a change of the byte controlling Trickle Charge settings (if not, may be a fake)
//John Geddes, March 2015

#include 
#include //http://playground.arduino.cc/uploads/Main/DS1302RTC.zip
const byte tcOption[]={B11110000,B10100101,B10100110,B10100111,B10101001,B10101010,B10101011,B00111010};
const int kCePin   = 5;  // Chip Enable
const int kIoPin   = 6;  // Input/Output
const int kSclkPin = 7;  // Serial Clock

DS1302RTC my1032rtc(kCePin, kIoPin, kSclkPin);

void printPaddedBin(unsigned long thisValue, byte outputLength=8, boolean endLine=false){
  String thisString;
  String netString=String(thisValue,BIN);//no leading zeroes
  byte padCharsRequired=outputLength-netString.length();
  for (byte padCount=0; padCount<(padCharsRequired);padCount++){
    thisString.concat("0");
  }
  Serial.print(thisString);
  Serial.print(netString);
  if (endLine){
    Serial.println();
  }
}

boolean setTrickleCharging(DS1302RTC thisRTC, boolean setChargingOn, byte ohms=0, byte noDiodes=0){
  //returns True if the setting is done successfully (or value is already correct)
  byte tcByte=0;//default=OFF (anything other than 1010 in bytes 7 to 4 disables trickle charging)
  if (setChargingOn){
    tcByte=160; //B10100000 - sets to Enabled but leaves resistor and diode bits at zero: we will add to these as appropriate;
    switch (noDiodes){
      case 1:
        tcByte+=4; //bit 2
        break;
      case 2:
        tcByte+=8; //bit 3
        break;
      default:
        Serial.println("Error: if setting ON, need either 1 or 2 diodes selected");
        return false;
    }
    switch (ohms){
      case 2:
        tcByte+=1; //bit 0
        break;
      case 4:
        tcByte+=2; //bit 1
        break;
      case 8:
        tcByte+=3; //bits 1 AND 2
        break;
      default:
        Serial.println("Error: if setting ON, need either 2, 4 or 8 ohms selected");
        return false;
    }
  } else {
    //leave value as default which sets as Disabled
  }
  thisRTC.writeEN(1); //in case the write-protect bit was set

  byte startValue=thisRTC.readRTC(0x91);

  if (startValue==tcByte){
    Serial.print("Trickle-charge byte was already set to ");
    Serial.print(tcByte);
    Serial.print(", ie ");
    printPaddedBin(tcByte, 8, true);
    return true;
  }
  //if here, then we are changing the byte
  thisRTC.writeRTC(0x90,tcByte);
  byte newValue=thisRTC.readRTC(0x91);
  if (newValue==startValue){
    //see if we can change the YEAR byte (which works on both genuine and dud/fake chips)
    byte currentByte_RTCyear=thisRTC.readRTC(0x8d);
    //now set it to a different value
    byte revisedYearByte;
    if (currentByte_RTCyear==B11110000){
      revisedYearByte=B10100101;
    } else {
      revisedYearByte=B11110000;   
    }
    thisRTC.writeRTC(0x8c,revisedYearByte);
    byte updatedValue_RTCyear=thisRTC.readRTC(0x8d);
    if (updatedValue_RTCyear==currentByte_RTCyear){
      Serial.print("Error 2: appears to write OK but does not change existing byte values for either Trickle-charge Byte (0x90) or Year byte (0x8c)");
      return false;
    } else {
      if (updatedValue_RTCyear==updatedValue_RTCyear){
        thisRTC.writeRTC(0x8c,currentByte_RTCyear);//set the year byte back again
        Serial.print("Error 3: will update Year byte (0x8c) but not Trickle-charge Byte (0x90) - looks like you might have a fake or defective DS1302");
      } else {
        thisRTC.writeRTC(0x8c,currentByte_RTCyear);//set the year byte back again
        Serial.print("Error 4: will update Year byte (0x8c) but to the wrong value - looks like you might have a fake or defective DS1302");
      }
    }
  } else {
    if (newValue==tcByte){
      //Bingo!
      Serial.print("SUCCESS - trickle-charging byte changed to ");
      Serial.print(tcByte);
      Serial.print(", ie ");
      printPaddedBin(tcByte);
      return true;
    } else {
      Serial.print("Error 5 changes existing value, which was  ");
      Serial.print(startValue);
      Serial.print(" (");
      printPaddedBin(startValue);
      Serial.print(") to new value of  ");
      Serial.print(newValue);
      Serial.print(" (");
      printPaddedBin(newValue);
      Serial.print(") instead of desired value of  ");
      Serial.print(tcByte);
      Serial.print(" (");
      printPaddedBin(tcByte);
      Serial.print(")");
      return false;
    }
  }
}


void setup() {
  delay (5000);//time to open Serial Monitor
  Serial.begin(9600);
  //initialise RTC to be writeable but clock STOPPED
  my1032rtc.writeEN(1);
  my1032rtc.haltRTC(1);//in case this helps
  setTrickleCharging(my1032rtc,true,2,1);
}

void loop() {}

Comments

Popular posts from this blog

HOW TO REGISTER FOR SAFETOKEN

How To Get Help In MMM Nigeria - Mavrodi Mondial Moneybox