From 779d9a0e90a20392785adbaa4974cafaa27005a8 Mon Sep 17 00:00:00 2001
From: marshmellow42 <marshmellowrf@gmail.com>
Date: Sat, 10 Feb 2018 17:30:32 -0500
Subject: [PATCH] reconfigure lf cmdread ...

to use lf config settings instead of it's own settings.  (now allows
full options of lf config...)

also it will now run `data samples` when the command completes making it
not necessary to run manually...

note: adjusted client wait message as it was confusing.
---
 armsrc/lfops.c   | 48 ++++++++++++++++++++++++++----------------------
 client/cmdlf.c   | 30 +++++++++++-------------------
 client/cmdmain.c |  2 +-
 3 files changed, 38 insertions(+), 42 deletions(-)

diff --git a/armsrc/lfops.c b/armsrc/lfops.c
index 5e9fb193..c7a7a59d 100644
--- a/armsrc/lfops.c
+++ b/armsrc/lfops.c
@@ -4,7 +4,7 @@
 // the license.
 //-----------------------------------------------------------------------------
 // Miscellaneous routines for low frequency tag operations.
-// Tags supported here so far are Texas Instruments (TI), HID
+// Tags supported here so far are Texas Instruments (TI), HID, EM4x05, EM410x
 // Also routines for raw mode reading/simulating of LF waveform
 //-----------------------------------------------------------------------------
 
@@ -28,17 +28,12 @@
  */
 void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command)
 {
-
+	// start timer
 	StartTicks();
-	int divisor_used = 95; // 125 KHz
-	// see if 'h' was specified
-
-	if (command[strlen((char *) command) - 1] == 'h')
-		divisor_used = 88; // 134.8 KHz
 
-	sample_config sc = { 0,0,1, divisor_used, 0};
-	setSamplingConfig(&sc);
-	//clear read buffer
+	// use lf config settings
+	sample_config *sc = getSamplingConfig();
+	// clear read buffer
 	BigBuf_Clear_keep_EM();
 
 	/* Make sure the tag is reset */
@@ -46,8 +41,8 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	WaitMS(2500);
 
-	//power on
-	LFSetupFPGAForADC(sc.divisor, 1);
+	// power on
+	LFSetupFPGAForADC(sc->divisor, 1);
 
 	// And a little more time for the tag to fully power up
 	WaitMS(2000);
@@ -56,15 +51,21 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
 	// now modulate the reader field
 
 	if (bitbang) {
-		//HACK it appears my loop and if statements take up about 7 us so adjust waits accordingly...
+		// HACK it appears the loop and if statements take up about 7us so adjust waits accordingly...
 		uint8_t hack_cnt = 7;
 		if (period_0 < hack_cnt || period_1 < hack_cnt) {
-			DbpString("Warning periods cannot be less than 7 in bit bang mode");
+			DbpString("Warning periods cannot be less than 7us in bit bang mode");
 			FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 			LED_D_OFF();
 			return;
 		}
-		//prime cmd_len to save time comparing strings while modulating
+
+		// hack2 needed---  it appears to take about 8-16us to turn the antenna back on 
+		// leading to ~ 1 to 2 125khz samples extra in every off period 
+		// so we should test for last 0 before next 1 and reduce period_0 by this extra amount...
+		// but is this time different for every antenna or other hw builds???  more testing needed
+
+		// prime cmd_len to save time comparing strings while modulating
 		int cmd_len = 0;
 		while(command[cmd_len] != '\0' && command[cmd_len] != ' ')
 			cmd_len++;
@@ -72,7 +73,6 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
 		int counter = 0;
 		bool off = false;
 		for (counter = 0; counter < cmd_len; counter++) {
-		//while(*command != '\0' && *command != ' ') {
 			// if cmd = 0 then turn field off
 			if (command[counter] == '0') {
 				// if field already off leave alone (affects timing otherwise)
@@ -81,17 +81,17 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
 					LED_D_OFF();
 					off = true;
 				}
-				// note we appear to take about 6us to switch over (or run the if statements/loop...)
+				// note we appear to take about 7us to switch over (or run the if statements/loop...)
 				WaitUS(period_0-hack_cnt);
 			// else if cmd = 1 then turn field on
 			} else {
 				// if field already on leave alone (affects timing otherwise)
 				if (off) {
-					FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);				
+					FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
 					LED_D_ON();
 					off = false;
 				}
-				// note we appear to take about 6us to switch over (or run the if statements/loop...)
+				// note we appear to take about 7us to switch over (or run the if statements/loop...)
 				WaitUS(period_1-hack_cnt);
 			}
 		}
