-int DetectpskNRZClock(uint8_t dest[], size_t size, int clock)
-{
- int i=0;
- int peak=0;
- int low=128;
- int clk[]={16,32,40,50,64,100,128,256};
- int loopCnt = 2048; //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
- for (i=0;i<loopCnt;++i){
- if(dest[i]>peak){
- peak = dest[i];
- }
- if(dest[i]<low){
- low = dest[i];
- }
- }
- peak=(int)(((peak-128)*.90)+128);
- low= (int)(((low-128)*.90)+128);
- //PrintAndLog("DEBUG: peak: %d, low: %d",peak,low);
- int ii;
- int clkCnt;
- int tol = 0;
- int peakcnt=0;
- int errCnt=0;
- int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
- int peaksdet[]={0,0,0,0,0,0,0,0,0};
- //test each valid clock from smallest to greatest to see which lines up
- for(clkCnt=0; clkCnt<6;++clkCnt){
- if (clk[clkCnt]==32){
- tol=0;
- }else{
- tol=0;
- }
- //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;
- peakcnt=0;
- // now that we have the first one lined up test rest of wave array
- for (i=0; i<((int)(size/clk[clkCnt])-1); ++i){
- if (dest[ii+(i*clk[clkCnt])]>=peak || dest[ii+(i*clk[clkCnt])]<=low){
- peakcnt++;
- }else if(dest[ii+(i*clk[clkCnt])-tol]>=peak || dest[ii+(i*clk[clkCnt])-tol]<=low){
- peakcnt++;
- }else if(dest[ii+(i*clk[clkCnt])+tol]>=peak || dest[ii+(i*clk[clkCnt])+tol]<=low){
- peakcnt++;
- }else{ //error no peak detected
- errCnt++;
- }
- }
- if(peakcnt>peaksdet[clkCnt]) {
- peaksdet[clkCnt]=peakcnt;
- bestErr[clkCnt]=errCnt;
- }
- }
- }
- }
- int iii=0;
- int best=0;
- //int ratio2; //debug
- int ratio;
- //int bits;
- for (iii=0; iii<7;++iii){
- ratio=1000;
- //ratio2=1000; //debug
- //bits=size/clk[iii]; //debug
- if (peaksdet[iii]>0){
- ratio=bestErr[iii]/peaksdet[iii];
- if (((bestErr[best]/peaksdet[best])>(ratio)+1)){
- best = iii;
- }
- //ratio2=bits/peaksdet[iii]; //debug
- }
- //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d, ratio: %d, bits: %d, peakbitr: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best],ratio, bits,ratio2);
- }
- return clk[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-20;
+
+ //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;
+ if (g_debugMode==2) prnt("DEBUG PSK: FC: %d",fc);
+
+ //find first full wave
+ for (i=160; i<loopCnt; i++){
+ if (dest[i] < dest[i+1] && dest[i+1] >= dest[i+2]){
+ if (waveStart == 0) {
+ waveStart = i+1;
+ //prnt("DEBUG: waveStart: %d",waveStart);
+ } else {
+ waveEnd = i+1;
+ //prnt("DEBUG: waveEnd: %d",waveEnd);
+ waveLenCnt = waveEnd-waveStart;
+ if (waveLenCnt > fc){
+ firstFullWave = waveStart;
+ fullWaveLen=waveLenCnt;
+ break;
+ }
+ waveStart=0;
+ }
+ }
+ }
+ if (g_debugMode ==2) prnt("DEBUG PSK: 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;
+ if (g_debugMode == 2) prnt("DEBUG PSK: 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
+ if (g_debugMode == 2) prnt("DEBUG PSK: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,i+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;
+ }
+ if (g_debugMode == 2) prnt("DEBUG PSK: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[i],peaksdet[i],bestErr[i],clk[best]);
+ }
+ return clk[best];
+}
+
+int DetectStrongNRZClk(uint8_t *dest, size_t size, int peak, int low){
+ //find shortest transition from high to low
+ size_t i = 0;
+ size_t transition1 = 0;
+ int lowestTransition = 255;
+ bool lastWasHigh = false;
+
+ //find first valid beginning of a high or low wave
+ while ((dest[i] >= peak || dest[i] <= low) && (i < size))
+ ++i;
+ while ((dest[i] < peak && dest[i] > low) && (i < size))
+ ++i;
+ lastWasHigh = (dest[i] >= peak);
+
+ if (i==size) return 0;
+ transition1 = i;
+
+ for (;i < size; i++) {
+ if ((dest[i] >= peak && !lastWasHigh) || (dest[i] <= low && lastWasHigh)) {
+ lastWasHigh = (dest[i] >= peak);
+ if (i-transition1 < lowestTransition) lowestTransition = i-transition1;
+ transition1 = i;
+ }
+ }
+ if (lowestTransition == 255) lowestTransition = 0;
+ if (g_debugMode==2) prnt("DEBUG NRZ: detectstrongNRZclk smallest wave: %d",lowestTransition);
+ return lowestTransition;
+}
+
+//by marshmellow
+//detect nrz clock by reading #peaks vs no peaks(or errors)
+int DetectNRZClock(uint8_t dest[], size_t size, int clock)
+{
+ size_t i=0;
+ uint8_t clk[]={8,16,32,40,50,64,100,128,255};
+ size_t loopCnt = 4096; //don't need to loop through entire array...
+ if (size == 0) return 0;
+ if (size<loopCnt) loopCnt = size-20;
+ //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;
+ if (getHiLo(dest, loopCnt, &peak, &low, 75, 75) < 1) return 0;
+
+ int lowestTransition = DetectStrongNRZClk(dest, size-20, peak, low);
+ size_t ii;
+ uint8_t clkCnt;
+ uint8_t tol = 0;
+ uint16_t smplCnt = 0;
+ int16_t peakcnt = 0;
+ int16_t peaksdet[] = {0,0,0,0,0,0,0,0};
+ uint16_t maxPeak = 255;
+ bool firstpeak = false;
+ //test for large clipped waves
+ for (i=0; i<loopCnt; i++){
+ if (dest[i] >= peak || dest[i] <= low){
+ if (!firstpeak) continue;
+ smplCnt++;
+ } else {
+ firstpeak=true;
+ if (smplCnt > 6 ){
+ if (maxPeak > smplCnt){
+ maxPeak = smplCnt;
+ //prnt("maxPk: %d",maxPeak);
+ }
+ peakcnt++;
+ //prnt("maxPk: %d, smplCnt: %d, peakcnt: %d",maxPeak,smplCnt,peakcnt);
+ smplCnt=0;
+ }
+ }
+ }
+ bool errBitHigh = 0;
+ bool bitHigh = 0;
+ uint8_t ignoreCnt = 0;
+ uint8_t ignoreWindow = 4;
+ bool lastPeakHigh = 0;
+ int lastBit = 0;
+ peakcnt=0;
+ //test each valid clock from smallest to greatest to see which lines up
+ for(clkCnt=0; clkCnt < 8; ++clkCnt){
+ //ignore clocks smaller than smallest peak
+ if (clk[clkCnt] < maxPeak - (clk[clkCnt]/4)) continue;
+ //try lining up the peaks by moving starting point (try first 256)
+ for (ii=20; ii < loopCnt; ++ii){
+ if ((dest[ii] >= peak) || (dest[ii] <= low)){
+ peakcnt = 0;
+ bitHigh = false;
+ ignoreCnt = 0;
+ lastBit = ii-clk[clkCnt];
+ //loop through to see if this start location works
+ for (i = ii; i < size-20; ++i) {
+ //if we are at a clock bit
+ if ((i >= lastBit + clk[clkCnt] - tol) && (i <= lastBit + clk[clkCnt] + tol)) {
+ //test high/low
+ if (dest[i] >= peak || dest[i] <= low) {
+ //if same peak don't count it
+ if ((dest[i] >= peak && !lastPeakHigh) || (dest[i] <= low && lastPeakHigh)) {
+ peakcnt++;
+ }
+ lastPeakHigh = (dest[i] >= peak);
+ bitHigh = true;
+ errBitHigh = false;
+ ignoreCnt = ignoreWindow;
+ lastBit += clk[clkCnt];
+ } else if (i == lastBit + clk[clkCnt] + tol) {
+ lastBit += clk[clkCnt];
+ }
+ //else if not a clock bit and no peaks
+ } else if (dest[i] < peak && dest[i] > low){
+ if (ignoreCnt==0){
+ bitHigh=false;
+ if (errBitHigh==true) peakcnt--;
+ errBitHigh=false;
+ } else {
+ ignoreCnt--;
+ }
+ // else if not a clock bit but we have a peak
+ } else if ((dest[i]>=peak || dest[i]<=low) && (!bitHigh)) {
+ //error bar found no clock...
+ errBitHigh=true;
+ }
+ }
+ if(peakcnt>peaksdet[clkCnt]) {
+ peaksdet[clkCnt]=peakcnt;
+ }
+ }
+ }
+ }
+ int iii=7;
+ uint8_t best=0;
+ for (iii=7; iii > 0; iii--){
+ if ((peaksdet[iii] >= (peaksdet[best]-1)) && (peaksdet[iii] <= peaksdet[best]+1) && lowestTransition) {
+ if (clk[iii] > (lowestTransition - (clk[iii]/8)) && clk[iii] < (lowestTransition + (clk[iii]/8))) {
+ best = iii;
+ }
+ } else if (peaksdet[iii] > peaksdet[best]){
+ best = iii;
+ }
+ if (g_debugMode==2) prnt("DEBUG NRZ: Clk: %d, peaks: %d, maxPeak: %d, bestClk: %d, lowestTrs: %d",clk[iii],peaksdet[iii],maxPeak, clk[best], lowestTransition);
+ }
+
+ return clk[best];
+}
+
+// by marshmellow
+// convert psk1 demod to psk2 demod
+// only transition waves are 1s
+void psk1TOpsk2(uint8_t *BitStream, size_t size)
+{
+ size_t i=1;
+ uint8_t lastBit=BitStream[0];
+ for (; i<size; i++){
+ if (BitStream[i]==7){
+ //ignore errors
+ } else if (lastBit!=BitStream[i]){
+ lastBit=BitStream[i];
+ BitStream[i]=1;
+ } else {
+ BitStream[i]=0;
+ }
+ }
+ return;