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


 

BBC iPlayer Radio - for older Androids

The BBC disgracefully abandoned older Android users in 2014 when they "upgraded" their iPlayer app to use separate versions for TV and for Radio. The Radio app demanded Android 4 upwards - justified on the basis that over 80% of users had suitable devices. Tough luck for the rest of us.

We were intended to use the iPlayer radio feature on the BBC website, but I found this unusable - most browsers refused to load an appropriate driver, and when I did find a workable combination, programmes might take 15 attempts to start - or not start at all.

Eventually, I found a way to get near-100% availability, and offer it here. It works on my Samsung Galaxy Player 4.2 running Android 2.3.6 - and I hope it will work for you too.




Happy listening

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