@@ -100,7 +100,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
 			FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 			LED_D_OFF();
 			WaitUS(delay_off);
-			FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
+			FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor);
 			FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
 			LED_D_ON();
 			if(*(command++) == '0') {
@@ -112,14 +112,18 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
 		FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 		LED_D_OFF();
 		WaitUS(delay_off);
-		FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
+		FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor);
 	}
 
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
 
 	// now do the read
 	DoAcquisition_config(false, 0);
-	// note leaves field on...  (for future commands?)
+
+	// Turn off antenna
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+	// tell client we are done
+	cmd_send(CMD_ACK,0,0,0,0,0);
 }
 
 /* blank r/w tag data stream
diff --git a/client/cmdlf.c b/client/cmdlf.c
index ef9c3cbb..42f73fa1 100644
--- a/client/cmdlf.c
+++ b/client/cmdlf.c
@@ -54,26 +54,24 @@ static int CmdHelp(const char *Cmd);
 
 int usage_lf_cmdread(void)
 {
-	PrintAndLog("Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes> [H] ");
+	PrintAndLog("Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes> ");
 	PrintAndLog("Options:        ");
 	PrintAndLog("       h             This help");
-	PrintAndLog("       L             Low frequency (125 KHz)");
-	PrintAndLog("       H             High frequency (134 KHz)");
-	PrintAndLog("       d <delay>     delay OFF period");
-	PrintAndLog("       z <zero>      time period ZERO");
-	PrintAndLog("       o <one>       time period ONE");
+	PrintAndLog("       d <delay>     delay OFF period between bits (0 for bitbang mode)");
+	PrintAndLog("       z <zero>      time period ZERO (antenna off in bitbang mode)");
+	PrintAndLog("       o <one>       time period ONE (antenna on in bitbang mode)");
 	PrintAndLog("       c <cmd>       Command bytes");
 	PrintAndLog("       ************* All periods in microseconds");
+	PrintAndLog("       ************* Use lf config to configure options.");
 	PrintAndLog("Examples:");
 	PrintAndLog("      lf cmdread d 80 z 100 o 200 c 11000");
-	PrintAndLog("      lf cmdread d 80 z 100 o 100 c 11000 H");
+	PrintAndLog("      lf cmdread d 80 z 100 o 100 c 11000");
 	return 0;
 }
 
 /* send a command before reading */
 int CmdLFCommandRead(const char *Cmd)
 {
-	static char dummy[3] = {0x20,0x00,0x00};
 	UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
 	bool errors = false;
 	//uint8_t divisor = 95; //125khz
@@ -84,14 +82,6 @@ int CmdLFCommandRead(const char *Cmd)
 		{
 		case 'h':
 			return usage_lf_cmdread();
-		case 'H':
-			//divisor = 88;
-			dummy[1]='h';
-			cmdp++;
-			break;
-		case 'L':
-			cmdp++;
-			break;
 		case 'c':
 			param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes, sizeof(c.d.asBytes));
 			cmdp+=2;
@@ -121,11 +111,13 @@ int CmdLFCommandRead(const char *Cmd)
 	//Validations
 	if(errors) return usage_lf_cmdread();
 	
-	// in case they specified 'H'
-	strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
-
 	clearCommandBuffer();
 	SendCommand(&c);
+
+	WaitForResponse(CMD_ACK,NULL);
+	getSamples(0, true);
+
+
 	return 0;
 }
 
diff --git a/client/cmdmain.c b/client/cmdmain.c
index 719617fd..8d9313f9 100644
--- a/client/cmdmain.c
+++ b/client/cmdmain.c
@@ -162,7 +162,7 @@ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeo
 		}
 		if (msclock() - start_time > 2000 && show_warning) {
 			PrintAndLog("Waiting for a response from the proxmark...");
-			PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
+			PrintAndLog("You can cancel this operation by pressing the pm3 button");
 			show_warning = false;
 		}
 	}
-- 
2.39.5