]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
data askraw patches, data askedgedetect demod,
authormarshmellow42 <marshmellowrf@gmail.com>
Fri, 6 Feb 2015 19:36:25 +0000 (14:36 -0500)
committermarshmellow42 <marshmellowrf@gmail.com>
Fri, 6 Feb 2015 19:36:25 +0000 (14:36 -0500)
data askraw patches - added amp option (for stubborn waves)
NEW data askedgedetect demod for manual demod,
adjusted detectclock (ask clock) in case of cleaned (edgedetect) waves
finish maxErr args
finish psk detect

client/cmddata.c
client/graph.c
common/lfdemod.c
common/lfdemod.h

index b03a3ebcd51dff16521be259c2e8724f0871552d..66ba7455531954d98f2491472a322b2317b149b1 100644 (file)
@@ -246,26 +246,6 @@ void printEM410x(uint64_t id)
     return;
 }
 
-//by marshmellow
-//take binary from demod buffer and see if we can find an EM410x ID
-int CmdEm410xDecode(const char *Cmd)
-{
-  uint64_t id=0;
-  size_t size = DemodBufferLen, idx=0;
-       id = Em410xDecode(DemodBuffer, &size, &idx);
-  if (id>0){
-    setDemodBuf(DemodBuffer, size, idx);
-    if (g_debugMode){
-      PrintAndLog("DEBUG: Printing demod buffer:");
-      printDemodBuff();
-    }
-    printEM410x(id);
-    return 1; 
-  }
-  return 0;
-}
-
-
 //by marshmellow
 //takes 3 arguments - clock, invert and maxErr as integers
 //attempts to demodulate ask while decoding manchester
@@ -276,7 +256,7 @@ int CmdAskEM410xDemod(const char *Cmd)
   int clk=0;
   int maxErr=100;
   char cmdp = param_getchar(Cmd, 0);
-  if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
+  if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
     PrintAndLog("Usage:  data askem410xdemod [clock] <0|1> [maxError]");
     PrintAndLog("     [set clock as integer] optional, if not set, autodetect.");
     PrintAndLog("     <invert>, 1 for invert output");
@@ -345,7 +325,7 @@ int Cmdaskmandemod(const char *Cmd)
        int clk=0;
   int maxErr=100;
   char cmdp = param_getchar(Cmd, 0);
-  if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
+  if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
     PrintAndLog("Usage:  data askmandemod [clock] <0|1> [maxError]");
     PrintAndLog("     [set clock as integer] optional, if not set, autodetect.");
     PrintAndLog("     <invert>, 1 for invert output");
@@ -364,6 +344,10 @@ int Cmdaskmandemod(const char *Cmd)
   if (invert != 0 && invert != 1) {
     PrintAndLog("Invalid argument: %s", Cmd);
     return 0;
+  }
+  if (clk==1){
+    invert=1;
+    clk=0;
   }
        size_t BitLen = getFromGraphBuf(BitStream);
   if (g_debugMode==1) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
@@ -409,6 +393,7 @@ int Cmdmandecoderaw(const char *Cmd)
   int i =0;
   int errCnt=0;
        size_t size=0;
+  size_t maxErr = 20;
   char cmdp = param_getchar(Cmd, 0);
   if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') {
     PrintAndLog("Usage:  data manrawdecode");
@@ -432,7 +417,7 @@ int Cmdmandecoderaw(const char *Cmd)
   }
        size=i;
        errCnt=manrawdecode(BitStream, &size);
-  if (errCnt>=20){
+  if (errCnt>=maxErr){
     PrintAndLog("Too many errors: %d",errCnt);
     return 0;
   }
@@ -471,7 +456,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
   int invert=0;
   int high=0, low=0;
   char cmdp = param_getchar(Cmd, 0);
-  if (strlen(Cmd) > 2 || cmdp == 'h' || cmdp == 'H') {
+  if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
     PrintAndLog("Usage:  data biphaserawdecode [offset] <invert>");
     PrintAndLog("     Converts 10 or 01 to 0 and 11 or 00 to 1");
     PrintAndLog("     --must have binary sequence in demodbuffer (run data askrawdemod first)");   
@@ -509,7 +494,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
 }
 
 //by marshmellow
-//takes 3 arguments - clock, invert, maxErr as integers
+//takes 4 arguments - clock, invert, maxErr as integers and amplify as char
 //attempts to demodulate ask only
 //prints binary found and saves in graphbuffer for further commands
 int Cmdaskrawdemod(const char *Cmd)
@@ -517,30 +502,40 @@ int Cmdaskrawdemod(const char *Cmd)
        int invert=0;
        int clk=0;
   int maxErr=100;
+  uint8_t askAmp = 0;
+  char amp = param_getchar(Cmd, 0);
   char cmdp = param_getchar(Cmd, 0);
-  if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
-    PrintAndLog("Usage:  data askrawdemod [clock] <0|1> [maxError]");
-    PrintAndLog("     [set clock as integer] optional, if not set, autodetect.");
-    PrintAndLog("     <invert>, 1 for invert output");
-    PrintAndLog("     [set maximum allowed errors], default = 100.");
+  if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') {
+    PrintAndLog("Usage:  data askrawdemod [clock] <invert> [maxError] [amplify]");
+    PrintAndLog("     [set clock as integer] optional, if not set, autodetect");
+    PrintAndLog("     <invert>, 1 to invert output");
+    PrintAndLog("     [set maximum allowed errors], default = 100");
+    PrintAndLog("     <amplify>, 'a' to attempt demod with ask amplification, default = no amp");
     PrintAndLog("");
-    PrintAndLog("    sample: data askrawdemod        = demod an ask tag from GraphBuffer");
-    PrintAndLog("          : data askrawdemod 32     = demod an ask tag from GraphBuffer using a clock of RF/32");
-    PrintAndLog("          : data askrawdemod 32 1   = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data");
-    PrintAndLog("          : data askrawdemod 1      = demod an ask tag from GraphBuffer while inverting data");
-    PrintAndLog("          : data askrawdemod 64 1 0 = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
+    PrintAndLog("    sample: data askrawdemod          = demod an ask tag from GraphBuffer");
+    PrintAndLog("          : data askrawdemod a        = demod an ask tag from GraphBuffer, amplified");
+    PrintAndLog("          : data askrawdemod 32       = demod an ask tag from GraphBuffer using a clock of RF/32");
+    PrintAndLog("          : data askrawdemod 32 1     = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data");
+    PrintAndLog("          : data askrawdemod 1        = demod an ask tag from GraphBuffer while inverting data");
+    PrintAndLog("          : data askrawdemod 64 1 0   = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
+    PrintAndLog("          : data askrawdemod 64 1 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
     return 0;
   }
   uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
-       sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
+       sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &amp);
   if (invert != 0 && invert != 1) {
     PrintAndLog("Invalid argument: %s", Cmd);
     return 0;
   }
+  if (clk==1){
+    invert=1;
+    clk=0;
+  }
+  if (amp == 'a' || amp == 'A') askAmp=1; 
        size_t BitLen = getFromGraphBuf(BitStream);
   if (BitLen==0) return 0;
   int errCnt=0;
-       errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert, maxErr);
+       errCnt = askrawdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp);
        if (errCnt==-1||BitLen<16){  //throw away static - allow 1 and -1 (in case of threshold command first)
                PrintAndLog("no data found");
     if (g_debugMode==1) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert);
