From fef74fdce43605f1710319b2b6e45969a5c62835 Mon Sep 17 00:00:00 2001
From: marshmellow42 <marshmellowrf@gmail.com>
Date: Wed, 8 Apr 2015 01:07:39 -0400
Subject: [PATCH] lf ask consolidation

backend:
askman and askraw demods merged into askdemod (args adjusted
accordingly)
re-arranged lfdemod.h in alphabetical order and by category

front end:
data detectclock a (ask) now also reports the selected best start
position for demod
data manrawdecode takes an invert arg now
---
 armsrc/lfops.c      |   2 +-
 client/cmddata.c    | 236 ++++++++++++++++++--------------------------
 client/cmddata.h    |   6 +-
 client/cmdlf.c      |   2 +-
 client/cmdlfem4x.c  |   4 +-
 client/cmdlft55xx.c |  86 ++++++++--------
 client/graph.c      |   4 +-
 common/lfdemod.c    | 224 ++++++++++++++++-------------------------
 common/lfdemod.h    |  50 +++++-----
 9 files changed, 264 insertions(+), 350 deletions(-)

diff --git a/armsrc/lfops.c b/armsrc/lfops.c
index e5a40b2e..e45b55fc 100644
--- a/armsrc/lfops.c
+++ b/armsrc/lfops.c
@@ -861,7 +861,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
 		size  = BigBuf_max_traceLen();
 		//askdemod and manchester decode
 		if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format
-		errCnt = askmandemod(dest, &size, &clk, &invert, maxErr);
+		errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1);
 		WDT_HIT();
 
 		if (errCnt<0) continue;
diff --git a/client/cmddata.c b/client/cmddata.c
index d838abd1..a8c809cf 100644
--- a/client/cmddata.c
+++ b/client/cmddata.c
@@ -208,22 +208,34 @@ void printEM410x(uint32_t hi, uint64_t id)
 	return;
 }
 
-
-int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo)
+int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo )
 {
-	int ans = ASKmanDemod(Cmd, FALSE, FALSE);
-	if (!ans) return 0;
-
-	size_t idx=0;
-	if (Em410xDecode(DemodBuffer,(size_t *) &DemodBufferLen, &idx, hi, lo)){
+	size_t idx = 0;
+	size_t BitLen = DemodBufferLen;
+	uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
+	memcpy(BitStream, DemodBuffer, BitLen); 
+	if (Em410xDecode(BitStream, &BitLen, &idx, hi, lo)){
+		//set GraphBuffer for clone or sim command
+		setDemodBuf(BitStream, BitLen, idx);
 		if (g_debugMode){
-			PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, DemodBufferLen);
+			PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
 			printDemodBuff();
 		}
+		if (verbose){
+			PrintAndLog("EM410x pattern found: ");
+			printEM410x(*hi, *lo);
+		}
 		return 1;
 	}
 	return 0;
 }
+
+int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose)
+{
+	if (!ASKDemod(Cmd, FALSE, FALSE, 1)) return 0;
+	return AskEm410xDecode(verbose, hi, lo);
+}
+
 //by marshmellow
 //takes 3 arguments - clock, invert and maxErr as integers
 //attempts to demodulate ask while decoding manchester
@@ -244,28 +256,28 @@ int CmdAskEM410xDemod(const char *Cmd)
 		PrintAndLog("          : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors");
 		return 0;
 	}
-	uint32_t hi = 0;
 	uint64_t lo = 0;
-	if (AskEm410xDemod(Cmd, &hi, &lo)) {
-		PrintAndLog("EM410x pattern found: ");
-		printEM410x(hi, lo);
-		return 1;
-	}
-	return 0;
+	uint32_t hi = 0;
+	return AskEm410xDemod(Cmd, &hi, &lo, true);
 }
 
-int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch)
+//by marshmellow
+//Cmd Args: Clock, invert, maxErr, maxLen as integers and amplify as char == 'a'
+//   (amp may not be needed anymore)
+//verbose will print results and demoding messages
+//emSearch will auto search for EM410x format in bitstream
+//askType switches decode: ask/raw = 0, ask/manchester = 1 
+int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType)
 {
 	int invert=0;
 	int clk=0;
 	int maxErr=100;
-	int maxLen=512*64;
-	//param_getdec(Cmd, 0, &clk);
-	//param_getdec(Cmd, 1, &invert);
-	//maxErr = param_get32ex(Cmd, 2, 0xFFFFFFFF, 10);
-	//if (maxErr == 0xFFFFFFFF) maxErr=100;
+	int maxLen=0;
+	uint8_t askAmp = 0;
+	char amp = param_getchar(Cmd, 0);
 	uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
-	sscanf(Cmd, "%i %i %i %i", &clk, &invert, &maxErr, &maxLen);
+	sscanf(Cmd, "%i %i %i %i %c", &clk, &invert, &maxErr, &maxLen, &amp);
+	if (!maxLen) maxLen = 512*64;
 	if (invert != 0 && invert != 1) {
 		PrintAndLog("Invalid argument: %s", Cmd);
 		return 0;
@@ -274,12 +286,14 @@ int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch)
 		invert=1;
 		clk=0;
 	}
+	if (amp == 'a' || amp == 'A') askAmp=1; 
 	size_t BitLen = getFromGraphBuf(BitStream);
 	if (g_debugMode) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
-	if (!BitLen) return 0;
+	if (BitLen<255) return 0;
 	if (maxLen<BitLen && maxLen != 0) BitLen = maxLen;
-	int errCnt = askmandemod(BitStream, &BitLen, &clk, &invert, maxErr);
-	if (errCnt<0||BitLen<16){  //if fatal error (or -1)
+
+	int errCnt = askdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp, askType);
+	if (errCnt<0 || BitLen<16){  //if fatal error (or -1)
 		if (g_debugMode) PrintAndLog("DEBUG: no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
 		return 0;
 	}
@@ -290,45 +304,37 @@ int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch)
 	if (verbose || g_debugMode) PrintAndLog("\nUsing Clock:%d, Invert:%d, Bits Found:%d",clk,invert,BitLen);
 
 	//output
