• 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() {}
  • You might also like

    No comments:

    Post a Comment

    Good day precious one, We love you more than anything.

Powered by Blogger.