@@ -716,6 +711,35 @@ int CmdGraphShiftZero(const char *Cmd)
   return 0;
 }
 
+//by marshmellow
+//use large jumps in read samples to identify edges of waves and then amplify that wave to max
+//similar to dirtheshold, threshold, and askdemod commands 
+//takes a threshold length which is the measured length between two samples then determines an edge
+int CmdAskEdgeDetect(const char *Cmd)
+{
+  int thresLen = 25;
+  sscanf(Cmd, "%i", &thresLen); 
+  int shift = 127;
+  int shiftedVal=0;
+  for(int i = 1; i<GraphTraceLen; i++){
+    if (GraphBuffer[i]-GraphBuffer[i-1]>=thresLen) //large jump up
+      shift=127;
+    else if(GraphBuffer[i]-GraphBuffer[i-1]<=-1*thresLen) //large jump down
+      shift=-127;
+
+    shiftedVal=GraphBuffer[i]+shift;
+
+    if (shiftedVal>127) 
+      shiftedVal=127;
+    else if (shiftedVal<-127) 
+      shiftedVal=-127;
+    GraphBuffer[i-1] = shiftedVal;
+  }
+  RepaintGraphWindow();
+  //CmdNorm("");
+  return 0;
+}
+
 /* Print our clock rate */
 // uses data from graphbuffer
 int CmdDetectClockRate(const char *Cmd)
@@ -726,8 +750,8 @@ int CmdDetectClockRate(const char *Cmd)
 
 //by marshmellow
 //fsk raw demod and print binary
-//takes 4 arguments - Clock, invert, rchigh, rclow
-//defaults: clock = 50, invert=0, rchigh=10, rclow=8 (RF/10 RF/8 (fsk2a))
+//takes 4 arguments - Clock, invert, fchigh, fclow
+//defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a))
 int CmdFSKrawdemod(const char *Cmd)
 {
   //raw fsk demod  no manchester decoding no start bit finding just get binary from wave
@@ -737,15 +761,16 @@ int CmdFSKrawdemod(const char *Cmd)
   int fchigh=0;
   int fclow=0;
   char cmdp = param_getchar(Cmd, 0);
-  if (strlen(Cmd) > 4 || cmdp == 'h' || cmdp == 'H') {
-    PrintAndLog("Usage:  data fskrawdemod [clock] <0|1> [rchigh] [rclow]");
-    PrintAndLog("     [set clock as integer] optional, if not set, autodetect.");
-    PrintAndLog("     <invert>, 1 for invert output");
-
-    PrintAndLog("     [set maximum allowed errors], default = 100.");
+  if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
+    PrintAndLog("Usage:  data fskrawdemod [clock] <invert> [fchigh] [fclow]");
+    PrintAndLog("     [set clock as integer] optional, omit for autodetect.");
+    PrintAndLog("     <invert>, 1 for invert output, can be used even if the clock is omitted");
+    PrintAndLog("     [fchigh], larger field clock length, omit for autodetect");
+    PrintAndLog("     [fclow], small field clock length, omit for autodetect");
     PrintAndLog("");
     PrintAndLog("    sample: data fskrawdemod           = demod an fsk tag from GraphBuffer using autodetect");
     PrintAndLog("          : data fskrawdemod 32        = demod an fsk tag from GraphBuffer using a clock of RF/32, autodetect fc");
+    PrintAndLog("          : data fskrawdemod 1         = demod an fsk tag from GraphBuffer using autodetect, invert output");   
     PrintAndLog("          : data fskrawdemod 32 1      = demod an fsk tag from GraphBuffer using a clock of RF/32, invert output, autodetect fc");
     PrintAndLog("          : data fskrawdemod 64 0 8 5  = demod an fsk1 RF/64 tag from GraphBuffer");
     PrintAndLog("          : data fskrawdemod 50 0 10 8 = demod an fsk2 RF/50 tag from GraphBuffer");
@@ -1381,10 +1406,8 @@ int CmdFSKfcDetect(const char *Cmd)
     return 0;
   }
   if ((fc1==10 && fc2==8) || (fc1==8 && fc2==5)){
-    if (g_debugMode){
-      PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1);
-      return 1;
-    }
+    PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1);
+    return 1;
   }
   if (g_debugMode){
     PrintAndLog("DEBUG: unknown fsk field clock detected");
@@ -1550,7 +1573,7 @@ int CmdNRZrawDemod(const char *Cmd)
   int clk=0;
   int maxErr=100;
   char cmdp = param_getchar(Cmd, 0);
-  if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
+  if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
     PrintAndLog("Usage:  data nrzrawdemod [clock] <0|1> [maxError]");
     PrintAndLog("     [set clock as integer] optional, if not set, autodetect.");
     PrintAndLog("     <invert>, 1 for invert output");
@@ -1609,7 +1632,7 @@ int CmdPSK1rawDemod(const char *Cmd)
 {
   int errCnt;
   char cmdp = param_getchar(Cmd, 0);
-  if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
+  if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
     PrintAndLog("Usage:  data psk1rawdemod [clock] <0|1> [maxError]");
     PrintAndLog("     [set clock as integer] optional, if not set, autodetect.");
     PrintAndLog("     <invert>, 1 for invert output");
@@ -1644,7 +1667,7 @@ int CmdPSK2rawDemod(const char *Cmd)
 {
   int errCnt=0;
   char cmdp = param_getchar(Cmd, 0);
-  if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
+  if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
     PrintAndLog("Usage:  data psk2rawdemod [clock] <0|1> [maxError]");
     PrintAndLog("     [set clock as integer] optional, if not set, autodetect.");
     PrintAndLog("     <invert>, 1 for invert output");
@@ -2261,6 +2284,7 @@ static command_t CommandTable[] =
   {"help",          CmdHelp,            1, "This help"},
   {"amp",           CmdAmp,             1, "Amplify peaks"},
   {"askdemod",      Cmdaskdemod,        1, "<0 or 1> -- Attempt to demodulate simple ASK tags"},
+  {"askedgedetect", CmdAskEdgeDetect,   1, "[threshold] Adjust Graph for manual ask demod using length of sample differences to detect the edge of a wave - default = 25"},
   {"askem410xdemod",CmdAskEM410xDemod,  1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"},
        {"askmandemod",   Cmdaskmandemod,     1, "[clock] [invert<0|1>] [maxErr] -- Attempt to demodulate ASK/Manchester tags and output binary (args optional)"},
        {"askrawdemod",   Cmdaskrawdemod,     1, "[clock] [invert<0|1>] -- Attempt to demodulate ASK tags and output bin (args optional)"},
index 009974371b3ed892dbaf2e96c176793b8d69faee..1bf730b75f6ccd0ae1b76585937734784c890c09 100644 (file)
@@ -94,7 +94,7 @@ int GetClock(const char *str, int peak, int verbose)
                        PrintAndLog("Failed to copy from graphbuffer");
                        return -1;
                }
-               clock = DetectASKClock(grph,size,0,20);
+               DetectASKClock(grph,size,&clock,20);
                // Only print this message if we're not looping something
                if (!verbose){
                        PrintAndLog("Auto-detected clock rate: %d", clock);
index 88a250d87efd105fa85f70ef919c2fd89585a75d..448195f2ad8787053392cad66cc46bd06bfb298c 100644 (file)
@@ -120,18 +120,19 @@ uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx)
 }
 
 //by marshmellow
-//takes 2 arguments - clock and invert both as integers
+//takes 3 arguments - clock, invert, maxErr as integers
 //attempts to demodulate ask while decoding manchester
 //prints binary found and saves in graphbuffer for further commands
-int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
+int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr)
 {
        int i;
-       int clk2=*clk;
-       *clk=DetectASKClock(BinStream, *size, *clk); //clock default
-
+       //int clk2=*clk;
+       int start = DetectASKClock(BinStream, *size, clk, 20); //clock default
+       if (*clk==0) return -3;
+       if (start < 0) return -3;
        // if autodetected too low then adjust  //MAY NEED ADJUSTMENT
-       if (clk2==0 && *clk<8) *clk =64;
-       if (clk2==0 && *clk<32) *clk=32;
+       //if (clk2==0 && *clk<8) *clk =64;
+       //if (clk2==0 && *clk<32) *clk=32;
        if (*invert != 0 && *invert != 1) *invert=0;
        uint32_t initLoopMax = 200;
        if (initLoopMax > *size) initLoopMax=*size;
@@ -145,14 +146,14 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
        int lastBit = 0;  //set first clock check
        uint32_t bitnum = 0;     //output counter
        int tol = 0;  //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
-       if (*clk<=32)tol=1;    //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
+       if (*clk<=32) tol=1;    //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
        int iii = 0;
        uint32_t gLen = *size;
        if (gLen > 3000) gLen=3000;
        uint8_t errCnt =0;
+       uint16_t MaxBits = 500;
        uint32_t bestStart = *size;
-       uint32_t bestErrCnt = (*size/1000);
-       uint32_t maxErr = (*size/1000);
+       int bestErrCnt = maxErr+1;
        // PrintAndLog("DEBUG - lastbit - %d",lastBit);
        // loop to find first wave that works
        for (iii=0; iii < gLen; ++iii){
@@ -179,10 +180,10 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
                                                if (errCnt>(maxErr)) break;  //allow 1 error for every 1000 samples else start over
                                        }
                                }
-                               if ((i-iii) >(400 * *clk)) break; //got plenty of bits
+                               if ((i-iii) >(MaxBits * *clk)) break; //got plenty of bits
                        }
                        //we got more than 64 good bits and not all errors