-	if (errCnt>0){
-		if (verbose || g_debugMode) PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d",errCnt);
-	}
-	if (verbose || g_debugMode) PrintAndLog("ASK/Manchester decoded bitstream:");
-	// Now output the bitstream to the scrollback by line of 16 bits
 	setDemodBuf(BitStream,BitLen,0);
-	if (verbose || g_debugMode) printDemodBuff();
-	uint64_t lo =0;
-	uint32_t hi =0;
-	size_t idx=0;
+	if (verbose || g_debugMode){
+		if (errCnt>0) PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d",errCnt);
+		if (askType) PrintAndLog("ASK/Manchester decoded bitstream:");
+		else PrintAndLog("ASK/Raw decoded bitstream:");
+		// Now output the bitstream to the scrollback by line of 16 bits
+		printDemodBuff();
+		
+	}
+	uint64_t lo = 0;
+	uint32_t hi = 0;
 	if (emSearch){
-		if (Em410xDecode(BitStream, &BitLen, &idx, &hi, &lo)){
-			//set GraphBuffer for clone or sim command
-			setDemodBuf(BitStream, BitLen, idx);
-			if (g_debugMode){
-				PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
-				printDemodBuff();
-			}
-			if (verbose) PrintAndLog("EM410x pattern found: ");
-			if (verbose) printEM410x(hi, lo);
-			return 1;
-		}
+		AskEm410xDecode(true, &hi, &lo);
 	}
 	return 1;
 }
 
 //by marshmellow
-//takes 3 arguments - clock, invert, maxErr as integers
+//takes 5 arguments - clock, invert, maxErr, maxLen as integers and amplify as char == 'a'
 //attempts to demodulate ask while decoding manchester
 //prints binary found and saves in graphbuffer for further commands
 int Cmdaskmandemod(const char *Cmd)
 {
 	char cmdp = param_getchar(Cmd, 0);
-	if (strlen(Cmd) > 20 || cmdp == 'h' || cmdp == 'H') {
-		PrintAndLog("Usage:  data rawdemod am [clock] <0|1> [maxError] [setSmplLen]");
-		PrintAndLog("     [set clock as integer] optional, if not set, autodetect.");
-		PrintAndLog("     <invert>, 1 for invert output");
-		PrintAndLog("     [set maximum allowed errors], default = 100.");
-		PrintAndLog("     [set maximum Samples to read], default = 32768 (512 bits at rf/64).");
+	if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') {
+		PrintAndLog("Usage:  data rawdemod am [clock] <invert> [maxError] [maxLen] [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("     [set maximum Samples to read], default = 32768 (512 bits at rf/64)");
+		PrintAndLog("     <amplify>, 'a' to attempt demod with ask amplification, default = no amp");
 		PrintAndLog("");
 		PrintAndLog("    sample: data rawdemod am        = demod an ask/manchester tag from GraphBuffer");
 		PrintAndLog("          : data rawdemod am 32     = demod an ask/manchester tag from GraphBuffer using a clock of RF/32");
@@ -337,7 +343,7 @@ int Cmdaskmandemod(const char *Cmd)
 		PrintAndLog("          : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
 		return 0;
 	}
-	return ASKmanDemod(Cmd, TRUE, TRUE);
+	return ASKDemod(Cmd, TRUE, TRUE, 1);
 }
 
 //by marshmellow
@@ -348,12 +354,14 @@ int Cmdmandecoderaw(const char *Cmd)
 	int i =0;
 	int errCnt=0;
 	size_t size=0;
+	int invert=0;
 	size_t maxErr = 20;
 	char cmdp = param_getchar(Cmd, 0);
 	if (strlen(Cmd) > 5 || cmdp == 'h' || cmdp == 'H') {
-		PrintAndLog("Usage:  data manrawdecode [maxErr]");
+		PrintAndLog("Usage:  data manrawdecode [invert] [maxErr]");
 		PrintAndLog("     Takes 10 and 01 and converts to 0 and 1 respectively");
 		PrintAndLog("     --must have binary sequence in demodbuffer (run data askrawdemod first)");
+		PrintAndLog("  [invert]  invert output");		
 		PrintAndLog("  [maxErr]  set number of errors allowed (default = 20)");		
 		PrintAndLog("");
 		PrintAndLog("    sample: data manrawdecode   = decode manchester bitstream from the demodbuffer");
@@ -372,9 +380,9 @@ int Cmdmandecoderaw(const char *Cmd)
 		return 0;
 	}
 
-	sscanf(Cmd, "%i", &maxErr);
+	sscanf(Cmd, "%i %i", &invert, &maxErr);
 	size=i;
-	errCnt=manrawdecode(BitStream, &size);
+	errCnt=manrawdecode(BitStream, &size, invert);
 	if (errCnt>=maxErr){
 		PrintAndLog("Too many errors: %d",errCnt);
 		return 0;
@@ -448,59 +456,6 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
 	return 1;
 }
 
-//by marshmellow
-//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 ASKrawDemod(const char *Cmd, bool verbose)
-{
-	int invert=0;
-	int clk=0;
-	int maxErr=100;
-	uint8_t askAmp = 0;
-	char amp = param_getchar(Cmd, 0);
-	uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
-	sscanf(Cmd, "%i %i %i %c", &clk, &invert, &maxErr, &amp);
-	if (invert != 0 && invert != 1) {
-		if (verbose || g_debugMode) 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 = 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)
-		if (verbose || g_debugMode) PrintAndLog("no data found");
-		if (g_debugMode) PrintAndLog("errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert);
-		return 0;
-	}
-	if (errCnt>maxErr) {
-		if (g_debugMode) 
-			PrintAndLog("Too many errors found, errCnt: %d, BitLen: %d, clk: %d, invert: %d", errCnt, BitLen, clk, invert);
-		return 0;
-	}
-	if (verbose || g_debugMode) 
-		PrintAndLog("Using Clock: %d - invert: %d - Bits Found: %d", clk, invert, BitLen);
-	
-	//move BitStream back to DemodBuffer
-	setDemodBuf(BitStream,BitLen,0);
-
-	//output
-	if (errCnt>0 && (verbose || g_debugMode)){
-		PrintAndLog("# Errors during Demoding (shown as 7 in bit stream): %d", errCnt);
-	}
-	if (verbose || g_debugMode){
-		PrintAndLog("ASK demoded bitstream:");
-		// Now output the bitstream to the scrollback by line of 16 bits
-		printDemodBuff();
-	} 
-	return 1;
-}
-
 //by marshmellow
 // - ASK Demod then Biphase decode GraphBuffer samples
 int ASKbiphaseDemod(const char *Cmd, bool verbose)
@@ -509,11 +464,11 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose)
 	int offset=0, clk=0, invert=0, maxErr=0, ans=0;
 	ans = sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr);
 	if (ans>0)
