From: marshmellow42 <marshmellowrf@gmail.com>
Date: Mon, 23 Mar 2015 20:29:50 +0000 (-0400)
Subject: lf updates
X-Git-Tag: show^2~1
X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/1fbf89561686188fa869a10e1251406740238234

lf updates

applies icemans full ata55x7 read/write settings
adds checksum to ioprox (thanks to iceman)
adds silent mode for lf read and getSamples
fix lf em em410xwatch and lf em410xspoof
improve data rawdemod ar -  for biphase demods
improve detectclock a for strong antennas
---

diff --git a/armsrc/appmain.c b/armsrc/appmain.c
index 3e670f0b..6e0b58b3 100644
--- a/armsrc/appmain.c
+++ b/armsrc/appmain.c
@@ -648,7 +648,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
 			setSamplingConfig((sample_config *) c->d.asBytes);
 			break;
 		case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
-			cmd_send(CMD_ACK,SampleLF(),0,0,0,0);
+			cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0);
 			break;
 		case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
 			ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
diff --git a/armsrc/lfops.c b/armsrc/lfops.c
index 94cfafdf..7bbc739d 100644
--- a/armsrc/lfops.c
+++ b/armsrc/lfops.c
@@ -1054,15 +1054,11 @@ void T55xxWriteBit(int bit)
 // Write one card block in page 0, no lock
 void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
 {
-    uint32_t i;
-
-    FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-    FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-    FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+    uint32_t i = 0;
 
-    // Give it a bit of time for the resonant antenna to settle.
-    // And for the tag to fully power up
-    //SpinDelay(150);
+    // Set up FPGA, 125kHz
+    // Wait for config.. (192+8190xPOW)x8 == 67ms
+    LFSetupFPGAForADC(0, true);
 
     // Now start writting
     FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
diff --git a/armsrc/lfsampling.c b/armsrc/lfsampling.c
index 6094bd34..120c0801 100644
--- a/armsrc/lfsampling.c
+++ b/armsrc/lfsampling.c
@@ -224,21 +224,21 @@ uint32_t DoAcquisition_config( bool silent)
 				  ,silent);
 }
 
-uint32_t ReadLF(bool activeField)
+uint32_t ReadLF(bool activeField, bool silent)
 {
-	printConfig();
+	if (!silent) printConfig();
 	LFSetupFPGAForADC(config.divisor, activeField);
 	// Now call the acquisition routine
-	return DoAcquisition_config(false);
+	return DoAcquisition_config(silent);
 }
 
 /**
 * Initializes the FPGA for reader-mode (field on), and acquires the samples.
 * @return number of bits sampled
 **/
-uint32_t SampleLF()
+uint32_t SampleLF(bool printCfg)
 {
-	return ReadLF(true);
+	return ReadLF(true, printCfg);
 }
 /**
 * Initializes the FPGA for snoop-mode (field off), and acquires the samples.
@@ -247,5 +247,5 @@ uint32_t SampleLF()
 
 uint32_t SnoopLF()
 {
-	return ReadLF(false);
+	return ReadLF(false, true);
 }
diff --git a/armsrc/lfsampling.h b/armsrc/lfsampling.h
index 9ab458f8..6c671ec8 100644
--- a/armsrc/lfsampling.h
+++ b/armsrc/lfsampling.h
@@ -5,7 +5,7 @@
 * Initializes the FPGA for reader-mode (field on), and acquires the samples.
 * @return number of bits sampled
 **/