-                       if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt<maxErr)) {
+                       if ((((i-iii)/ *clk) > (64)) && (errCnt<=maxErr)) {
                                //possible good read
                                if (errCnt==0){
                                        bestStart=iii;
@@ -196,7 +197,7 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
                        }
                }
        }
-       if (bestErrCnt<maxErr){
+       if (bestErrCnt<=maxErr){
                //best run is good enough set to best run and set overwrite BinStream
                iii=bestStart;
                lastBit = bestStart - *clk;
@@ -226,7 +227,7 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
                                        lastBit+=*clk;//skip over error
                                }
                        }
-                       if (bitnum >=400) break;
+                       if (bitnum >=MaxBits) break;
                }
                *size=bitnum;
        } else{
@@ -258,12 +259,14 @@ int ManchesterEncode(uint8_t *BitStream, size_t size)
 //run through 2 times and take least errCnt
 int manrawdecode(uint8_t * BitStream, size_t *size)
 {
-       int bitnum=0;
-       int errCnt =0;
-       int i=1;
-       int bestErr = 1000;
-       int bestRun = 0;
-       int ii=1;
+       uint16_t bitnum=0;
+       uint16_t MaxBits = 500;
+       uint16_t errCnt = 0;
+       size_t i=1;
+       uint16_t bestErr = 1000;
+       uint16_t bestRun = 0;
+       size_t ii=1;
+       if (size == 0) return -1;
        for (ii=1;ii<3;++ii){
                i=1;
                for (i=i+ii;i<*size-2;i+=2){
@@ -272,7 +275,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
                        } else {
                                errCnt++;
                        }
-                       if(bitnum>300) break;
+                       if(bitnum>MaxBits) break;
                }
                if (bestErr>errCnt){
                        bestErr=errCnt;
@@ -284,7 +287,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
        if (errCnt<20){
                ii=bestRun;
                i=1;
-               for (i=i+ii;i < *size-2;i+=2){
+               for (i=i+ii; i < *size-2; i+=2){
                        if(BitStream[i] == 1 && (BitStream[i+1] == 0)){
                                BitStream[bitnum++]=0;
                        } else if((BitStream[i] == 0) && BitStream[i+1] == 1){
@@ -293,7 +296,7 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
                                BitStream[bitnum++]=77;
                                //errCnt++;
                        }
-                       if(bitnum>300) break;
+                       if(bitnum>MaxBits) break;
                }
                *size=bitnum;
        }
@@ -304,10 +307,12 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
 //take 01 or 10 = 0 and 11 or 00 = 1
 int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
 {
-       uint8_t bitnum=0;
+       uint16_t bitnum=0;
        uint32_t errCnt =0;
        uint32_t i;
+       uint16_t MaxBits=500;
        i=offset;
+       if (size == 0) return -1;
        for (;i<*size-2; i+=2){
                if((BitStream[i]==1 && BitStream[i+1]==0) || (BitStream[i]==0 && BitStream[i+1]==1)){
                        BitStream[bitnum++]=1^invert;
@@ -317,56 +322,76 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
                        BitStream[bitnum++]=77;
                        errCnt++;
                }
-               if(bitnum>250) break;
+               if(bitnum>MaxBits) break;
        }
        *size=bitnum;
        return errCnt;
 }
 
 //by marshmellow
-//takes 2 arguments - clock and invert both as integers
+void askAmp(uint8_t *BitStream, size_t size)
+{
+  int shift = 127;
+  int shiftedVal=0;
+  for(int i = 1; i<size; i++){
+    if (BitStream[i]-BitStream[i-1]>=30) //large jump up
+      shift=127;
+    else if(BitStream[i]-BitStream[i-1]<=-20) //large jump down
+      shift=-127;
+
+    shiftedVal=BitStream[i]+shift;
+
+    if (shiftedVal>255) 
+      shiftedVal=255;
+    else if (shiftedVal<0) 
+      shiftedVal=0;
+    BitStream[i-1] = shiftedVal;
+  }
+  return;
+}
+
+//by marshmellow
+//takes 3 arguments - clock, invert and maxErr as integers
 //attempts to demodulate ask only
 //prints binary found and saves in graphbuffer for further commands
-int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
+int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp)
 {
        uint32_t i;
-       // int invert=0;  //invert default
-       int clk2 = *clk;
-       *clk=DetectASKClock(BinStream, *size, *clk); //clock default
-       //uint8_t BitStream[502] = {0};
-
-       //HACK: if clock not detected correctly - default
-       if (clk2==0 && *clk<8) *clk =64;
-       if (clk2==0 && *clk<32 && clk2==0) *clk=32;
+       if (*size==0) return -1;
+       int start = DetectASKClock(BinStream, *size, clk, 20); //clock default
+       if (*clk==0) return -1;
+       if (start<0) return -1;
        if (*invert != 0 && *invert != 1) *invert =0;
        uint32_t initLoopMax = 200;
        if (initLoopMax > *size) initLoopMax=*size;
        // Detect high and lows
        //25% fuzz in case highs and lows aren't clipped [marshmellow]
        int high, low, ans;
+       if (amp==1) askAmp(BinStream, *size);
        ans = getHiLo(BinStream, initLoopMax, &high, &low, 75, 75);
-       if (ans<1) return -2; //just noise
+       if (ans<1) return -1; //just noise
 
        //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
        int lastBit = 0;  //set first clock check
        uint32_t bitnum = 0;     //output counter
        uint8_t tol = 0;  //clock tolerance adjust - waves will be accepted as within the clock
                          //  if they fall + or - this value + clock from last valid wave
-       if (*clk == 32) tol=1;    //clock tolerance may not be needed anymore currently set to
+       if (*clk == 32) tol=0;    //clock tolerance may not be needed anymore currently set to
                                  //  + or - 1 but could be increased for poor waves or removed entirely
        uint32_t iii = 0;
        uint32_t gLen = *size;
        if (gLen > 500) gLen=500;
        uint8_t errCnt =0;
        uint32_t bestStart = *size;
-       uint32_t bestErrCnt = (*size/1000);
-       uint32_t maxErr = bestErrCnt;
+       uint32_t bestErrCnt = maxErr; //(*size/1000);
        uint8_t midBit=0;
+       uint16_t MaxBits=1000;
        //PrintAndLog("DEBUG - lastbit - %d",lastBit);
        //loop to find first wave that works
-       for (iii=0; iii < gLen; ++iii){
+       for (iii=start; iii < gLen; ++iii){
                if ((BinStream[iii]>=high) || (BinStream[iii]<=low)){
                        lastBit=iii-*clk;
+                       errCnt=0;
                        //loop through to see if this start location works
                        for (i = iii; i < *size; ++i) {
                                if ((BinStream[i] >= high) && ((i-lastBit)>(*clk-tol))){
@@ -395,16 +420,16 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
 
                                                errCnt++;
                                                lastBit+=*clk;//skip over until hit too many errors
-                                               if (errCnt > ((*size/1000))){  //allow 1 error for every 1000 samples else start over
-                                                       errCnt=0;
+                                               if (errCnt > maxErr){  
+                                                       //errCnt=0;
                                                        break;
                                                }
                                        }
                                }
-                               if ((i-iii)>(500 * *clk)) break; //got enough bits
+                               if ((i-iii)>(MaxBits * *clk)) break; //got enough bits
                        }
                        //we got more than 64 good bits and not all errors
-                       if ((((i-iii)/ *clk) > (64+errCnt)) && (errCnt<(*size/1000))) {
+                       if ((((i-iii)/ *clk) > (64)) && (errCnt<=maxErr)) {
                                //possible good read
                                if (errCnt==0){
                                        bestStart=iii;
@@ -418,9 +443,9 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
                        }
                }
        }
-       if (bestErrCnt<maxErr){
+       if (bestErrCnt<=maxErr){
                //best run is good enough - set to best run and overwrite BinStream
-               iii=bestStart;
+               iii = bestStart;
                lastBit = bestStart - *clk;
                bitnum=0;
                for (i = iii; i < *size; ++i) {
@@ -432,7 +457,7 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
                        } else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){
                                //low found and we are expecting a bar
                                lastBit+=*clk;
-                               BinStream[bitnum] = 1-*invert;
+                               BinStream[bitnum] = 1 - *invert;
                                bitnum++;
                                midBit=0;
                        } else if ((BinStream[i]<=low) && (midBit==0) && ((i-lastBit)>((*clk/2)-tol))){
@@ -462,11 +487,10 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert)
                                                BinStream[bitnum]=77;
                                                bitnum++;
                                        }
-
                                        lastBit+=*clk;//skip over error
                                }
                        }
-                       if (bitnum >=400) break;
+                       if (bitnum >= MaxBits) break;
                }
                *size=bitnum;
        } else{
@@ -744,32 +768,71 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size)
        return (int)startIdx;
 }
 
+
+uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low)
+{
+       uint8_t allPeaks=1;
+       uint16_t cntPeaks=0;
+       for (size_t i=20; i<255; i++){
+               if (dest[i]>low && dest[i]<high) 
+                       allPeaks=0;
+               else
+                       cntPeaks++;
+       }
+       if (allPeaks==0){
+               if (cntPeaks>190) return 1;
+       }
+       return allPeaks;
+}
+
 // by marshmellow
 // not perfect especially with lower clocks or VERY good antennas (heavy wave clipping)
 // maybe somehow adjust peak trimming value based on samples to fix?
-int DetectASKClock(uint8_t dest[], size_t size, int clock)
+// return start index of best starting position for that clock and return clock (by reference)
+int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
 {
   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 == 0) return -1;
   if (size<loopCnt) loopCnt = size;
-
   //if we already have a valid clock quit
   
   for (;i<8;++i)
-    if (clk[i] == clock) return clock;
+    if (clk[i] == *clock) return 0;
 
   //get high and low peak
   int peak, low;
   getHiLo(dest, loopCnt, &peak, &low, 75, 75);
   
+  //test for large clean peaks
+  if (DetectCleanAskWave(dest, size, peak, low)==1){
+         uint16_t fcTest=0;
+         uint8_t mostFC=0;
+         fcTest=countFC(dest, size, &mostFC);
+         uint8_t fc1 = fcTest >> 8;
+         uint8_t fc2 = fcTest & 0xFF;
+
+         for (i=0; i<8; i++){
+               if (clk[i] == fc1) {
+                       *clock=fc1;
+                       return 0;
+               }
+               if (clk[i] == fc2) {
+                       *clock=fc2;
+                       return 0;
+               }
+         }
+  }
+  
   int ii;
   int clkCnt;
   int tol = 0;
   int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
+  int bestStart[]={0,0,0,0,0,0,0,0,0};
   int errCnt=0;
   //test each valid clock from smallest to greatest to see which lines up
-  for(clkCnt=0; clkCnt < 8; ++clkCnt){
+  for(clkCnt=0; clkCnt < 8; clkCnt++){
     if (clk[clkCnt] == 32){
       tol=1;
     }else{
@@ -777,7 +840,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock)
     }
     bestErr[clkCnt]=1000;
     //try lining up the peaks by moving starting point (try first 256)
-    for (ii=0; ii < loopCnt; ++ii){
+    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
@@ -792,9 +855,15 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock)
         //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(errCnt==0 && clkCnt<6) {
+               *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;
+        if(errCnt<bestErr[clkCnt]){
+                                       bestErr[clkCnt]=errCnt;
+                                       bestStart[clkCnt]=ii;
+        }
       }
     }
   }
