Monday, April 27, 2015

 

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 or Mega
//Tests whether a DS1302 will process a change of the byte controlling Trickle Charge settings (if not, may be a fake)
//John Geddes, February 2016


#include
#include //http://playground.arduino.cc/uploads/Main/DS1302RTC.zip

const int PIN_1302_CE   = A0;   //5;  // Chip Enable
const int PIN_1302_IO   = A1;   //6;  // Input/Output
const int PIN_1302_SCLK = A2;   //7;  // Serial Clock


#define OPTION_TRICKLE_CHARGE_BYTE 0
#define OPTION_YEAR_BYTE 1
byte testResult=0;//score 1 for rtc byte ok, 2 for yeat byte ok. value of 3 means all ok
DS1302RTC my1032rtc(PIN_1302_CE, PIN_1302_IO, PIN_1302_SCLK);

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

byte toggleByteAndReportOutcome(byte whichByte){
  //returns 1 if ok, otherwise 0
  byte addressWriteByte; //read byte has address one higher
  byte retValIfOK=0;
  String descString;
  byte maxValueBeforeReturningTo1;
  byte valueA;
  byte valueB;
  switch (whichByte){
    case OPTION_TRICKLE_CHARGE_BYTE:
      descString="TRICKLE-CHARGE";
      addressWriteByte=0x90;
      retValIfOK=1;
      valueA=165;
      valueB=166;
      break;
    case OPTION_YEAR_BYTE:
      descString="YEAR";
      addressWriteByte=0x8c;
      retValIfOK=2;
      valueA=B10100001;
      valueB=B10100111;
      break;    
  }
  byte startingByteValue=my1032rtc.readRTC((addressWriteByte+1));
  byte targetByteValue=startingByteValue+1;

  if (startingByteValue==valueA){
    targetByteValue=valueB;
  } else {
    targetByteValue=valueA;
  }

  Serial.print("Attempt to update ");
  Serial.print(descString);
  Serial.print(" byte which currently holds value of ");
  Serial.print(startingByteValue);
  Serial.print(", ie ");
  printPaddedBin(startingByteValue, 8, false);
  Serial.print(" to new value of ");
  Serial.print(targetByteValue);
  Serial.print(", ie ");
  printPaddedBin(targetByteValue, 8, true);

  my1032rtc.writeRTC(addressWriteByte,targetByteValue);
  byte revisedByteValue=my1032rtc.readRTC((addressWriteByte+1));
  if (revisedByteValue==targetByteValue){
    Serial.print("SUCCESS - new value is ");
    Serial.print(revisedByteValue);
    Serial.print(", ie ");
    printPaddedBin(revisedByteValue, 8, true);
    return retValIfOK;
  } else if (revisedByteValue==startingByteValue){
    Serial.print("ERROR - updating has failed: value stayed at ");
    Serial.print(revisedByteValue);
    Serial.print(", ie ");
    printPaddedBin(revisedByteValue, 8, true);
    return 0;
  } else {
    Serial.print("ERROR - updating has failed: value changed but wrong -  at ");
    Serial.print(revisedByteValue);
    Serial.print(", ie ");
    printPaddedBin(revisedByteValue, 8, true);
    return 0;
  }
}


void setup() {
  delay (2000);//time to open Serial Monitor
  Serial.begin(9600);
  Serial.println("DS1302 test started");
  //initialise RTC to be writeable but clock STOPPED
  my1032rtc.writeEN(1);
  Serial.println("DS1302 set to write-enabled");
  my1032rtc.haltRTC(1);//in case this helps
  Serial.println("DS1302 halted");
  testResult+=toggleByteAndReportOutcome(OPTION_TRICKLE_CHARGE_BYTE);
  
  Serial.print("testResult=");
  Serial.println(testResult);
  
  testResult+=toggleByteAndReportOutcome(OPTION_YEAR_BYTE);
  
  Serial.print("testResult=");
  Serial.println(testResult);

  Serial.println("\n");
  switch(testResult){
    case 0:
      Serial.println("Failed both tests: could not update trickle-charge byte or year byte. Check connections");
      break;
    case 1:
      Serial.println ("OK on updating trickle-charge byte but failed on year byte - looks like genuine-but-faulty chip");
      break;
    case 2:
      Serial.println ("Failed to update trickle-charge byte but succeeded with change of year byte - this is the result you get with a FAKE DS1302");
      break;
    case 3:
      Serial.println ("OK on both tests - GENUINE DS1302 working properly");
      break;
  }
}

void loop() {}


Comments:
Get the best price for your mobile phone with PhoneMonkey today. We have the best mobile. We have Sell my Iphone (5, 5s 5c 4s 6), Sell my phone, how much is my phone worth, Sell my Ipad (Air Mini) and PhoneMonkey.
 
Post a Comment



<< Home

This page is powered by Blogger. Isn't yours?