-		ans = ASKrawDemod(Cmd+1, FALSE);
+		ans = ASKDemod(Cmd+1, FALSE, FALSE, 0);
 	else
-		ans = ASKrawDemod(Cmd, FALSE);
+		ans = ASKDemod(Cmd, FALSE, FALSE, 0);
 	if (!ans) {
-		if (g_debugMode || verbose) PrintAndLog("Error AskrawDemod: %d", ans);
+		if (g_debugMode || verbose) PrintAndLog("Error AskDemod: %d", ans);
 		return 0;
 	}
 
@@ -521,8 +476,7 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose)
 	size_t size = DemodBufferLen;
 	uint8_t BitStream[MAX_DEMOD_BUF_LEN];
 	memcpy(BitStream, DemodBuffer, DemodBufferLen); 
-
-	int errCnt = BiphaseRawDecode(BitStream, &size, offset, invert);
+	int errCnt = BiphaseRawDecode(BitStream, &size, offset, 0);
 	if (errCnt < 0){
 		if (g_debugMode || verbose) PrintAndLog("Error BiphaseRawDecode: %d", errCnt);
 		return 0;
@@ -543,12 +497,13 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose)
 int Cmdaskbiphdemod(const char *Cmd)
 {
 	char cmdp = param_getchar(Cmd, 0);
-	if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') {
-		PrintAndLog("Usage:  data rawdemod ab [offset] [clock] <invert> [maxError] <amplify>");
+	if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') {
+		PrintAndLog("Usage:  data rawdemod ab [offset] [clock] <invert> [maxError] [maxLen] <amplify>");
 		PrintAndLog("     [offset], offset to begin biphase, default=0");
 		PrintAndLog("     [set clock as integer] optional, if not set, autodetect");
 		PrintAndLog("     <invert>, 1 to invert output");
 		PrintAndLog("     [set maximum allowed errors], default = 100");
+		PrintAndLog("     [set maximum Samples to read], default = 32768 (512 bits at rf/64)");
 		PrintAndLog("     <amplify>, 'a' to attempt demod with ask amplification, default = no amp");
 		PrintAndLog("     NOTE: <invert>  can be entered as second or third argument");
 		PrintAndLog("     NOTE: <amplify> can be entered as first, second or last argument");
@@ -556,13 +511,13 @@ int Cmdaskbiphdemod(const char *Cmd)
 		PrintAndLog("");
 		PrintAndLog("     NOTE: --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester");
 		PrintAndLog("");
-		PrintAndLog("    sample: data rawdemod ab            = demod an ask/biph tag from GraphBuffer");
-		PrintAndLog("          : data rawdemod ab a          = demod an ask/biph tag from GraphBuffer, amplified");
-		PrintAndLog("          : data rawdemod ab 1 32       = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32");
-		PrintAndLog("          : data rawdemod ab 0 32 1     = demod an ask/biph tag from GraphBuffer using a clock of RF/32 and inverting data");
-		PrintAndLog("          : data rawdemod ab 0 1        = demod an ask/biph tag from GraphBuffer while inverting data");
-		PrintAndLog("          : data rawdemod ab 0 64 1 0   = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
-		PrintAndLog("          : data rawdemod ab 0 64 1 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
+		PrintAndLog("    sample: data rawdemod ab              = demod an ask/biph tag from GraphBuffer");
+		PrintAndLog("          : data rawdemod ab 0 a          = demod an ask/biph tag from GraphBuffer, amplified");
+		PrintAndLog("          : data rawdemod ab 1 32         = demod an ask/biph tag from GraphBuffer using an offset of 1 and a clock of RF/32");
+		PrintAndLog("          : data rawdemod ab 0 32 1       = demod an ask/biph tag from GraphBuffer using a clock of RF/32 and inverting data");
+		PrintAndLog("          : data rawdemod ab 0 1          = demod an ask/biph tag from GraphBuffer while inverting data");
+		PrintAndLog("          : data rawdemod ab 0 64 1 0     = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
+		PrintAndLog("          : data rawdemod ab 0 64 1 0 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
 		return 0;
 	}
 	return ASKbiphaseDemod(Cmd, TRUE);
@@ -646,27 +601,28 @@ int CmdG_Prox_II_Demod(const char *Cmd)
 	return 1;
 }
 
-//by marshmellow - see ASKrawDemod
+//by marshmellow - see ASKDemod
 int Cmdaskrawdemod(const char *Cmd)
 {
 	char cmdp = param_getchar(Cmd, 0);
-	if (strlen(Cmd) > 12 || cmdp == 'h' || cmdp == 'H') {
-		PrintAndLog("Usage:  data rawdemod ar [clock] <invert> [maxError] [amplify]");
+	if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') {
+		PrintAndLog("Usage:  data rawdemod ar [clock] <invert> [maxError] [maxLen] [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("     [set maximum Samples to read], default = 32768 (1024 bits at rf/64)");
 		PrintAndLog("     <amplify>, 'a' to attempt demod with ask amplification, default = no amp");
 		PrintAndLog("");
-		PrintAndLog("    sample: data rawdemod ar          = demod an ask tag from GraphBuffer");
-		PrintAndLog("          : data rawdemod ar a        = demod an ask tag from GraphBuffer, amplified");
-		PrintAndLog("          : data rawdemod ar 32       = demod an ask tag from GraphBuffer using a clock of RF/32");
-		PrintAndLog("          : data rawdemod ar 32 1     = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data");
-		PrintAndLog("          : data rawdemod ar 1        = demod an ask tag from GraphBuffer while inverting data");
-		PrintAndLog("          : data rawdemod ar 64 1 0   = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
-		PrintAndLog("          : data rawdemod ar 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");
+		PrintAndLog("    sample: data rawdemod ar            = demod an ask tag from GraphBuffer");
+		PrintAndLog("          : data rawdemod ar a          = demod an ask tag from GraphBuffer, amplified");
+		PrintAndLog("          : data rawdemod ar 32         = demod an ask tag from GraphBuffer using a clock of RF/32");
+		PrintAndLog("          : data rawdemod ar 32 1       = demod an ask tag from GraphBuffer using a clock of RF/32 and inverting data");
+		PrintAndLog("          : data rawdemod ar 1          = demod an ask tag from GraphBuffer while inverting data");
+		PrintAndLog("          : data rawdemod ar 64 1 0     = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
+		PrintAndLog("          : data rawdemod ar 64 1 0 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;
 	}
-	return ASKrawDemod(Cmd, TRUE);
+	return ASKDemod(Cmd, TRUE, FALSE, 0);
 }
 
 int AutoCorrelate(int window, bool SaveGrph, bool verbose)
@@ -849,7 +805,6 @@ int CmdAskEdgeDetect(const char *Cmd)
 {
 	int thresLen = 25;
 	sscanf(Cmd, "%i", &thresLen); 
-	int shift = 127;
 
 	for(int i = 1; i<GraphTraceLen; i++){
 		if (GraphBuffer[i]-GraphBuffer[i-1]>=thresLen) //large jump up
@@ -867,9 +822,10 @@ int CmdAskEdgeDetect(const char *Cmd)
 int CmdDetectClockRate(const char *Cmd)
 {
 	char cmdp = param_getchar(Cmd, 0);
-	if (strlen(Cmd) > 3 || strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') {
-		PrintAndLog("Usage:  data detectclock [modulation]");
+	if (strlen(Cmd) > 6 || strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') {
+		PrintAndLog("Usage:  data detectclock [modulation] <clock>");
 		PrintAndLog("     [modulation as char], specify the modulation type you want to detect the clock of");
+		PrintAndLog("     <clock>             , specify the clock (optional - to get best start position only)");
 		PrintAndLog("       'a' = ask, 'f' = fsk, 'n' = nrz/direct, 'p' = psk");
 		PrintAndLog("");
 		PrintAndLog("    sample: data detectclock a    = detect the clock of an ask modulated wave in the GraphBuffer");
@@ -879,7 +835,7 @@ int CmdDetectClockRate(const char *Cmd)
 	}
 	int ans=0;
 	if (cmdp == 'a'){
-		ans = GetAskClock("", true, false);
+		ans = GetAskClock(Cmd+1, true, false);
 	} else if (cmdp == 'f'){
 		ans = GetFskClock("", true, false);
 	} else if (cmdp == 'n'){
@@ -2166,7 +2122,7 @@ static command_t CommandTable[] =
 	{"askem410xdemod",  CmdAskEM410xDemod,  1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
 	{"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
 	{"autocorr",        CmdAutoCorr,        1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
-	{"biphaserawdecode",CmdBiphaseDecodeRaw,1,"[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
+	{"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
 	{"bitsamples",      CmdBitsamples,      0, "Get raw samples as bitstring"},
 	{"buffclear",       CmdBuffClear,       1, "Clear sample buffer and graph window"},
 	{"dec",             CmdDec,             1, "Decimate samples"},
@@ -2185,7 +2141,7 @@ static command_t CommandTable[] =
 	{"load",            CmdLoad,            1, "<filename> -- Load trace (to graph window"},
 	{"ltrim",           CmdLtrim,           1, "<samples> -- Trim samples from left of trace"},
 	{"rtrim",           CmdRtrim,           1, "<location to end trace> -- Trim samples from right of trace"},
-	{"manrawdecode",    Cmdmandecoderaw,    1, "[maxErr] -- Manchester decode binary stream in DemodBuffer"},
+	{"manrawdecode",    Cmdmandecoderaw,    1, "[invert] [maxErr] -- Manchester decode binary stream in DemodBuffer"},
 	{"norm",            CmdNorm,            1, "Normalize max/min to +/-128"},
 	{"plot",            CmdPlot,            1, "Show graph window (hit 'h' in window for keystroke help)"},
 	{"printdemodbuffer",CmdPrintDemodBuff,  1, "[x] -- print the data in the DemodBuffer - 'x' for hex output"},
diff --git a/client/cmddata.h b/client/cmddata.h
index 0d2e32d6..9e179b9c 100644
--- a/client/cmddata.h
+++ b/client/cmddata.h
@@ -56,10 +56,10 @@ int CmdScale(const char *Cmd);
 int CmdDirectionalThreshold(const char *Cmd);
 int CmdZerocrossings(const char *Cmd);
 int CmdIndalaDecode(const char *Cmd);
-int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo);
+int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo );
+int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose);
 int ASKbiphaseDemod(const char *Cmd, bool verbose);
-int ASKmanDemod(const char *Cmd, bool verbose, bool emSearch);
-int ASKrawDemod(const char *Cmd, bool verbose);
+int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType);
 int FSKrawDemod(const char *Cmd, bool verbose);
 int PSKDemod(const char *Cmd, bool verbose);
 int NRZrawDemod(const char *Cmd, bool verbose);
diff --git a/client/cmdlf.c b/client/cmdlf.c
index a52e1423..d441574a 100644
--- a/client/cmdlf.c
+++ b/client/cmdlf.c
@@ -1091,7 +1091,7 @@ int CmdLFfind(const char *Cmd)
 				return 1;
 			}
 		}
-		ans=ASKmanDemod("0 0 0",TRUE,FALSE);
+		ans=ASKDemod("0 0 0",TRUE,FALSE,1);
 		if (ans>0) {
 			PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!");
 			PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'");
diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c
index 909045d3..614624a6 100644
--- a/client/cmdlfem4x.c
+++ b/client/cmdlfem4x.c
@@ -47,7 +47,7 @@ int CmdEM410xRead(const char *Cmd)
 	uint32_t hi=0;
 	uint64_t lo=0;
 
-	if(!AskEm410xDemod("", &hi, &lo)) return 0;
+	if(!AskEm410xDemod("", &hi, &lo, false)) return 0;
 	PrintAndLog("EM410x pattern found: ");
 	printEM410x(hi, lo);
 	if (hi){
@@ -455,7 +455,7 @@ int EM4x50Read(const char *Cmd, bool verbose)
 		else
 			phaseoff = 0;
 		i += 2;
-		if (ASKmanDemod(tmp2, false, false) < 1) {
+		if (ASKDemod(tmp2, false, false, 1) < 1) {
 			save_restoreGB(0);
 			return 0;
 		}
diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c
index e0f89153..564ad29d 100644
--- a/client/cmdlft55xx.c
+++ b/client/cmdlft55xx.c
@@ -262,11 +262,10 @@ int CmdT55xxReadBlock(const char *Cmd) {
 
 bool DecodeT55xxBlock(){
 	
-	char buf[10] = {0x00};
+	char buf[30] = {0x00};
 	char *cmdStr = buf;
 	int ans = 0;
 	uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};
-
 	DemodBufferLen = 0x00;
 
 	//trim 1/2 a clock from beginning
@@ -290,7 +289,7 @@ bool DecodeT55xxBlock(){
 			break;
 		case DEMOD_ASK:
 			snprintf(cmdStr, sizeof(buf),"%d %d 0", bitRate[config.bitrate], config.inverted );
-			ans = ASKmanDemod(cmdStr, FALSE, FALSE);
+			ans = ASKDemod(cmdStr, FALSE, FALSE, 1);
 			break;
 		case DEMOD_PSK1:
 			snprintf(cmdStr, sizeof(buf),"%d %d 0", bitRate[config.bitrate], config.inverted );
@@ -337,72 +336,79 @@ bool tryDetectModulation(){
 	char cmdStr[8] = {0};
 	uint8_t hits = 0;
 	t55xx_conf_block_t tests[15];
-	
+	int bitRate=0;
 	if (GetFskClock("", FALSE, FALSE)){ 
 		uint8_t fc1 = 0, fc2 = 0, clk=0;
 		fskClocks(&fc1, &fc2, &clk, FALSE);
 		sprintf(cmdStr,"%d", clk/2);
 		CmdLtrim(cmdStr);
-		if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset)){
+		if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){
 			tests[hits].modulation = DEMOD_FSK;
 			if (fc1==8 && fc2 == 5)
 				tests[hits].modulation = DEMOD_FSK1a;
 			else if (fc1==10 && fc2 == 8)
 				tests[hits].modulation = DEMOD_FSK2;
-
+			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = FALSE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 			++hits;
 		}
-		if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset)) {
+		if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)) {
 			tests[hits].modulation = DEMOD_FSK;
-			if (fc1==8 && fc2 == 5)
+			if (fc1 == 8 && fc2 == 5)
 				tests[hits].modulation = DEMOD_FSK1;
-			else if (fc1==10 && fc2 == 8)
+			else if (fc1 == 10 && fc2 == 8)
 				tests[hits].modulation = DEMOD_FSK2a;
 
+			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = TRUE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 			++hits;
 		}
 	} else {
-		if ( ASKmanDemod("0 0 1", FALSE, FALSE) && test(DEMOD_ASK, &tests[hits].offset)) {
+		if ( ASKDemod("0 0 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {
 			tests[hits].modulation = DEMOD_ASK;
+			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = FALSE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 			++hits;
-			}
+		}
 
-		if ( ASKmanDemod("0 1 1", FALSE, FALSE)  && test(DEMOD_ASK, &tests[hits].offset)) {
+		if ( ASKDemod("0 1 1", FALSE, FALSE, 1)  && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {
 			tests[hits].modulation = DEMOD_ASK;
+			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = TRUE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 			++hits;
-			}
+		}
 		
-		if ( NRZrawDemod("0 0 1", FALSE)  && test(DEMOD_NRZ, &tests[hits].offset)) {
+		if ( NRZrawDemod("0 0 1", FALSE)  && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {
 			tests[hits].modulation = DEMOD_NRZ;
+			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = FALSE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 			++hits;
 		}
 
-		if ( NRZrawDemod("0 1 1", FALSE)  && test(DEMOD_NRZ, &tests[hits].offset)) {
+		if ( NRZrawDemod("0 1 1", FALSE)  && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {
 			tests[hits].modulation = DEMOD_NRZ;
+			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = TRUE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 			++hits;
-			}
+		}
 		
-		if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) {
+		if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {
 			tests[hits].modulation = DEMOD_PSK1;
+			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = FALSE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 			++hits;
 		}
 		
-		if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset)) {
+		if ( PSKDemod("0 1 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {
 			tests[hits].modulation = DEMOD_PSK1;
+			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = TRUE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 			++hits;
@@ -411,8 +417,9 @@ bool tryDetectModulation(){
 		// PSK2 - needs a call to psk1TOpsk2.
 		if ( PSKDemod("0 0 1", FALSE)) {
 			psk1TOpsk2(DemodBuffer, DemodBufferLen);
-			if (test(DEMOD_PSK2, &tests[hits].offset)){
+			if (test(DEMOD_PSK2, &tests[hits].offset, &bitRate)){
 				tests[hits].modulation = DEMOD_PSK2;
+				tests[hits].bitrate = bitRate;
 				tests[hits].inverted = FALSE;
 				tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 				++hits;
@@ -422,22 +429,25 @@ bool tryDetectModulation(){
 		// PSK3 - needs a call to psk1TOpsk2.
 		if ( PSKDemod("0 0 1", FALSE)) {
 			psk1TOpsk2(DemodBuffer, DemodBufferLen);
-			if (test(DEMOD_PSK3, &tests[hits].offset)){
+			if (test(DEMOD_PSK3, &tests[hits].offset, &bitRate)){
 				tests[hits].modulation = DEMOD_PSK3;
+				tests[hits].bitrate = bitRate;
 				tests[hits].inverted = FALSE;
 				tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 				++hits;
 			}
 		} // inverse waves does not affect this demod
 	
-		if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset) ) {
+		if ( ASKbiphaseDemod("0 0 0 1", FALSE) && test(DEMOD_BI, &tests[hits].offset, &bitRate) ) {
 			tests[hits].modulation = DEMOD_BI;
+			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = FALSE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 			++hits;
 		}
-		if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset) ) {
+		if ( ASKbiphaseDemod("0 0 1 1", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate) ) {
 			tests[hits].modulation = DEMOD_BIa;
+			tests[hits].bitrate = bitRate;
 			tests[hits].inverted = TRUE;
 			tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
 			++hits;
@@ -445,6 +455,7 @@ bool tryDetectModulation(){
 	}		
 	if ( hits == 1) {
 		config.modulation = tests[0].modulation;
+		config.bitrate = tests[0].bitrate;
 		config.inverted = tests[0].inverted;
 		config.offset = tests[0].offset;
 		config.block0 = tests[0].block0;
@@ -504,35 +515,27 @@ bool testBitRate(uint8_t readRate, uint8_t mod){
 		case DEMOD_FSK2:
 		case DEMOD_FSK2a:
 			detRate = GetFskClock("",FALSE, FALSE); 
-			if (expected[readRate] == detRate) {
-				config.bitrate = readRate;
+			if (expected[readRate] == detRate) 
 				return TRUE;
-			}
 			break;
 		case DEMOD_ASK:
 		case DEMOD_BI:
 		case DEMOD_BIa:
 			detRate = GetAskClock("",FALSE, FALSE); 
-			if (expected[readRate] == detRate) {
-				config.bitrate = readRate;
+			if (expected[readRate] == detRate) 
 				return TRUE;
-			}
 			break;
 		case DEMOD_PSK1:
 		case DEMOD_PSK2:
 		case DEMOD_PSK3:
 			detRate = GetPskClock("",FALSE, FALSE); 
-			if (expected[readRate] == detRate) {
-				config.bitrate = readRate;
+			if (expected[readRate] == detRate)
 				return TRUE;
-			}
 			break;
 		case DEMOD_NRZ:
 			detRate = GetNrzClock("",FALSE, FALSE); 
-			if (expected[readRate] == detRate) {
-				config.bitrate = readRate;
+			if (expected[readRate] == detRate)
 				return TRUE;
-			}
 			break;
 		default:
 			return FALSE;
@@ -540,9 +543,9 @@ bool testBitRate(uint8_t readRate, uint8_t mod){
 	return FALSE;
 }
 
-bool test(uint8_t mode, uint8_t *offset){
+bool test(uint8_t mode, uint8_t *offset, int *fndBitRate){
 
-	if ( !DemodBufferLen) return FALSE;
+	if ( DemodBufferLen < 64 ) return FALSE;
 	uint8_t si = 0;
 	for (uint8_t idx = 0; idx < 64; idx++){
 		si = idx;
@@ -555,7 +558,8 @@ bool test(uint8_t mode, uint8_t *offset){
 		if ( resv > 0x00) continue;
 
 		uint8_t xtRate   = PackBits(si, 3, DemodBuffer); si += 3;     //extended mode part of rate
-		uint8_t bitRate  = PackBits(si, 3, DemodBuffer); si += 3;     //bit rate
+		int bitRate  = PackBits(si, 3, DemodBuffer); si += 3;     //bit rate
+		if (bitRate > 7) continue;
 		uint8_t extend   = PackBits(si, 1, DemodBuffer); si += 1;     //bit 15 extended mode
 		uint8_t modread  = PackBits(si, 5, DemodBuffer); si += 5+2+1; 
 		//uint8_t pskcr   = PackBits(si, 2, DemodBuffer); si += 2+1;  //could check psk cr
@@ -571,6 +575,7 @@ bool test(uint8_t mode, uint8_t *offset){
 		//test modulation
 		if (!testModulation(mode, modread)) continue;
 		if (!testBitRate(bitRate, mode)) continue;
+		*fndBitRate = bitRate;
 		*offset = idx;
 		return TRUE;
 	}
@@ -760,10 +765,10 @@ int CmdT55xxInfo(const char *Cmd){
 	
 	if (strlen(Cmd)==0)
 		AquireData( CONFIGURATION_BLOCK );
-	
+
 	if (!DecodeT55xxBlock()) return 1;
 
-	if ( !DemodBufferLen) return 1;
+	if ( DemodBufferLen < 32) return 1;
 
 	uint8_t si = config.offset;
 	uint32_t bl0      = PackBits(si, 32, DemodBuffer);
@@ -873,7 +878,8 @@ int AquireData( uint8_t block ){
 }
 
 char * GetBitRateStr(uint32_t id){
- 	static char buf[20];
+ 	static char buf[25];
+
 	char *retStr = buf;
 		switch (id){
 		case 0: 
diff --git a/client/graph.c b/client/graph.c
index 3bea7881..06279848 100644
--- a/client/graph.c
+++ b/client/graph.c
@@ -143,10 +143,10 @@ int GetAskClock(const char str[], bool printAns, bool verbose)
 			PrintAndLog("Failed to copy from graphbuffer");
 		return -1;
 	}
-	DetectASKClock(grph, size, &clock, 20);
+	int start = DetectASKClock(grph, size, &clock, 20);
 	// Only print this message if we're not looping something
 	if (printAns){
-		PrintAndLog("Auto-detected clock rate: %d", clock);
+		PrintAndLog("Auto-detected clock rate: %d, Best Starting Position: %d", clock, start);
 	}
 	return clock;
 }
diff --git a/common/lfdemod.c b/common/lfdemod.c
index 5bbf8a66..7d40d22e 100644
--- a/common/lfdemod.c
+++ b/common/lfdemod.c
@@ -112,7 +112,8 @@ uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_
 	return 0;
 }
 
-// demodulates strong heavily clipped samples
+//by marshmellow
+//demodulates strong heavily clipped samples
 int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int high, int low)
 {
 	size_t bitCnt=0, smplCnt=0, errCnt=0;
@@ -163,52 +164,81 @@ int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int
 }
 
 //by marshmellow
-//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 maxErr)
+void askAmp(uint8_t *BitStream, size_t size)
 {
-	size_t i;
+	for(size_t i = 1; i<size; i++){
+		if (BitStream[i]-BitStream[i-1]>=30) //large jump up
+			BitStream[i]=127;
+		else if(BitStream[i]-BitStream[i-1]<=-20) //large jump down
+			BitStream[i]=-127;
+	}
+	return;
+}
+
+//by marshmellow
+//attempts to demodulate ask modulations, askType == 0 for ask/raw, askType==1 for ask/manchester
+int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType)
+{
+	if (*size==0) return -1;
 	int start = DetectASKClock(BinStream, *size, clk, maxErr); //clock default
 	if (*clk==0 || start < 0) return -3;
-	if (*invert != 1) *invert=0;
+	if (*invert != 1) *invert = 0;
+	if (amp==1) askAmp(BinStream, *size);
+
 	uint8_t initLoopMax = 255;
 	if (initLoopMax > *size) initLoopMax = *size;
 	// Detect high and lows
-	// 25% fuzz in case highs and lows aren't clipped [marshmellow]
+	//25% clip in case highs and lows aren't clipped [marshmellow]
 	int high, low;
-	if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1) return -2; //just noise
+	if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1) 
+		return -2; //just noise
 
+	size_t errCnt = 0;
 	// if clean clipped waves detected run alternate demod
 	if (DetectCleanAskWave(BinStream, *size, high, low)) {
-		cleanAskRawDemod(BinStream, size, *clk, *invert, high, low);
-		return manrawdecode(BinStream, size);	
+		errCnt = cleanAskRawDemod(BinStream, size, *clk, *invert, high, low);
+		if (askType) //askman
+			return manrawdecode(BinStream, size, 0);	
+		else //askraw
+			return errCnt;
 	}
 
-	// PrintAndLog("DEBUG - valid high: %d - valid low: %d",high,low);
-	int lastBit;  //set first clock check
-	uint16_t bitnum = 0;     //output counter
+	int lastBit;  //set first clock check - can go negative
+	size_t i, bitnum = 0;     //output counter
+	uint8_t midBit = 0;
 	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 + or - 1 but could be increased for poor waves or removed entirely
-	uint16_t errCnt = 0, MaxBits = 512;
+	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
+	size_t MaxBits = 1024;
 	lastBit = start - *clk;
+
 	for (i = start; i < *size; ++i) {
-		if ((BinStream[i] >= high) && ((i-lastBit) > (*clk-tol))){
-			//high found and we are expecting a bar
-			lastBit += *clk;
-			BinStream[bitnum++] = *invert;
-		} else if ((BinStream[i] <= low) && ((i-lastBit) > (*clk-tol))){
-			//low found and we are expecting a bar
+		if (i-lastBit >= *clk-tol){
+			if (BinStream[i] >= high) {
+				BinStream[bitnum++] = *invert;
+			} else if (BinStream[i] <= low) {
+				BinStream[bitnum++] = *invert ^ 1;
+			} else if (i-lastBit >= *clk+tol) {
+				if (bitnum > 0) {
+					BinStream[bitnum++]=7;
+					errCnt++;						
+				} 
+			} else { //in tolerance - looking for peak
+				continue;
+			}
+			midBit = 0;
 			lastBit += *clk;
-			BinStream[bitnum++] = *invert ^ 1;
-		} else if ((i-lastBit)>(*clk+tol)){
-			//should have hit a high or low based on clock!!
-			//PrintAndLog("DEBUG - no wave in expected area - location: %d, expected: %d-%d, lastBit: %d - resetting search",i,(lastBit+(clk-((int)(tol)))),(lastBit+(clk+((int)(tol)))),lastBit);
-			if (bitnum > 0) {
-				BinStream[bitnum++] = 7;
-				errCnt++;
-			}		
-			lastBit += *clk;//skip over error
+		} else if (i-lastBit >= (*clk/2-tol) && !midBit && !askType){
+			if (BinStream[i] >= high) {
+				BinStream[bitnum++] = *invert;
+			} else if (BinStream[i] <= low) {
+				BinStream[bitnum++] = *invert ^ 1;
+			} else if (i-lastBit >= *clk/2+tol) {
+				BinStream[bitnum] = BinStream[bitnum-1];
+				bitnum++;
+			} else { //in tolerance - looking for peak
+				continue;
+			}
+			midBit = 1;
 		}
 		if (bitnum >= MaxBits) break;
 	}
@@ -216,34 +246,18 @@ int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max
 	return errCnt;
 }
 
-//by marshmellow
-//encode binary data into binary manchester 
-int ManchesterEncode(uint8_t *BitStream, size_t size)
-{
-	size_t modIdx=20000, i=0;
-	if (size>modIdx) return -1;
-	for (size_t idx=0; idx < size; idx++){
-		BitStream[idx+modIdx++] = BitStream[idx];
-		BitStream[idx+modIdx++] = BitStream[idx]^1;
-	}
-	for (; i<(size*2); i++){
-		BitStream[i] = BitStream[i+20000];
-	}
-	return i;
-}
-
 //by marshmellow
 //take 10 and 01 and manchester decode
 //run through 2 times and take least errCnt
-int manrawdecode(uint8_t * BitStream, size_t *size)
+int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert)
 {
 	uint16_t bitnum=0, MaxBits = 512, errCnt = 0;
 	size_t i, ii;
 	uint16_t bestErr = 1000, bestRun = 0;
-	if (size == 0) return -1;
+	if (*size < 16) return -1;
 	//find correct start position [alignment]
 	for (ii=0;ii<2;++ii){
-		for (i=ii; i<*size-2; i+=2)
+		for (i=ii; i<*size-3; i+=2)
 			if (BitStream[i]==BitStream[i+1])
 				errCnt++;
 
@@ -254,11 +268,11 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
 		errCnt=0;
 	}
 	//decode
-	for (i=bestRun; i < *size-2; i+=2){
+	for (i=bestRun; i < *size-3; i+=2){
 		if(BitStream[i] == 1 && (BitStream[i+1] == 0)){
-			BitStream[bitnum++]=0;
+			BitStream[bitnum++]=invert;
 		} else if((BitStream[i] == 0) && BitStream[i+1] == 1){
-			BitStream[bitnum++]=1;
+			BitStream[bitnum++]=invert^1;
 		} else {
 			BitStream[bitnum++]=7;
 		}
@@ -268,6 +282,22 @@ int manrawdecode(uint8_t * BitStream, size_t *size)
 	return bestErr;
 }
 
+//by marshmellow
+//encode binary data into binary manchester 
+int ManchesterEncode(uint8_t *BitStream, size_t size)
+{
+	size_t modIdx=20000, i=0;
+	if (size>modIdx) return -1;
+	for (size_t idx=0; idx < size; idx++){
+		BitStream[idx+modIdx++] = BitStream[idx];
+		BitStream[idx+modIdx++] = BitStream[idx]^1;
+	}
+	for (; i<(size*2); i++){
+		BitStream[i] = BitStream[i+20000];
+	}
+	return i;
+}
+
 //by marshmellow
 //take 01 or 10 = 1 and 11 or 00 = 0
 //check for phase errors - should never have 111 or 000 should be 01001011 or 10110100 for 1010
@@ -307,88 +337,7 @@ int BiphaseRawDecode(uint8_t *BitStream, size_t *size, int offset, int invert)
 	return errCnt;
 }
 
-//by marshmellow
-void askAmp(uint8_t *BitStream, size_t size)
-{
-	int shift = 127;
-	int shiftedVal=0;
-	for(size_t 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
-int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp)
-{
-	if (*size==0) return -1;
-	int start = DetectASKClock(BinStream, *size, clk, maxErr); //clock default
-	if (*clk==0 || start < 0) return -1;
-	if (*invert != 1) *invert = 0;
-	if (amp==1) askAmp(BinStream, *size);
-
-	uint8_t initLoopMax = 255;
-	if (initLoopMax > *size) initLoopMax = *size;
-	// Detect high and lows
-	//25% clip in case highs and lows aren't clipped [marshmellow]
-	int high, low;
-	if (getHiLo(BinStream, initLoopMax, &high, &low, 75, 75) < 1) 
-		return -1; //just noise
-
-	// if clean clipped waves detected run alternate demod
-	if (DetectCleanAskWave(BinStream, *size, high, low))
-		return cleanAskRawDemod(BinStream, size, *clk, *invert, high, low);
-
-	int lastBit;  //set first clock check - can go negative
-	size_t i, errCnt = 0, bitnum = 0;     //output counter
-	uint8_t midBit = 0;
-	size_t MaxBits = 1024;
-	lastBit = start - *clk;
-
-	for (i = start; i < *size; ++i) {
-		if (i - lastBit == *clk){
-			if (BinStream[i] >= high) {
-				BinStream[bitnum++] = *invert;
-			} else if (BinStream[i] <= low) {
-				BinStream[bitnum++] = *invert ^ 1;
-			} else {
-				if (bitnum > 0) {
-					BinStream[bitnum++]=7;
-					errCnt++;						
-				} 
-			}
-			midBit = 0;
-			lastBit += *clk;
-		} else if (i-lastBit == (*clk/2) && midBit == 0){
-			if (BinStream[i] >= high) {
-				BinStream[bitnum++] = *invert;
-			} else if (BinStream[i] <= low) {
-				BinStream[bitnum++] = *invert ^ 1;
-			} else {
-				BinStream[bitnum] = BinStream[bitnum-1];
-				bitnum++;
-			}
-			midBit = 1;
-		}
-		if (bitnum >= MaxBits) break;
-	}
-	*size = bitnum;
-	return errCnt;
-}
-
+// by marshmellow
 // demod gProxIIDemod 
 // error returns as -x 
 // success returns start position in BitStream
@@ -684,7 +633,8 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size)
 	return (int)startIdx;
 }
 
-
+// by marshmellow
+// to detect a wave that has heavily clipped (clean) samples
 uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low)
 {
 	uint16_t allPeaks=1;
@@ -792,7 +742,7 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr)
 
 	//test each valid clock from smallest to greatest to see which lines up
 	for(; clkCnt < clkEnd; clkCnt++){
-		if (clk[clkCnt] == 32){
+		if (clk[clkCnt] <= 32){
 			tol=1;
 		}else{
 			tol=0;
diff --git a/common/lfdemod.h b/common/lfdemod.h
index 0a4ceed9..ab81c34c 100644
--- a/common/lfdemod.h
+++ b/common/lfdemod.h
@@ -15,35 +15,37 @@
 #define LFDEMOD_H__
 #include <stdint.h>
 
-int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr);
-uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low);
-int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low);
-int askmandemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr);
-uint8_t Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
-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 maxErr, uint8_t amp);
+//generic
+int      askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType);
+int      BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
+uint32_t bytebits_to_byte(uint8_t* src, size_t numbits);
+uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj);
+int      DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr);
+uint8_t  DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low);
+uint8_t  detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
+int      DetectNRZClock(uint8_t dest[], size_t size, int clock);
+int      DetectPSKClock(uint8_t dest[], size_t size, int clock);
+int      DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low);
+uint8_t  Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
+int      fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, 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      ManchesterEncode(uint8_t *BitStream, size_t size);
+int      manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert);
+int      nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr);
+uint8_t  parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
+uint8_t  preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
+int      pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
+void     psk2TOpsk1(uint8_t *BitStream, size_t size);
+void     psk1TOpsk2(uint8_t *BitStream, size_t size);
+size_t   removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
+
+//tag specific
+int AWIDdemodFSK(uint8_t *dest, size_t *size);
 int gProxII_Demod(uint8_t BitStream[], size_t *size);
 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 nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr);
-void psk1TOpsk2(uint8_t *BitStream, size_t size);
-void psk2TOpsk1(uint8_t *BitStream, size_t size);
-int DetectNRZClock(uint8_t dest[], size_t size, int clock);
 int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
 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, uint8_t fskAdj);
-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);
-int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
-int DetectPSKClock(uint8_t dest[], size_t size, int clock);
 
 #endif
-- 
2.39.5