@@ -809,120 +878,175 @@ int DetectASKClock(uint8_t dest[], size_t size, int clock)
       }
     }
   }
-  return clk[best];
+  if (bestErr[best]>maxErr) return -1;
+  *clock=clk[best];
+  return bestStart[best];
 }
 
 //by marshmellow
-//detect psk clock by reading #peaks vs no peaks(or errors)
-int DetectpskNRZClock(uint8_t dest[], size_t size, int clock)
+//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)
 {
-       int i=0;
-       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 < 7; ++i)
-               if (clk[i] == clock) return 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;
 
-       //get high and low peak
-       int peak, low;
-       getHiLo(dest, loopCnt, &peak, &low, 75, 75);
+  //if we already have a valid clock quit
+  size_t i=1;
+  for (; i < 8; ++i)
+    if (clk[i] == clock) return clock;
 
-       //PrintAndLog("DEBUG: peak: %d, low: %d",peak,low);
-       int ii;
-       uint8_t clkCnt;
-       uint8_t tol = 0;
-       int peakcnt=0;
-       int errCnt=0;
-       int bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000};
-       int peaksdet[]={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 < 7; ++clkCnt){
-               if (clk[clkCnt] <= 32){
-                       tol=1;
-               }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-ii-tol)/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];
+  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};
+  countFC(dest, size, &fc);
+  //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];
 }
 