-uint32_t SampleLF();
+uint32_t SampleLF(bool silent);
 
 /**
 * Initializes the FPGA for snoop-mode (field off), and acquires the samples.
diff --git a/client/cmddata.c b/client/cmddata.c
index 8017d169..a69b5ca7 100644
--- a/client/cmddata.c
+++ b/client/cmddata.c
@@ -558,6 +558,7 @@ int CmdBiphaseDecodeRaw(const char *Cmd)
 		PrintAndLog("Usage:  data biphaserawdecode [offset] [invert] [maxErr]");
 		PrintAndLog("     Converts 10 or 01 to 1 and 11 or 00 to 0");
 		PrintAndLog("     --must have binary sequence in demodbuffer (run data askrawdemod first)");
+    PrintAndLog("     --invert for Conditional Dephase Encoding (CDP) AKA Differential Manchester");
 		PrintAndLog("");
 		PrintAndLog("     [offset <0|1>], set to 0 not to adjust start position or to 1 to adjust decode start position");
 		PrintAndLog("     [invert <0|1>], set to 1 to invert output");
@@ -720,6 +721,8 @@ int Cmdaskbiphdemod(const char *Cmd)
     PrintAndLog("     NOTE: <amplify> can be entered as first, second or last argument");
     PrintAndLog("     NOTE: any other arg must have previous args set to work");
     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");
@@ -1420,7 +1423,20 @@ int CmdFSKdemodIO(const char *Cmd)
   uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4
   uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
   uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
-  PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
+  uint8_t crc = bytebits_to_byte(BitStream+idx+54,8);
+  uint16_t calccrc = 0;
+
+  for (uint8_t i=1; i<6; ++i){
+    calccrc += bytebits_to_byte(BitStream+idx+9*i,8);
+    PrintAndLog("%d", calccrc);
+  }
+  calccrc &= 0xff;
+  calccrc = 0xff - calccrc;
+
+  char *crcStr = (crc == calccrc) ? "crc ok": "!crc";
+
+  PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
+  //PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
   setDemodBuf(BitStream,64,idx);
   if (g_debugMode){
     PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64);
@@ -2056,7 +2072,7 @@ int CmdRawDemod(const char *Cmd)
 		PrintAndLog("   <help> as 'h', prints the help for the specific modulation");	
 		PrintAndLog("   <options> see specific modulation help for optional parameters");				
 		PrintAndLog("");
-		PrintAndLog("    sample: data rawdemod fs h         = print help for ask/raw demod");
+		PrintAndLog("    sample: data rawdemod fs h         = print help specific to fsk demod");
 		PrintAndLog("          : data rawdemod fs           = demod GraphBuffer using: fsk - autodetect");
 		PrintAndLog("          : data rawdemod ab           = demod GraphBuffer using: ask/biphase - autodetect");
 		PrintAndLog("          : data rawdemod am           = demod GraphBuffer using: ask/manchester - autodetect");
@@ -2185,57 +2201,64 @@ uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
 	return val;
 }
 
-int CmdSamples(const char *Cmd)
+int getSamples(const char *Cmd, bool silent)
 {
-	//If we get all but the last byte in bigbuf,
-	// we don't have to worry about remaining trash
-	// in the last byte in case the bits-per-sample
-	// does not line up on byte boundaries
-	uint8_t got[BIGBUF_SIZE-1] = { 0 };
+  //If we get all but the last byte in bigbuf,
+  // we don't have to worry about remaining trash
+  // in the last byte in case the bits-per-sample
+  // does not line up on byte boundaries
 
-	int n = strtol(Cmd, NULL, 0);
-	if (n == 0)
-		n = sizeof(got);
+  uint8_t got[BIGBUF_SIZE-1] = { 0 };
 
-	if (n > sizeof(got))
-		n = sizeof(got);
+  int n = strtol(Cmd, NULL, 0);
 
-	PrintAndLog("Reading %d bytes from device memory\n", n);
-	GetFromBigBuf(got,n,0);
-	PrintAndLog("Data fetched");
-	UsbCommand response;
-	WaitForResponse(CMD_ACK, &response);
-	uint8_t bits_per_sample = 8;
+  if (n == 0)
+    n = sizeof(got);
 
-	//Old devices without this feature would send 0 at arg[0]
-	if(response.arg[0] > 0)
-	{
-		sample_config *sc = (sample_config *) response.d.asBytes;
-		PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample
-					, sc->decimation);
-		bits_per_sample = sc->bits_per_sample;
-	}
-	if(bits_per_sample < 8)
-	{
-		PrintAndLog("Unpacking...");
-		BitstreamOut bout = { got, bits_per_sample * n,  0};
-		int j =0;
-		for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) {
-			uint8_t sample = getByte(bits_per_sample, &bout);
-			GraphBuffer[j] = ((int) sample )- 128;
-		}
-		GraphTraceLen = j;
-		PrintAndLog("Unpacked %d samples" , j );
-	}else
-	{
-		for (int j = 0; j < n; j++) {
-			GraphBuffer[j] = ((int)got[j]) - 128;
-		}
-		GraphTraceLen = n;
-	}
+  if (n > sizeof(got))
+    n = sizeof(got);
 
-	RepaintGraphWindow();
-	return 0;
+  PrintAndLog("Reading %d bytes from device memory\n", n);
+  GetFromBigBuf(got,n,0);
+  PrintAndLog("Data fetched");
+  UsbCommand response;
+  WaitForResponse(CMD_ACK, &response);
+  uint8_t bits_per_sample = 8;
+
+  //Old devices without this feature would send 0 at arg[0]
+  if(response.arg[0] > 0)
+  {
+    sample_config *sc = (sample_config *) response.d.asBytes;
+    PrintAndLog("Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample
+          , sc->decimation);
+    bits_per_sample = sc->bits_per_sample;
+  }
+  if(bits_per_sample < 8)
+  {
+    PrintAndLog("Unpacking...");
+    BitstreamOut bout = { got, bits_per_sample * n,  0};
+    int j =0;
+    for (j = 0; j * bits_per_sample < n * 8 && j < sizeof(GraphBuffer); j++) {
+      uint8_t sample = getByte(bits_per_sample, &bout);
+      GraphBuffer[j] = ((int) sample )- 128;
+    }
+    GraphTraceLen = j;
+    PrintAndLog("Unpacked %d samples" , j );
+  }else
+  {
+    for (int j = 0; j < n; j++) {
+      GraphBuffer[j] = ((int)got[j]) - 128;
+    }
+    GraphTraceLen = n;
+  }
+
+  RepaintGraphWindow();
+  return 0;
+}
+
+int CmdSamples(const char *Cmd)
+{
+  return getSamples(Cmd, false);
 }
 
 int CmdTuneSamples(const char *Cmd)
diff --git a/client/cmddata.h b/client/cmddata.h
index 052bce06..f6b4b950 100644
--- a/client/cmddata.h
+++ b/client/cmddata.h
@@ -71,6 +71,8 @@ int FSKrawDemod(const char *Cmd, bool verbose);
 int PSKDemod(const char *Cmd, bool verbose);
 int NRZrawDemod(const char *Cmd, bool verbose);
 void printEM410x(uint32_t hi, uint64_t id);
+int getSamples(const char *Cmd, bool silent);
+
 
 #define MAX_DEMOD_BUF_LEN (1024*128)
 extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
diff --git a/client/cmdlf.c b/client/cmdlf.c
index 4a1ee519..0fab2adf 100644
--- a/client/cmdlf.c
+++ b/client/cmdlf.c
@@ -362,6 +362,7 @@ int usage_lf_read()
 	PrintAndLog("Usage: lf read");
 	PrintAndLog("Options:        ");
 	PrintAndLog("       h            This help");
+	PrintAndLog("       s            silent run no printout");
 	PrintAndLog("This function takes no arguments. ");
 	PrintAndLog("Use 'lf config' to set parameters.");
 	return 0;
@@ -481,13 +482,15 @@ int CmdLFSetConfig(const char *Cmd)
 int CmdLFRead(const char *Cmd)
 {
 
-	uint8_t cmdp =0;
-	if(param_getchar(Cmd, cmdp) == 'h')
+	uint8_t cmdp = 0;
+	bool arg1 = false;
+	if (param_getchar(Cmd, cmdp) == 'h')
 	{
 		return usage_lf_read();
 	}
+	if (param_getchar(Cmd, cmdp) == 's') arg1 = true; //suppress print
 	//And ship it to device
-	UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K};
+	UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
 	SendCommand(&c);
 	WaitForResponse(CMD_ACK,NULL);
 	return 0;
@@ -1137,7 +1140,7 @@ static command_t CommandTable[] =
   {"io",       	  CmdLFIO,	          1, "{ ioProx tags... }"},
   {"indalademod", CmdIndalaDemod,     1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
   {"indalaclone", CmdIndalaClone,     0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
-  {"read",        CmdLFRead,          0, "Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
+  {"read",        CmdLFRead,          0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
   {"search",      CmdLFfind,          1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) - 'u' to search for unknown tags"},
   {"sim",         CmdLFSim,           0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
   {"simask",      CmdLFaskSim,        0, "[clock] [invert <1|0>] [manchester/raw <'m'|'r'>] [msg separator 's'] [d <hexdata>] -- Simulate LF ASK tag from demodbuffer or input"},
diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c
index 5faf4801..b915aa5a 100644
--- a/client/cmdlfem4x.c
+++ b/client/cmdlfem4x.c
@@ -53,8 +53,9 @@ int CmdEM410xRead(const char *Cmd)
     PrintAndLog ("EM410x XL pattern found");
     return 0;
   }
-  char id[11] = {0x00};
-  sprintf(id, "%010x", lo);
+  char id[12] = {0x00};
+  sprintf(id, "%010llx",lo);
+  
   global_em410xId = id;
   return 1;
 }
@@ -148,8 +149,8 @@ int CmdEM410xWatch(const char *Cmd)
 			break;
 		}
 		
-		CmdLFRead("");
-		CmdSamples("6000");		
+		CmdLFRead("s");
+		getSamples("8192",true); //capture enough to get 2 full messages		
 	} while (!CmdEM410xRead(""));
 
 	return 0;
@@ -158,9 +159,9 @@ int CmdEM410xWatch(const char *Cmd)
 int CmdEM410xWatchnSpoof(const char *Cmd)
 {
 	CmdEM410xWatch(Cmd);
-    PrintAndLog("# Replaying captured ID: %s",global_em410xId);
-    CmdLFaskSim("");
-  return 0;
+	PrintAndLog("# Replaying captured ID: %s",global_em410xId);
+	CmdLFaskSim("");
+	return 0;
 }
 
 /* Read the transmitted data of an EM4x50 tag
diff --git a/client/cmdlft55xx.c b/client/cmdlft55xx.c
index 57540bd8..da3ee1a9 100644
--- a/client/cmdlft55xx.c
+++ b/client/cmdlft55xx.c
@@ -246,7 +246,7 @@ int CmdT55xxReadBlock(const char *Cmd) {
 	WaitForResponse(CMD_ACK,NULL);
 	setGraphBuf(got, 12000);
 	DemodBufferLen=0;
-	if (!DecodeT55xxBlock()) return 0;
+	if (!DecodeT55xxBlock()) return 3;
 	char blk[10]={0};
 	sprintf(blk,"%d", block);
 	printT55xxBlock(blk);
@@ -1009,7 +1009,7 @@ char * GetModulationStr( uint32_t id){
 			sprintf(retStr,"%d - Biphase",id);
 			break;
 		case 0x18:
-			sprintf(retStr,"%d - Biphase a",id);
+			sprintf(retStr,"%d - Biphase a - AKA Conditional Dephase Encoding(CDP)",id);
 			break;
 		case 17:
 			sprintf(retStr,"%d - Reserved",id);
@@ -1071,7 +1071,7 @@ char * GetSelectedModulationStr( uint8_t id){
 			sprintf(retStr,"BIPHASE");
 			break;
 		case DEMOD_BIa:
-			sprintf(retStr,"BIPHASEa");
+			sprintf(retStr,"BIPHASEa - (CDP)");
 			break;
 		default:
 			sprintf(retStr,"(Unknown)");
diff --git a/client/scripts/test_t55x7_psk.lua b/client/scripts/test_t55x7_psk.lua
index 766d853f..cbd78e87 100644
--- a/client/scripts/test_t55x7_psk.lua
+++ b/client/scripts/test_t55x7_psk.lua
@@ -42,6 +42,7 @@ Arguments:
 
 local TIMEOUT = 2000 -- Shouldn't take longer than 2 seconds
 local DEBUG = true -- the debug flag
+
 	
 -- local procedurecmds = {
 	-- [1] = '%s%s%s%s',
@@ -54,11 +55,11 @@ local DEBUG = true -- the debug flag
 -- }
 
 -- --BLOCK 0 = 00 08 80 40 PSK
-						-- -----------
-							--  08------- bitrate
-									-- 8----- modulation PSK1
-									 -- 0---- PSK ClockRate
-										 -- 40 max 2 blocks
+             -- -----------
+			   -- 08------- bitrate
+				  -- 8----- modulation PSK1
+				   -- 0---- PSK ClockRate
+				      -- 40 max 2 blocks
 
 local procedurecmds = {
 	[1] = '00%02X%X%X40',
@@ -110,26 +111,30 @@ function test(modulation)
 	for bitrate = 0x0, 0x1d, 0x4 do
 	
 		for clockrate = 0,8,4 do
-			local cmd = procedurecmds[_]
-
-			if #cmd == 0 then
-
-			elseif _ == 1 then
-
-				dbg("Writing to T55x7 TAG")
 
-				local config = cmd:format(bitrate, modulation, clockrate)
-				dbg(('lf t55xx write 0 %s'):format(config))
+			for _ = 1, #procedurecmds do
+				local cmd = procedurecmds[_]
 				
-				config = tonumber(config,16) 
-				local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config ,arg2 = 0, arg3 = 0}
-				local err = core.SendCommand(writecommand:getBytes())
-				if err then return oops(err) end
-				local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
-			else
-				dbg(cmd)
-				core.console( cmd )
+				if #cmd == 0 then  
+				
+				elseif _ == 1 then
+
+					dbg("Writing to T55x7 TAG")
+
+					local config = cmd:format(bitrate, modulation, clockrate)
+					dbg(('lf t55xx write 0 %s'):format(config))
+					
+					config = tonumber(config,16) 
+					local writecommand = Command:new{cmd = cmds.CMD_T55XX_WRITE_BLOCK, arg1 = config ,arg2 = 0, arg3 = 0}
+					local err = core.SendCommand(writecommand:getBytes())
+					if err then return oops(err) end
+					local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
+				else
+					dbg(cmd)
+					core.console( cmd )
+				end
 			end
+			core.clearCommandBuffer()	
 		end
 	end
 	print( string.rep('--',20) )
@@ -147,10 +152,20 @@ local function main(args)
 
 	core.clearCommandBuffer()
 
-	test(1) --PSK1
-	-- test(2) --PSK2
-	-- test(3) --PSK3
+	test(1)  -- PSK1
+	--test(2) -- PSK2
+	--test(3) -- PSK3
 	
 	print( string.rep('--',20) )
 end
 main(args)
+
+-- Where it iterates over 
+  -- xxxx8xxx = PSK RF/2 with Manchester modulation
+  -- xxxx1xxx = PSK RF/2 with PSK1 modulation (phase change when input changes)
+  -- xxxx2xxx = PSK RF/2 with PSk2 modulation (phase change on bitclk if input high)
+  -- xxxx3xxx = PSK RF/2 with PSk3 modulation (phase change on rising edge of input)
+
+    -- XXXXX0XX = PSK RF/2
+    -- XXXXX4XX = PSK RF/4
+    -- XXXXX8XX = PSK RF/8
diff --git a/common/lfdemod.c b/common/lfdemod.c
index 5b0bc29d..c7acb404 100644
--- a/common/lfdemod.c
+++ b/common/lfdemod.c
@@ -375,34 +375,39 @@ int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int
 			smplCnt++;
 		} else if (BinStream[i] <= low && !waveHigh){
 			smplCnt++;
-		} else { //not high or low or a transition
-			if (smplCnt > clk-(clk/4)) { //full clock
-				if (smplCnt > clk + (clk/4)) { //too many samples
-					errCnt++;
-					BinStream[bitCnt++]=77;
-				} else if (waveHigh) {
-					BinStream[bitCnt++] = invert;
-					BinStream[bitCnt++] = invert;
-				} else if (!waveHigh) {
-					BinStream[bitCnt++] = invert ^ 1;
-					BinStream[bitCnt++] = invert ^ 1;
-				}
-				waveHigh ^= 1;  
-				smplCnt = 0;
-			} else if (smplCnt > (clk/2) - (clk/5)) {
-				if (waveHigh) {
-					BinStream[bitCnt++] = invert;
-				} else if (!waveHigh) {
-					BinStream[bitCnt++] = invert ^ 1;
+		} else { //transition
+			if ((BinStream[i] >= high && !waveHigh) || (BinStream[i] <= low && waveHigh)){
+				if (smplCnt > clk-(clk/4)-1) { //full clock
+					if (smplCnt > clk + (clk/4)+1) { //too many samples
+						errCnt++;
+						BinStream[bitCnt++]=77;
+					} else if (waveHigh) {
+						BinStream[bitCnt++] = invert;
+						BinStream[bitCnt++] = invert;
+					} else if (!waveHigh) {
+						BinStream[bitCnt++] = invert ^ 1;
+						BinStream[bitCnt++] = invert ^ 1;
+					}
+					waveHigh ^= 1;  
+					smplCnt = 0;
+				} else if (smplCnt > (clk/2) - (clk/4)-1) {
+					if (waveHigh) {
+						BinStream[bitCnt++] = invert;
+					} else if (!waveHigh) {
+						BinStream[bitCnt++] = invert ^ 1;
+					}
+					waveHigh ^= 1;  
+					smplCnt = 0;
+				} else if (!bitCnt) {
+					//first bit
+					waveHigh = (BinStream[i] >= high);
+					smplCnt = 1;
+				} else {
+					smplCnt++;
+					//transition bit oops
 				}
-				waveHigh ^= 1;  
-				smplCnt = 0;
-			} else if (!bitCnt) {
-				//first bit
-				waveHigh = (BinStream[i] >= high);
-				smplCnt = 1;
-			} else {
-				//transition bit? ignore
+			} else { //haven't hit new high or new low yet
+				smplCnt++;
 			}
 		}
 	}
@@ -888,16 +893,18 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size)
 
 uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low)
 {
-	uint8_t allPeaks=1;
+	uint16_t allPeaks=1;
 	uint16_t cntPeaks=0;
-	for (size_t i=30; i<255; i++){
+	size_t loopEnd = 572;
+	if (loopEnd > size) loopEnd = size;
+	for (size_t i=60; i<loopEnd; i++){
 		if (dest[i]>low && dest[i]<high) 
 			allPeaks=0;
 		else
 			cntPeaks++;
 	}
-	if (allPeaks==0){
-		if (cntPeaks>210) return 1;
+	if (allPeaks == 0){
+		if (cntPeaks > 300) return 1;
 	}
 	return allPeaks;
 }
@@ -939,10 +946,12 @@ int DetectStrongAskClock(uint8_t dest[], size_t size)
 			}
 		}
 	}
+	uint8_t tol;
 	for (idx=8; idx>0; idx--){
-		if (clk[idx] >= highCnt && clk[idx] <= highCnt+2)
+		tol = clk[idx]/8;
+		if (clk[idx] >= highCnt - tol && clk[idx] <= highCnt + tol)
 			return clk[idx];
-		if (clk[idx] >= highCnt2 && clk[idx] <= highCnt2+2)
+		if (clk[idx] >= highCnt2 - tol && clk[idx] <= highCnt2 + tol)
 			return clk[idx];
 	}
 	return -1;