- int i=0;
- int clk[]={8,16,32,40,50,64,100,128,256};
- int loopCnt = 256; //don't need to loop through entire array...
- if (size<loopCnt) loopCnt = size;
-
- //if we already have a valid clock quit
-
- for (;i<8;++i)
- if (clk[i] == clock) return clock;
-
- //get high and low peak
- int peak, low;
- getHiLo(dest, loopCnt, &peak, &low, 75, 75);
-
- int ii;
- int clkCnt;
- int tol = 0;
- int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
- int errCnt=0;
- //test each valid clock from smallest to greatest to see which lines up
- for(clkCnt=0; clkCnt < 8; ++clkCnt){
- if (clk[clkCnt] == 32){
- tol=1;
- }else{
- tol=0;
- }
- bestErr[clkCnt]=1000;
- //try lining up the peaks by moving starting point (try first 256)
- for (ii=0; ii < loopCnt; ++ii){
- if ((dest[ii] >= peak) || (dest[ii] <= low)){
- errCnt=0;
- // now that we have the first one lined up test rest of wave array
- for (i=0; i<((int)((size-ii-tol)/clk[clkCnt])-1); ++i){
- if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){
- }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){
- }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){
- }else{ //error no peak detected
- errCnt++;
- }
- }
- //if we found no errors then we can stop here
- // this is correct one - return this clock
- //PrintAndLog("DEBUG: clk %d, err %d, ii %d, i %d",clk[clkCnt],errCnt,ii,i);
- if(errCnt==0 && clkCnt<6) return clk[clkCnt];
- //if we found errors see if it is lowest so far and save it as best run
- if(errCnt<bestErr[clkCnt]) bestErr[clkCnt]=errCnt;
- }
- }
- }
- uint8_t iii=0;
- uint8_t best=0;
- for (iii=0; iii<8; ++iii){
- if (bestErr[iii]<bestErr[best]){
- if (bestErr[iii]==0) bestErr[iii]=1;
- // current best bit to error ratio vs new bit to error ratio
- if (((size/clk[best])/bestErr[best] < (size/clk[iii])/bestErr[iii]) ){
- best = iii;
- }
- }
- }
- return clk[best];
+ size_t i=1;
+ uint8_t clk[] = {255,8,16,32,40,50,64,100,128,255};
+ uint8_t clkEnd = 9;
+ uint8_t loopCnt = 255; //don't need to loop through entire array...
+ if (size <= loopCnt) return -1; //not enough samples
+
+ //if we already have a valid clock
+ uint8_t clockFnd=0;
+ for (;i<clkEnd;++i)
+ if (clk[i] == *clock) clockFnd = i;
+ //clock found but continue to find best startpos
+
+ //get high and low peak
+ int peak, low;
+ if (getHiLo(dest, loopCnt, &peak, &low, 75, 75) < 1) return -1;
+
+ //test for large clean peaks
+ if (!clockFnd){
+ if (DetectCleanAskWave(dest, size, peak, low)==1){
+ int ans = DetectStrongAskClock(dest, size, peak, low);
+ for (i=clkEnd-1; i>0; i--){
+ if (clk[i] == ans) {
+ *clock = ans;
+ //clockFnd = i;
+ return 0; // for strong waves i don't use the 'best start position' yet...
+ //break; //clock found but continue to find best startpos [not yet]
+ }
+ }
+ }
+ }
+
+ uint8_t ii;
+ uint8_t clkCnt, tol = 0;
+ uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
+ uint8_t bestStart[]={0,0,0,0,0,0,0,0,0};
+ size_t errCnt = 0;
+ size_t arrLoc, loopEnd;
+
+ if (clockFnd>0) {
+ clkCnt = clockFnd;
+ clkEnd = clockFnd+1;
+ }
+ else clkCnt=1;
+
+ //test each valid clock from smallest to greatest to see which lines up
+ for(; clkCnt < clkEnd; clkCnt++){
+ if (clk[clkCnt] <= 32){
+ tol=1;
+ }else{
+ tol=0;
+ }
+ //if no errors allowed - keep start within the first clock
+ if (!maxErr && size > clk[clkCnt]*2 + tol && clk[clkCnt]<128) loopCnt=clk[clkCnt]*2;
+ bestErr[clkCnt]=1000;
+ //try lining up the peaks by moving starting point (try first few clocks)
+ for (ii=0; ii < loopCnt; ii++){
+ if (dest[ii] < peak && dest[ii] > low) continue;
+
+ errCnt=0;
+ // now that we have the first one lined up test rest of wave array
+ loopEnd = ((size-ii-tol) / clk[clkCnt]) - 1;
+ for (i=0; i < loopEnd; ++i){
+ arrLoc = ii + (i * clk[clkCnt]);
+ if (dest[arrLoc] >= peak || dest[arrLoc] <= low){
+ }else if (dest[arrLoc-tol] >= peak || dest[arrLoc-tol] <= low){
+ }else if (dest[arrLoc+tol] >= peak || dest[arrLoc+tol] <= low){
+ }else{ //error no peak detected
+ errCnt++;
+ }
+ }
+ //if we found no errors then we can stop here and a low clock (common clocks)
+ // this is correct one - return this clock
+ //PrintAndLog("DEBUG: clk %d, err %d, ii %d, i %d",clk[clkCnt],errCnt,ii,i);
+ if(errCnt==0 && clkCnt<7) {
+ if (!clockFnd) *clock = clk[clkCnt];
+ return ii;
+ }
+ //if we found errors see if it is lowest so far and save it as best run
+ if(errCnt<bestErr[clkCnt]){
+ bestErr[clkCnt]=errCnt;
+ bestStart[clkCnt]=ii;
+ }
+ }
+ }
+ uint8_t iii;
+ uint8_t best=0;
+ for (iii=1; iii<clkEnd; ++iii){
+ if (bestErr[iii] < bestErr[best]){
+ if (bestErr[iii] == 0) bestErr[iii]=1;
+ // current best bit to error ratio vs new bit to error ratio
+ if ( (size/clk[best])/bestErr[best] < (size/clk[iii])/bestErr[iii] ){
+ best = iii;
+ }
+ }
+ }
+ //if (bestErr[best] > maxErr) return -1;
+ if (!clockFnd) *clock = clk[best];
+ return bestStart[best];
+}
+
+//by marshmellow
+//detect psk clock by reading each phase shift
+// a phase shift is determined by measuring the sample length of each wave
+int DetectPSKClock(uint8_t dest[], size_t size, int clock)
+{
+ uint8_t clk[]={255,16,32,40,50,64,100,128,255}; //255 is not a valid clock
+ uint16_t loopCnt = 4096; //don't need to loop through entire array...
+ if (size == 0) return 0;
+ if (size<loopCnt) loopCnt = size;
+
+ //if we already have a valid clock quit
+ size_t i=1;
+ for (; i < 8; ++i)
+ if (clk[i] == clock) return clock;
+
+ size_t waveStart=0, waveEnd=0, firstFullWave=0, lastClkBit=0;
+ uint8_t clkCnt, fc=0, fullWaveLen=0, tol=1;
+ uint16_t peakcnt=0, errCnt=0, waveLenCnt=0;
+ uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
+ uint16_t peaksdet[]={0,0,0,0,0,0,0,0,0};
+ fc = countFC(dest, size, 0);
+ if (fc!=2 && fc!=4 && fc!=8) return -1;
+ //PrintAndLog("DEBUG: FC: %d",fc);
+
+ //find first full wave
+ for (i=0; i<loopCnt; i++){
+ if (dest[i] < dest[i+1] && dest[i+1] >= dest[i+2]){
+ if (waveStart == 0) {
+ waveStart = i+1;
+ //PrintAndLog("DEBUG: waveStart: %d",waveStart);
+ } else {
+ waveEnd = i+1;
+ //PrintAndLog("DEBUG: waveEnd: %d",waveEnd);
+ waveLenCnt = waveEnd-waveStart;
+ if (waveLenCnt > fc){
+ firstFullWave = waveStart;
+ fullWaveLen=waveLenCnt;
+ break;
+ }
+ waveStart=0;
+ }
+ }
+ }
+ //PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen);
+
+ //test each valid clock from greatest to smallest to see which lines up
+ for(clkCnt=7; clkCnt >= 1 ; clkCnt--){
+ lastClkBit = firstFullWave; //set end of wave as clock align
+ waveStart = 0;
+ errCnt=0;
+ peakcnt=0;
+ //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d",clk[clkCnt],lastClkBit);
+
+ for (i = firstFullWave+fullWaveLen-1; i < loopCnt-2; i++){
+ //top edge of wave = start of new wave
+ if (dest[i] < dest[i+1] && dest[i+1] >= dest[i+2]){
+ if (waveStart == 0) {
+ waveStart = i+1;
+ waveLenCnt=0;
+ } else { //waveEnd
+ waveEnd = i+1;
+ waveLenCnt = waveEnd-waveStart;
+ if (waveLenCnt > fc){
+ //if this wave is a phase shift
+ //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, ii: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,ii+1,fc);
+ if (i+1 >= lastClkBit + clk[clkCnt] - tol){ //should be a clock bit
+ peakcnt++;
+ lastClkBit+=clk[clkCnt];
+ } else if (i<lastClkBit+8){
+ //noise after a phase shift - ignore
+ } else { //phase shift before supposed to based on clock
+ errCnt++;
+ }
+ } else if (i+1 > lastClkBit + clk[clkCnt] + tol + fc){
+ lastClkBit+=clk[clkCnt]; //no phase shift but clock bit
+ }
+ waveStart=i+1;
+ }
+ }
+ }
+ if (errCnt == 0){
+ return clk[clkCnt];
+ }
+ if (errCnt <= bestErr[clkCnt]) bestErr[clkCnt]=errCnt;
+ if (peakcnt > peaksdet[clkCnt]) peaksdet[clkCnt]=peakcnt;
+ }
+ //all tested with errors
+ //return the highest clk with the most peaks found
+ uint8_t best=7;
+ for (i=7; i>=1; i--){
+ if (peaksdet[i] > peaksdet[best]) {
+ best = i;
+ }
+ //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best]);
+ }
+ return clk[best];