-// by marshmellow (attempt to get rid of high immediately after a low)
-void pskCleanWave(uint8_t *BitStream, size_t size)
+//by marshmellow
+//detect nrz clock by reading #peaks vs no peaks(or errors)
+int DetectNRZClock(uint8_t dest[], size_t size, int clock)
 {
-       int i;
-       int gap = 4;
-       int newLow=0;
-       int newHigh=0;
-       int high, low;
-       getHiLo(BitStream, size, &high, &low, 80, 90);
-       for (i=0; i < size; ++i){
-               if (newLow == 1){
-                       if (BitStream[i]>low){
-                               BitStream[i]=low+8;
-                               gap--;
-                       }
-                       if (gap == 0){
-                               newLow=0;
-                               gap=4;
-                       }
-               }else if (newHigh == 1){
-                       if (BitStream[i]<high){
-                               BitStream[i]=high-8;
-                               gap--;
-                       }
-                       if (gap == 0){
-                               newHigh=0;
-                               gap=4;
-                       }
-               }
-               if (BitStream[i] <= low) newLow=1;
-               if (BitStream[i] >= high) newHigh=1;
-       }
-       return;
+  int i=0;
+  int clk[]={8,16,32,40,50,64,100,128,256};
+  int 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
+  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);
+
+  //PrintAndLog("DEBUG: peak: %d, low: %d",peak,low);
+  int ii;
+  uint8_t clkCnt;
+  uint8_t tol = 0;
+  int peakcnt=0;
+  int peaksdet[]={0,0,0,0,0,0,0,0};
+  int maxPeak=0;
+  //test for large clipped waves
+  for (i=0; i<loopCnt; i++){
+       if (dest[i] >= peak || dest[i] <= low){
+               peakcnt++;
+       } else {
+               if (peakcnt>0 && maxPeak < peakcnt){
+                               maxPeak = peakcnt;
+               }
+               peakcnt=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 largest peak
+       if (clk[clkCnt]<maxPeak) continue;
+
+    //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)){
+        peakcnt=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){
+            peakcnt++;
+          }
+        }
+        if(peakcnt>peaksdet[clkCnt]) {
+          peaksdet[clkCnt]=peakcnt;
+        }
+      }
+    }
+  }
+  int iii=7;
+  int best=0;
+  for (iii=7; iii > 0; iii--){
+   if (peaksdet[iii] > peaksdet[best]){
+       best = iii;
+    }
+    //PrintAndLog("DEBUG: Clk: %d, peaks: %d, errs: %d, bestClk: %d",clk[iii],peaksdet[iii],bestErr[iii],clk[best]);
+  }
+  return clk[best];
 }
 
 // by marshmellow
@@ -1007,137 +1131,166 @@ int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert)
        return 1;
 }
 
-// by marshmellow - demodulate PSK1 wave or NRZ wave (both similar enough)
+// by marshmellow - demodulate NRZ wave (both similar enough)
 // peaks invert bit (high=1 low=0) each clock cycle = 1 bit determined by last peak
-int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert)
+// there probably is a much simpler way to do this.... 
+int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr)
 {
-       if (justNoise(dest, *size)) return -1;
-       pskCleanWave(dest,*size);
-       int clk2 = DetectpskNRZClock(dest, *size, *clk);
-       *clk=clk2;
-       uint32_t i;
-       int high, low, ans;
-       ans = getHiLo(dest, 1260, &high, &low, 75, 80); //25% fuzz on high 20% fuzz on low
-       if (ans<1) return -2; //just noise
-       uint32_t gLen = *size;
-       //PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
-       int lastBit = 0;  //set first clock check
-       uint32_t bitnum = 0;     //output counter
-       uint8_t tol = 1;  //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
-       if (*clk==32) tol = 2;    //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
-       uint32_t iii = 0;
-       uint8_t errCnt =0;
-       uint32_t bestStart = *size;
-       uint32_t maxErr = (*size/1000);
-       uint32_t bestErrCnt = maxErr;
-       uint8_t curBit=0;
-       uint8_t bitHigh=0;
-       uint8_t ignorewin=*clk/8;
-       //PrintAndLog("DEBUG - lastbit - %d",lastBit);
-       //loop to find first wave that works - align to clock
-       for (iii=0; iii < gLen; ++iii){
-               if ((dest[iii]>=high) || (dest[iii]<=low)){
-                       lastBit=iii-*clk;
-                       //loop through to see if this start location works
-                       for (i = iii; i < *size; ++i) {
-                               //if we found a high bar and we are at a clock bit
-                               if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
-                                       bitHigh=1;
-                                       lastBit+=*clk;
-                                       ignorewin=*clk/8;
-                                       bitnum++;
-                               //else if low bar found and we are at a clock point
-                               }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
-                                       bitHigh=1;
-                                       lastBit+=*clk;
-                                       ignorewin=*clk/8;
-                                       bitnum++;
-                               //else if no bars found
-                               }else if(dest[i] < high && dest[i] > low) {
-                                       if (ignorewin==0){
-                                               bitHigh=0;
-                                       }else ignorewin--;
-                                                                               //if we are past a clock point
-                                       if (i >= lastBit+*clk+tol){ //clock val
-                                               lastBit+=*clk;
-                                               bitnum++;
-                                       }
-                               //else if bar found but we are not at a clock bit and we did not just have a clock bit
-                               }else if ((dest[i]>=high || dest[i]<=low) && (i<lastBit+*clk-tol || i>lastBit+*clk+tol) && (bitHigh==0)){
-                                       //error bar found no clock...
-                                       errCnt++;
-                               }
-                               if (bitnum>=1000) break;
-                       }
-                       //we got more than 64 good bits and not all errors
-                       if ((bitnum > (64+errCnt)) && (errCnt < (maxErr))) {
-                               //possible good read
-                               if (errCnt == 0){
-                                       bestStart = iii;
-                                       bestErrCnt = errCnt;
-                                       break;  //great read - finish
-                               }
-                               if (errCnt < bestErrCnt){  //set this as new best run
-                                       bestErrCnt = errCnt;
-                                       bestStart = iii;
-                               }
-                       }
-               }
-       }
-       if (bestErrCnt < maxErr){
-               //best run is good enough set to best run and set overwrite BinStream
-               iii=bestStart;
-               lastBit=bestStart-*clk;
-               bitnum=0;
-               for (i = iii; i < *size; ++i) {
-                       //if we found a high bar and we are at a clock bit
-                       if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
-                               bitHigh=1;
-                               lastBit+=*clk;
-                               curBit=1-*invert;
-                               dest[bitnum]=curBit;
-                               ignorewin=*clk/8;
-                               bitnum++;
-                       //else if low bar found and we are at a clock point
-                       }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
-                               bitHigh=1;
-                               lastBit+=*clk;
-                               curBit=*invert;
-                               dest[bitnum]=curBit;
-                               ignorewin=*clk/8;
-                               bitnum++;
-                       //else if no bars found
-                       }else if(dest[i]<high && dest[i]>low) {
-                               if (ignorewin==0){
-                                       bitHigh=0;
-                               }else ignorewin--;
-                               //if we are past a clock point
-                               if (i>=lastBit+*clk+tol){ //clock val
-                                       lastBit+=*clk;
-                                       dest[bitnum]=curBit;
-                                       bitnum++;
-                               }
-                       //else if bar found but we are not at a clock bit and we did not just have a clock bit
-                       }else if ((dest[i]>=high || dest[i]<=low) && ((i<lastBit+*clk-tol) || (i>lastBit+*clk+tol)) && (bitHigh==0)){
-                               //error bar found no clock...
-                               bitHigh=1;
-                               dest[bitnum]=77;
-                               bitnum++;
-                               errCnt++;
-                       }
-                       if (bitnum >=1000) break;
-               }
-               *size=bitnum;
-       } else{
-               *size=bitnum;
-               *clk=bestStart;
-               return -1;
-       }
+  if (justNoise(dest, *size)) return -1;
+  *clk = DetectNRZClock(dest, *size, *clk);
+  if (*clk==0) return -2;
+  uint32_t i;
+  int high, low, ans;
+  ans = getHiLo(dest, 1260, &high, &low, 75, 75); //25% fuzz on high 25% fuzz on low
+  if (ans<1) return -2; //just noise
+  uint32_t gLen = 256;
+  if (gLen>*size) gLen = *size;
+  int lastBit = 0;  //set first clock check
+  uint32_t bitnum = 0;     //output counter
+  uint8_t tol = 1;  //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
+  uint32_t iii = 0;
+  uint16_t errCnt =0;
+  uint16_t MaxBits = 1000;
+  uint32_t bestErrCnt = maxErr+1;
+  uint32_t bestPeakCnt = 0;
+  uint32_t bestPeakStart=0;
+  uint8_t curBit=0;
+  uint8_t bitHigh=0;
+  uint8_t errBitHigh=0;
+  uint16_t peakCnt=0;
+  uint8_t ignoreWindow=4;
+  uint8_t ignoreCnt=ignoreWindow; //in case of noice near peak
+  //loop to find first wave that works - align to clock
+  for (iii=0; iii < gLen; ++iii){
+    if ((dest[iii]>=high) || (dest[iii]<=low)){
+      lastBit=iii-*clk;
+      peakCnt=0;
+      errCnt=0;
+      bitnum=0;
+      //loop through to see if this start location works
+      for (i = iii; i < *size; ++i) {
+        //if we found a high bar and we are at a clock bit
+        if ((dest[i]>=high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
+          bitHigh=1;
+          lastBit+=*clk;
+          bitnum++;
+          peakCnt++;
+          errBitHigh=0;
+          ignoreCnt=ignoreWindow;
+        //else if low bar found and we are at a clock point
+        }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
+          bitHigh=1;
+          lastBit+=*clk;
+          bitnum++;
+          peakCnt++;
+          errBitHigh=0;
+          ignoreCnt=ignoreWindow;
+        //else if no bars found
+        }else if(dest[i] < high && dest[i] > low) {
+          if (ignoreCnt==0){
+            bitHigh=0;
+            if (errBitHigh==1){
+              errCnt++;
+            }
+            errBitHigh=0;
+          } else {
+            ignoreCnt--;
+          }
+          //if we are past a clock point
+          if (i >= lastBit+*clk+tol){ //clock val
+            lastBit+=*clk;
+            bitnum++;
+          }
+        //else if bar found but we are not at a clock bit and we did not just have a clock bit
+        }else if ((dest[i]>=high || dest[i]<=low) && (i<lastBit+*clk-tol || i>lastBit+*clk+tol) && (bitHigh==0)){
+          //error bar found no clock...
+          errBitHigh=1;
+        }
+        if (bitnum>=MaxBits) break;
+      }
+      //we got more than 64 good bits and not all errors
+      if (bitnum > (64) && (errCnt <= (maxErr))) {
+        //possible good read
+        if (errCnt == 0){
+          //bestStart = iii;
+          bestErrCnt = errCnt;
+          bestPeakCnt = peakCnt;
+          bestPeakStart = iii;
+          break;  //great read - finish
+        }
+        if (errCnt < bestErrCnt){  //set this as new best run
+          bestErrCnt = errCnt;
+          //bestStart = iii;
+        }
+        if (peakCnt > bestPeakCnt){
+          bestPeakCnt=peakCnt;
+          bestPeakStart=iii;
+        } 
+      }
+    }
+  }
+  //PrintAndLog("DEBUG: bestErrCnt: %d, maxErr: %d, bestStart: %d, bestPeakCnt: %d, bestPeakStart: %d",bestErrCnt,maxErr,bestStart,bestPeakCnt,bestPeakStart);
+  if (bestErrCnt <= maxErr){
+    //best run is good enough set to best run and set overwrite BinStream
+    iii=bestPeakStart;
+    lastBit=bestPeakStart-*clk;
+    bitnum=0;
+    for (i = iii; i < *size; ++i) {
+      //if we found a high bar and we are at a clock bit
+      if ((dest[i] >= high ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
+        bitHigh=1;
+        lastBit+=*clk;
+        curBit=1-*invert;
+        dest[bitnum]=curBit;
+        bitnum++;
+        errBitHigh=0;
+        ignoreCnt=ignoreWindow;
+      //else if low bar found and we are at a clock point
+      }else if ((dest[i]<=low ) && (i>=lastBit+*clk-tol && i<=lastBit+*clk+tol)){
+        bitHigh=1;
+        lastBit+=*clk;
+        curBit=*invert;
+        dest[bitnum]=curBit;
+        bitnum++;
+        errBitHigh=0;
+        ignoreCnt=ignoreWindow;
+      //else if no bars found
+      }else if(dest[i]<high && dest[i]>low) {
+        if (ignoreCnt==0){
+          bitHigh=0;
+          //if peak is done was it an error peak?
+          if (errBitHigh==1){
+            dest[bitnum]=77;
+            bitnum++;
+            errCnt++;
+          }
+          errBitHigh=0;
+        } else {
+          ignoreCnt--;
+        }
+        //if we are past a clock point
+        if (i>=lastBit+*clk+tol){ //clock val
+          lastBit+=*clk;
+          dest[bitnum]=curBit;
+          bitnum++;
+        }
+      //else if bar found but we are not at a clock bit and we did not just have a clock bit
+      }else if ((dest[i]>=high || dest[i]<=low) && ((i<lastBit+*clk-tol) || (i>lastBit+*clk+tol)) && (bitHigh==0)){
+        //error bar found no clock...
+        errBitHigh=1;
+      }
+      if (bitnum >= MaxBits) break;
+    }
+    *size=bitnum;
+  } else{
+    *size=bitnum;
+    return -1;
+  }
 
-       if (bitnum>16){
-               *size=bitnum;
-       } else return -1;
-       return errCnt;
+  if (bitnum>16){
+    *size=bitnum;
+  } else return -1;
+  return errCnt;
 }
 
 //by marshmellow
@@ -1153,6 +1306,7 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc
   uint16_t rfCounter = 0;
   uint8_t firstBitFnd = 0;
   size_t i;
+       if (size == 0) return 0;
 
   uint8_t fcTol = (uint8_t)(0.5+(float)(fcHigh-fcLow)/2);
   rfLensFnd=0;
@@ -1249,7 +1403,8 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fc
 //by marshmellow
 //countFC is to detect the field clock lengths.
 //counts and returns the 2 most common wave lengths
-uint16_t countFC(uint8_t *BitStream, size_t size)
+//mainly used for FSK field clock detection
+uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t *mostFC)
 {
   uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0};
   uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0};
@@ -1257,7 +1412,8 @@ uint16_t countFC(uint8_t *BitStream, size_t size)
   uint8_t lastFCcnt=0;
   uint32_t fcCounter = 0;
   size_t i;
-  
+  if (size == 0) return 0;
+
   // prime i to first up transition
   for (i = 1; i < size-1; i++)
     if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1])
@@ -1320,7 +1476,8 @@ uint16_t countFC(uint8_t *BitStream, size_t size)
     fcH=fcLens[best2];
     fcL=fcLens[best1];
   }
+
+  *mostFC=fcLens[best1]; 
   // TODO: take top 3 answers and compare to known Field clocks to get top 2
 
   uint16_t fcs = (((uint16_t)fcH)<<8) | fcL;
@@ -1328,3 +1485,152 @@ uint16_t countFC(uint8_t *BitStream, size_t size)
   
   return fcs;
 }
+
+//by marshmellow
+//countPSK_FC is to detect the psk carrier clock length.
+//counts and returns the 1 most common wave length
+uint8_t countPSK_FC(uint8_t *BitStream, size_t size)
+{
+  uint8_t fcLens[] = {0,0,0,0,0,0,0,0,0,0};
+  uint16_t fcCnts[] = {0,0,0,0,0,0,0,0,0,0};
+  uint8_t fcLensFnd = 0;
+  uint32_t fcCounter = 0;
+  size_t i;
+       if (size == 0) return 0;
+  
+  // prime i to first up transition
+  for (i = 1; i < size-1; i++)
+    if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1])
+      break;
+
+  for (; i < size-1; i++){
+    if (BitStream[i] > BitStream[i-1] && BitStream[i] >= BitStream[i+1]){
+      // new up transition
+      fcCounter++;
+      
+      // save last field clock count  (fc/xx)
+      // find which fcLens to save it to:
+      for (int ii=0; ii<10; ii++){
+        if (fcLens[ii]==fcCounter){
+          fcCnts[ii]++;
+          fcCounter=0;
+          break;
+        }
+      }
+      if (fcCounter>0 && fcLensFnd<10){
+        //add new fc length 
+        fcCnts[fcLensFnd]++;
+        fcLens[fcLensFnd++]=fcCounter;
+      }
+      fcCounter=0;
+    } else {
+      // count sample
+      fcCounter++;
+    }
+  }
+  
+  uint8_t best1=9;
+  uint16_t maxCnt1=0;
+  // go through fclens and find which ones are bigest  
+  for (i=0; i<10; i++){
+    //PrintAndLog("DEBUG: FC %d, Cnt %d",fcLens[i],fcCnts[i]);    
+    // get the best FC value
+    if (fcCnts[i]>maxCnt1) {
+      maxCnt1=fcCnts[i];
+      best1=i;
+    }
+  }
+  return fcLens[best1]; 
+}
+
+//by marshmellow - demodulate PSK1 wave 
+//uses wave lengths (# Samples) 
+int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert)
+{
+  uint16_t loopCnt = 4096;  //don't need to loop through entire array...
+       if (size == 0) return -1;
+  if (*size<loopCnt) loopCnt = *size;
+
+  uint8_t curPhase = *invert;
+  size_t i, waveStart=0, waveEnd=0, firstFullWave=0, lastClkBit=0;
+  uint8_t fc=0, fullWaveLen=0, tol=1;
+  uint16_t errCnt=0, waveLenCnt=0;
+  fc = countPSK_FC(dest, *size);
+  if (fc!=2 && fc!=4 && fc!=8) return -1;
+  //PrintAndLog("DEBUG: FC: %d",fc);
+  *clock = DetectPSKClock(dest, *size, *clock);
+  if (*clock==0) return -1;
+  int avgWaveVal=0, lastAvgWaveVal=0;
+  //find first full wave
+  for (i=0; i<loopCnt; i++){
+    if (dest[i]+fc < dest[i+1] && dest[i+1] >= dest[i+2]){
+      if (waveStart == 0) {
+        waveStart = i+1;
+        avgWaveVal=dest[i+1];
+        //PrintAndLog("DEBUG: waveStart: %d",waveStart);
+      } else {
+        waveEnd = i+1;
+        //PrintAndLog("DEBUG: waveEnd: %d",waveEnd);
+        waveLenCnt = waveEnd-waveStart;
+        lastAvgWaveVal = avgWaveVal/waveLenCnt;
+        if (waveLenCnt > fc){
+          firstFullWave = waveStart;
+          fullWaveLen=waveLenCnt;
+          //if average wave value is > graph 0 then it is an up wave or a 1
+          if (lastAvgWaveVal > 128) curPhase^=1;
+          break;
+        } 
+        waveStart=0;
+        avgWaveVal=0;
+      }
+    }
+    avgWaveVal+=dest[i+1];
+  }
+  //PrintAndLog("DEBUG: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen);  
+  lastClkBit = firstFullWave; //set start of wave as clock align
+  waveStart = 0;
+  errCnt=0;
+  size_t numBits=0;
+  //PrintAndLog("DEBUG: clk: %d, lastClkBit: %d", *clock, lastClkBit);
+
+  for (i = firstFullWave+fullWaveLen-1; i < *size-3; i++){
+    //top edge of wave = start of new wave 
+    if (dest[i]+fc < dest[i+1] && dest[i+1] >= dest[i+2]){
+      if (waveStart == 0) {
+        waveStart = i+1;
+        waveLenCnt=0;
+        avgWaveVal = dest[i+1];
+      } else { //waveEnd
+        waveEnd = i+1;
+        waveLenCnt = waveEnd-waveStart;
+        lastAvgWaveVal = avgWaveVal/waveLenCnt;
+        if (waveLenCnt > fc){ 
+          //PrintAndLog("DEBUG: avgWaveVal: %d, waveSum: %d",lastAvgWaveVal,avgWaveVal);
+          //if this wave is a phase shift
+          //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+*clock-tol,i+1,fc);
+          if (i+1 >= lastClkBit + *clock - tol){ //should be a clock bit
+            curPhase^=1;
+            dest[numBits] = curPhase;
+            numBits++;
+            lastClkBit += *clock;
+          } else if (i<lastClkBit+10){
+            //noise after a phase shift - ignore
+          } else { //phase shift before supposed to based on clock
+            errCnt++;
+            dest[numBits] = 77;
+            numBits++;
+          }
+        } else if (i+1 > lastClkBit + *clock + tol + fc){
+          lastClkBit += *clock; //no phase shift but clock bit
+          dest[numBits] = curPhase;
+          numBits++;
+        }
+        avgWaveVal=0;
+        waveStart=i+1;
+      }
+    }
+    avgWaveVal+=dest[i+1];
+  }
+  *size = numBits;
+  return errCnt;
+}
index dbeab0f7b58621290100544e209436a42fad5d99..2880ff82fb9959efd7d549256119597b534e6386 100644 (file)
 #define LFDEMOD_H__
 #include <stdint.h>
 
-int DetectASKClock(uint8_t dest[], size_t size, int clock);
-int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
+int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr);
+int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr);
 uint64_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx);
 int ManchesterEncode(uint8_t *BitStream, size_t size);
 int manrawdecode(uint8_t *BitStream, size_t *size);
 int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
-int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert);
+int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp);
 int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
 int IOdemodFSK(uint8_t *dest, size_t size);
 int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
 uint32_t bytebits_to_byte(uint8_t* src, size_t numbits);
-int pskNRZrawDemod(uint8_t *dest, size_t *size, int *clk, int *invert);
+int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr);
 void psk1TOpsk2(uint8_t *BitStream, size_t size);
-int DetectpskNRZClock(uint8_t dest[], size_t size, int clock);
+int DetectNRZClock(uint8_t dest[], size_t size, int clock);
 int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
 void pskCleanWave(uint8_t *bitStream, size_t size);
 int PyramiddemodFSK(uint8_t *dest, size_t *size);
 int AWIDdemodFSK(uint8_t *dest, size_t *size);
 size_t removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
-uint16_t countFC(uint8_t *BitStream, size_t size);
+uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t *mostFC);
 uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
 int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
 int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
 uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
 uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
 uint8_t justNoise(uint8_t *BitStream, size_t size);
+uint8_t countPSK_FC(uint8_t *BitStream, size_t size);
+int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
+int DetectPSKClock(uint8_t dest[], size_t size, int clock);
 
 #endif
Impressum, Datenschutz