X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/07c808038c48a74842290084d1217d6f69cbf18e..b7eddc14db9262a51ad3100ade7386d03500ace8:/armsrc/lfops.c?ds=inline

diff --git a/armsrc/lfops.c b/armsrc/lfops.c
index b9dbb8e2..7e53d4a5 100644
--- a/armsrc/lfops.c
+++ b/armsrc/lfops.c
@@ -15,130 +15,45 @@
 #include "crc16.h"
 #include "string.h"
 #include "lfdemod.h"
+#include "lfsampling.h"
+#include "usb_cdc.h"
 
 
 /**
-* Does the sample acquisition. If threshold is specified, the actual sampling
-* is not commenced until the threshold has been reached.
-* @param trigger_threshold - the threshold
-* @param silent - is true, now outputs are made. If false, dbprints the status
-*/
-void DoAcquisition125k_internal(int trigger_threshold,bool silent)
-{
-	uint8_t *dest = (uint8_t *)BigBuf;
-	int n = sizeof(BigBuf);
-	int i;
-
-	memset(dest, 0, n);
-	i = 0;
-	for(;;) {
-		if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
-			AT91C_BASE_SSC->SSC_THR = 0x43;
-			LED_D_ON();
-		}
-		if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
-			dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-			LED_D_OFF();
-			if (trigger_threshold != -1 && dest[i] < trigger_threshold)
-				continue;
-			else
-				trigger_threshold = -1;
-			if (++i >= n) break;
-		}
-	}
-	if(!silent)
-	{
-		Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
-		    dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
-
-	}
-}
-/**
-* Perform sample aquisition.
-*/
-void DoAcquisition125k(int trigger_threshold)
-{
-	DoAcquisition125k_internal(trigger_threshold, false);
-}
-
-/**
-* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
-* if not already loaded, sets divisor and starts up the antenna.
-* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz
-* 				   0 or 95 ==> 125 KHz
-*
-**/
-void LFSetupFPGAForADC(int divisor, bool lf_field)
-{
-	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-	if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
-		FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-	else if (divisor == 0)
-		FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-	else
-		FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
-
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
-
-	// Connect the A/D to the peak-detected low-frequency path.
-	SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
-	// Give it a bit of time for the resonant antenna to settle.
-	SpinDelay(50);
-	// Now set up the SSC to get the ADC samples that are now streaming at us.
-	FpgaSetupSsc();
-}
-/**
-* Initializes the FPGA, and acquires the samples.
-**/
-void AcquireRawAdcSamples125k(int divisor)
-{
-	LFSetupFPGAForADC(divisor, true);
-	// Now call the acquisition routine
-	DoAcquisition125k_internal(-1,false);
-}
-/**
-* Initializes the FPGA for snoop-mode, and acquires the samples.
-**/
-
-void SnoopLFRawAdcSamples(int divisor, int trigger_threshold)
-{
-	LFSetupFPGAForADC(divisor, false);
-	DoAcquisition125k(trigger_threshold);
-}
-
+ * Function to do a modulation and then get samples.
+ * @param delay_off
+ * @param period_0
+ * @param period_1
+ * @param command
+ */
 void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
 {
 
-	/* Make sure the tag is reset */
-	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-	SpinDelay(2500);
-
-
 	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);
 
-	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-	// Give it a bit of time for the resonant antenna to settle.
-	SpinDelay(50);
+	/* Make sure the tag is reset */
+	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+	SpinDelay(2500);
+
+	LFSetupFPGAForADC(sc.divisor, 1);
 
 	// And a little more time for the tag to fully power up
 	SpinDelay(2000);
 
-	// Now set up the SSC to get the ADC samples that are now streaming at us.
-	FpgaSetupSsc();
-
 	// now modulate the reader field
 	while(*command != '\0' && *command != ' ') {
 		FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 		LED_D_OFF();
 		SpinDelayUs(delay_off);
-		FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
+		FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
 
 		FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
 		LED_D_ON();
@@ -150,14 +65,16 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1,
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	LED_D_OFF();
 	SpinDelayUs(delay_off);
-	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used);
+	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
 
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
 
 	// now do the read
-	DoAcquisition125k(-1);
+	DoAcquisition_config(false);
 }
 
+
+
 /* blank r/w tag data stream
 ...0000000000000000 01111111
 1010101010101010101010101010101010101010101010101010101010101010
@@ -177,8 +94,8 @@ void ReadTItag(void)
  #define FREQLO 123200
  #define FREQHI 134200
 
-	signed char *dest = (signed char *)BigBuf;
-	int n = sizeof(BigBuf);
+	signed char *dest = (signed char *)BigBuf_get_addr();
+	uint16_t n = BigBuf_max_traceLen();
 	// 128 bit shift register [shift3:shift2:shift1:shift0]
 	uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0;
 
@@ -288,7 +205,7 @@ void ReadTItag(void)
 		crc = update_crc16(crc, (shift1>>24)&0xff);
 
 		Dbprintf("Info: Tag data: %x%08x, crc=%x",
-		    (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF);
+				 (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF);
 		if (crc != (shift2&0xffff)) {
 			Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc);
 		} else {
@@ -330,7 +247,8 @@ void AcquireTiType(void)
  #define TIBUFLEN 1250
 
 	// clear buffer
-	memset(BigBuf,0,sizeof(BigBuf));
+	uint32_t *BigBuf = (uint32_t *)BigBuf_get_addr();
+	memset(BigBuf,0,BigBuf_max_traceLen()/sizeof(uint32_t));
 
 	// Set up the synchronous serial port
 	AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN;
@@ -378,7 +296,7 @@ void AcquireTiType(void)
 	AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
 	AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT;
 
-	char *dest = (char *)BigBuf;
+	char *dest = (char *)BigBuf_get_addr();
 	n = TIBUFLEN*32;
 	// unpack buffer
 	for (i=TIBUFLEN-1; i>=0; i--) {
@@ -409,7 +327,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
 		crc = update_crc16(crc, (idhi>>24)&0xff);
 	}
 	Dbprintf("Writing to tag: %x%08x, crc=%x",
-	    (unsigned int) idhi, (unsigned int) idlo, crc);
+			(unsigned int) idhi, (unsigned int) idlo, crc);
 
 	// TI tags charge at 134.2Khz
 	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
@@ -467,7 +385,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
 void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
 {
 	int i;
-	uint8_t *tab = (uint8_t *)BigBuf;
+	uint8_t *tab = BigBuf_get_addr();
 
 	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
@@ -477,19 +395,19 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
 	AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
 	AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
 
-#define SHORT_COIL()	LOW(GPIO_SSC_DOUT)
-#define OPEN_COIL()		HIGH(GPIO_SSC_DOUT)
+ #define SHORT_COIL()	LOW(GPIO_SSC_DOUT)
+ #define OPEN_COIL()		HIGH(GPIO_SSC_DOUT)
 
 	i = 0;
 	for(;;) {
+		//wait until SSC_CLK goes HIGH
 		while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
-			if(BUTTON_PRESS()) {
+			if(BUTTON_PRESS() || usb_poll()) {
 				DbpString("Stopped");
 				return;
 			}
 			WDT_HIT();
 		}
-
 		if (ledcontrol)
 			LED_D_ON();
 
@@ -500,7 +418,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
 
 		if (ledcontrol)
 			LED_D_OFF();
-
+		//wait until SSC_CLK goes LOW
 		while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
 			if(BUTTON_PRESS()) {
 				DbpString("Stopped");
@@ -511,6 +429,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
 
 		i++;
 		if(i == period) {
+
 			i = 0;
 			if (gap) {
 				SHORT_COIL();
@@ -525,29 +444,31 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0)
 {
 }
 
-// compose fc/8 fc/10 waveform
-static void fc(int c, int *n) {
-	uint8_t *dest = (uint8_t *)BigBuf;
+// compose fc/8 fc/10 waveform (FSK2)
+static void fc(int c, int *n)
+{
+	uint8_t *dest = BigBuf_get_addr();
 	int idx;
 
 	// for when we want an fc8 pattern every 4 logical bits
 	if(c==0) {
 		dest[((*n)++)]=1;
 		dest[((*n)++)]=1;
-		dest[((*n)++)]=0;
-		dest[((*n)++)]=0;
+		dest[((*n)++)]=1;
+		dest[((*n)++)]=1;
 		dest[((*n)++)]=0;
 		dest[((*n)++)]=0;
 		dest[((*n)++)]=0;
 		dest[((*n)++)]=0;
 	}
-	//	an fc/8  encoded bit is a bit pattern of  11000000  x6 = 48 samples
+
+	//	an fc/8  encoded bit is a bit pattern of  11110000  x6 = 48 samples
 	if(c==8) {
 		for (idx=0; idx<6; idx++) {
 			dest[((*n)++)]=1;
 			dest[((*n)++)]=1;
-			dest[((*n)++)]=0;
-			dest[((*n)++)]=0;
+			dest[((*n)++)]=1;
+			dest[((*n)++)]=1;
 			dest[((*n)++)]=0;
 			dest[((*n)++)]=0;
 			dest[((*n)++)]=0;
@@ -555,14 +476,14 @@ static void fc(int c, int *n) {
 		}
 	}
 
-	//	an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
+	//	an fc/10 encoded bit is a bit pattern of 1111100000 x5 = 50 samples
 	if(c==10) {
 		for (idx=0; idx<5; idx++) {
 			dest[((*n)++)]=1;
 			dest[((*n)++)]=1;
 			dest[((*n)++)]=1;
-			dest[((*n)++)]=0;
-			dest[((*n)++)]=0;
+			dest[((*n)++)]=1;
+			dest[((*n)++)]=1;
 			dest[((*n)++)]=0;
 			dest[((*n)++)]=0;
 			dest[((*n)++)]=0;
@@ -571,6 +492,36 @@ static void fc(int c, int *n) {
 		}
 	}
 }
+// compose fc/X fc/Y waveform (FSKx)
+static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt) 
+{
+	uint8_t *dest = BigBuf_get_addr();
+	uint8_t halfFC = fc/2;
+	uint8_t wavesPerClock = clock/fc;
+	uint8_t mod = clock % fc;    //modifier
+	uint8_t modAdj = fc/mod;     //how often to apply modifier
+	bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk=TRUE;
+	// loop through clock - step field clock
+	for (uint8_t idx=0; idx < wavesPerClock; idx++){
+		// put 1/2 FC length 1's and 1/2 0's per field clock wave (to create the wave)
+		memset(dest+(*n), 0, fc-halfFC);  //in case of odd number use extra here
+		memset(dest+(*n)+(fc-halfFC), 1, halfFC);
+		*n += fc;
+	}
+	if (mod>0) (*modCnt)++;
+	if ((mod>0) && modAdjOk){  //fsk2 
+		if ((*modCnt % modAdj) == 0){ //if 4th 8 length wave in a rf/50 add extra 8 length wave
+			memset(dest+(*n), 0, fc-halfFC);
+			memset(dest+(*n)+(fc-halfFC), 1, halfFC);
+			*n += fc;
+		}
+	}
+	if (mod>0 && !modAdjOk){  //fsk1
+		memset(dest+(*n), 0, mod-(mod/2));
+		memset(dest+(*n)+(mod-(mod/2)), 1, mod/2);
+		*n += mod;
+	}
+}
 
 // prepare a waveform pattern in the buffer based on the ID given then
 // simulate a HID tag until the button is pressed
@@ -588,12 +539,12 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
 	*/
 
 	if (hi>0xFFF) {
-		DbpString("Tags can only have 44 bits.");
+		DbpString("Tags can only have 44 bits. - USE lf simfsk for larger tags");
 		return;
 	}
 	fc(0,&n);
 	// special start of frame marker containing invalid bit sequences
-	fc(8,  &n);	fc(8,  &n);	// invalid
+	fc(8,  &n);	fc(8,  &n); // invalid
 	fc(8,  &n);	fc(10, &n); // logical 0
 	fc(10, &n);	fc(10, &n); // invalid
 	fc(8,  &n);	fc(10, &n); // logical 0
@@ -603,9 +554,9 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
 	for (i=11; i>=0; i--) {
 		if ((i%4)==3) fc(0,&n);
 		if ((hi>>i)&1) {
-			fc(10, &n);	fc(8,  &n);		// low-high transition
+			fc(10, &n); fc(8,  &n);		// low-high transition
 		} else {
-			fc(8,  &n);	fc(10, &n);		// high-low transition
+			fc(8,  &n); fc(10, &n);		// high-low transition
 		}
 	}
 
@@ -614,9 +565,9 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
 	for (i=31; i>=0; i--) {
 		if ((i%4)==3) fc(0,&n);
 		if ((lo>>i)&1) {
-			fc(10, &n);	fc(8,  &n);		// low-high transition
+			fc(10, &n); fc(8,  &n);		// low-high transition
 		} else {
-			fc(8,  &n);	fc(10, &n);		// high-low transition
+			fc(8,  &n); fc(10, &n);		// high-low transition
 		}
 	}
 
@@ -628,14 +579,186 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
 		LED_A_OFF();
 }
 
+// prepare a waveform pattern in the buffer based on the ID given then
+// simulate a FSK tag until the button is pressed
+// arg1 contains fcHigh and fcLow, arg2 contains invert and clock
+void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
+{
+	int ledcontrol=1;
+	int n=0, i=0;
+	uint8_t fcHigh = arg1 >> 8;
+	uint8_t fcLow = arg1 & 0xFF;
+	uint16_t modCnt = 0;
+	uint8_t clk = arg2 & 0xFF;
+	uint8_t invert = (arg2 >> 8) & 1;
+
+	for (i=0; i<size; i++){
+		if (BitStream[i] == invert){
+			fcAll(fcLow, &n, clk, &modCnt);
+		} else {
+			fcAll(fcHigh, &n, clk, &modCnt);
+		}
+	}
+	Dbprintf("Simulating with fcHigh: %d, fcLow: %d, clk: %d, invert: %d, n: %d",fcHigh, fcLow, clk, invert, n);
+	/*Dbprintf("DEBUG: First 32:");
+	uint8_t *dest = BigBuf_get_addr();
+	i=0;
+	Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
+	i+=16;
+	Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
+	*/
+	if (ledcontrol)
+		LED_A_ON();
+
+	SimulateTagLowFrequency(n, 0, ledcontrol);
+
+	if (ledcontrol)
+		LED_A_OFF();
+}
+
+// compose ask waveform for one bit(ASK)
+static void askSimBit(uint8_t c, int *n, uint8_t clock, uint8_t manchester)
+{
+	uint8_t *dest = BigBuf_get_addr();
+	uint8_t halfClk = clock/2;
+	// c = current bit 1 or 0
+	if (manchester==1){
+		memset(dest+(*n), c, halfClk);
+		memset(dest+(*n) + halfClk, c^1, halfClk);
+	} else {
+		memset(dest+(*n), c, clock);
+	}
+	*n += clock;
+}
+
+static void biphaseSimBit(uint8_t c, int *n, uint8_t clock, uint8_t *phase)
+{
+	uint8_t *dest = BigBuf_get_addr();
+	uint8_t halfClk = clock/2;
+	if (c){
+		memset(dest+(*n), c ^ 1 ^ *phase, halfClk);
+		memset(dest+(*n) + halfClk, c ^ *phase, halfClk);
+	} else {
+		memset(dest+(*n), c ^ *phase, clock);
+		*phase ^= 1;
+	}
+
+}
+
+// args clock, ask/man or askraw, invert, transmission separator
+void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
+{
+	int ledcontrol = 1;
+	int n=0, i=0;
+	uint8_t clk = (arg1 >> 8) & 0xFF;
+	uint8_t encoding = arg1 & 0xFF;
+	uint8_t separator = arg2 & 1;
+	uint8_t invert = (arg2 >> 8) & 1;
+
+	if (encoding==2){  //biphase
+		uint8_t phase=0;
+		for (i=0; i<size; i++){
+			biphaseSimBit(BitStream[i]^invert, &n, clk, &phase);
+		}
+		if (BitStream[0]==BitStream[size-1]){ //run a second set inverted to keep phase in check
+			for (i=0; i<size; i++){
+				biphaseSimBit(BitStream[i]^invert, &n, clk, &phase);
+			}
+		}
+	} else {  // ask/manchester || ask/raw
+		for (i=0; i<size; i++){
+			askSimBit(BitStream[i]^invert, &n, clk, encoding);
+		}
+		if (encoding==0 && BitStream[0]==BitStream[size-1]){ //run a second set inverted (for biphase phase)
+			for (i=0; i<size; i++){
+				askSimBit(BitStream[i]^invert^1, &n, clk, encoding);
+			}
+		}
+	}
+	
+	if (separator==1) Dbprintf("sorry but separator option not yet available"); 
+
+	Dbprintf("Simulating with clk: %d, invert: %d, encoding: %d, separator: %d, n: %d",clk, invert, encoding, separator, n);
+	//DEBUG
+	//Dbprintf("First 32:");
+	//uint8_t *dest = BigBuf_get_addr();
+	//i=0;
+	//Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
+	//i+=16;
+	//Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
+
+	if (ledcontrol)
+		LED_A_ON();
+	
+	SimulateTagLowFrequency(n, 0, ledcontrol);
+
+	if (ledcontrol)
+		LED_A_OFF();
+}
+
+//carrier can be 2,4 or 8
+static void pskSimBit(uint8_t waveLen, int *n, uint8_t clk, uint8_t *curPhase, bool phaseChg)
+{
+	uint8_t *dest = BigBuf_get_addr();
+	uint8_t halfWave = waveLen/2;
+	//uint8_t idx;
+	int i = 0;
+	if (phaseChg){
+		// write phase change
+		memset(dest+(*n), *curPhase^1, halfWave);
+		memset(dest+(*n) + halfWave, *curPhase, halfWave);
+		*n += waveLen;
+		*curPhase ^= 1;
+		i += waveLen;
+	}
+	//write each normal clock wave for the clock duration
+	for (; i < clk; i+=waveLen){
+		memset(dest+(*n), *curPhase, halfWave);
+		memset(dest+(*n) + halfWave, *curPhase^1, halfWave);
+		*n += waveLen;
+	}
+}
+
+// args clock, carrier, invert,
+void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
+{
+	int ledcontrol=1;
+	int n=0, i=0;
+	uint8_t clk = arg1 >> 8;
+	uint8_t carrier = arg1 & 0xFF;
+	uint8_t invert = arg2 & 0xFF;
+	uint8_t curPhase = 0;
+	for (i=0; i<size; i++){
+		if (BitStream[i] == curPhase){
+			pskSimBit(carrier, &n, clk, &curPhase, FALSE);
+		} else {
+			pskSimBit(carrier, &n, clk, &curPhase, TRUE);
+		}
+	}
+	Dbprintf("Simulating with Carrier: %d, clk: %d, invert: %d, n: %d",carrier, clk, invert, n);
+	//Dbprintf("DEBUG: First 32:");
+	//uint8_t *dest = BigBuf_get_addr();
+	//i=0;
+	//Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
+	//i+=16;
+	//Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
+		   
+	if (ledcontrol)
+		LED_A_ON();
+	SimulateTagLowFrequency(n, 0, ledcontrol);
+
+	if (ledcontrol)
+		LED_A_OFF();
+}
+
 // loop to get raw HID waveform then FSK demodulate the TAG ID from it
 void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
 {
-	uint8_t *dest = (uint8_t *)BigBuf;
-
-	size_t size=0; //, found=0;
+	uint8_t *dest = BigBuf_get_addr();
+	//const size_t sizeOfBigBuff = BigBuf_max_traceLen();
+	size_t size; 
 	uint32_t hi2=0, hi=0, lo=0;
-
+	int idx=0;
 	// Configure to go in 125Khz listen mode
 	LFSetupFPGAForADC(95, true);
 
@@ -644,19 +767,18 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
 		WDT_HIT();
 		if (ledcontrol) LED_A_ON();
 
-		DoAcquisition125k_internal(-1,true);
+		DoAcquisition_default(-1,true);
 		// FSK demodulator
-		size = HIDdemodFSK(dest, sizeof(BigBuf), &hi2, &hi, &lo);
-
-		WDT_HIT();
-
-		if (size>0 && lo>0){
-			// final loop, go over previously decoded manchester data and decode into usable tag ID
-			// 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
-			if (hi2 != 0){ //extra large HID tags
+		//size = sizeOfBigBuff;  //variable size will change after demod so re initialize it before use
+		size = 50*128*2; //big enough to catch 2 sequences of largest format
+		idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
+		
+		if (idx>0 && lo>0 && (size==96 || size==192)){
+			// go over previously decoded manchester data and decode into usable tag ID
+			if (hi2 != 0){ //extra large HID tags  88/192 bits
 				Dbprintf("TAG ID: %x%08x%08x (%d)",
-				    (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
-			}else {  //standard HID tags <38 bits
+				  (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
+			}else {  //standard HID tags 44/96 bits
 				//Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
 				uint8_t bitlen = 0;
 				uint32_t fc = 0;
@@ -701,16 +823,18 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
 				//Dbprintf("TAG ID: %x%08x (%d)",
 				// (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
 				Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
-				    (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
-				    (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum);
+						 (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
+						 (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum);
 			}
 			if (findone){
 				if (ledcontrol)	LED_A_OFF();
+				*high = hi;
+				*low = lo;
 				return;
 			}
 			// reset
-			hi2 = hi = lo = 0;
 		}
+		hi2 = hi = lo = idx = 0;
 		WDT_HIT();
 	}
 	DbpString("Stopped");
@@ -719,10 +843,11 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
 
 void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
 {
-	uint8_t *dest = (uint8_t *)BigBuf;
+	uint8_t *dest = BigBuf_get_addr();
 
-	size_t size=0;
-	int clk=0, invert=0, errCnt=0;
+	size_t size=0, idx=0;
+	int clk=0, invert=0, errCnt=0, maxErr=20;
+	uint32_t hi=0;
 	uint64_t lo=0;
 	// Configure to go in 125Khz listen mode
 	LFSetupFPGAForADC(95, true);
@@ -732,38 +857,44 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
 		WDT_HIT();
 		if (ledcontrol) LED_A_ON();
 
-		DoAcquisition125k_internal(-1,true);
-		size = sizeof(BigBuf);
-		//Dbprintf("DEBUG: Buffer got");
+		DoAcquisition_default(-1,true);
+		size  = BigBuf_max_traceLen();
 		//askdemod and manchester decode
-		errCnt = askmandemod(dest, &size, &clk, &invert);
-		//Dbprintf("DEBUG: ASK Got");
+		if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format
+		errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1);
 		WDT_HIT();
 
-		if (errCnt>=0){
-			lo = Em410xDecode(dest,size);
-			//Dbprintf("DEBUG: EM GOT");
-			if (lo>0){
+		if (errCnt<0) continue;
+	
+		errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
+		if (errCnt){
+			if (size>64){
+				Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
+				  hi,
+				  (uint32_t)(lo>>32),
+				  (uint32_t)lo,
+				  (uint32_t)(lo&0xFFFF),
+				  (uint32_t)((lo>>16LL) & 0xFF),
+				  (uint32_t)(lo & 0xFFFFFF));
+			} else {
 				Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
-				    (uint32_t)(lo>>32),
-				    (uint32_t)lo,
-				    (uint32_t)(lo&0xFFFF),
-				    (uint32_t)((lo>>16LL) & 0xFF),
-				    (uint32_t)(lo & 0xFFFFFF));
+				  (uint32_t)(lo>>32),
+				  (uint32_t)lo,
+				  (uint32_t)(lo&0xFFFF),
+				  (uint32_t)((lo>>16LL) & 0xFF),
+				  (uint32_t)(lo & 0xFFFFFF));
 			}
+
 			if (findone){
-				if (ledcontrol)	LED_A_OFF();
+				if (ledcontrol) LED_A_OFF();
+				*high=lo>>32;
+				*low=lo & 0xFFFFFFFF;
 				return;
 			}
-		} else{
-			//Dbprintf("DEBUG: No Tag");
 		}
 		WDT_HIT();
-		lo = 0;
-		clk=0;
-		invert=0;
-		errCnt=0;
-		size=0;
+		hi = lo = size = idx = 0;
+		clk = invert = errCnt = 0;
 	}
 	DbpString("Stopped");
 	if (ledcontrol) LED_A_OFF();
@@ -771,7 +902,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
 
 void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
 {
-	uint8_t *dest = (uint8_t *)BigBuf;
+	uint8_t *dest = BigBuf_get_addr();
 	int idx=0;
 	uint32_t code=0, code2=0;
 	uint8_t version=0;
@@ -783,49 +914,51 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
 	while(!BUTTON_PRESS()) {
 		WDT_HIT();
 		if (ledcontrol) LED_A_ON();
-		DoAcquisition125k_internal(-1,true);
+		DoAcquisition_default(-1,true);
 		//fskdemod and get start index
 		WDT_HIT();
-		idx = IOdemodFSK(dest,sizeof(BigBuf));
-		if (idx>0){
-			//valid tag found
-
-			//Index map
-			//0           10          20          30          40          50          60
-			//|           |           |           |           |           |           |
-			//01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
-			//-----------------------------------------------------------------------------
-			//00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
-			//
-			//XSF(version)facility:codeone+codetwo
-			//Handle the data
-			if(findone){ //only print binary if we are doing one
-				Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx],   dest[idx+1],   dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
-				Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
-				Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
-				Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
-				Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
-				Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
-				Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
-			}
-			code = bytebits_to_byte(dest+idx,32);
-			code2 = bytebits_to_byte(dest+idx+32,32);
-			version = bytebits_to_byte(dest+idx+27,8); //14,4
-			facilitycode = bytebits_to_byte(dest+idx+18,8) ;
-			number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
-
-			Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
-			// if we're only looking for one tag
-			if (findone){
-				if (ledcontrol)	LED_A_OFF();
-				//LED_A_OFF();
-				return;
-			}
-			code=code2=0;
-			version=facilitycode=0;
-			number=0;
-			idx=0;
+		idx = IOdemodFSK(dest, BigBuf_max_traceLen());
+		if (idx<0) continue;
+		//valid tag found
+
+		//Index map
+		//0           10          20          30          40          50          60
+		//|           |           |           |           |           |           |
+		//01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
+		//-----------------------------------------------------------------------------
+		//00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
+		//
+		//XSF(version)facility:codeone+codetwo
+		//Handle the data
+		if(findone){ //only print binary if we are doing one
+			Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx],   dest[idx+1],   dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7],dest[idx+8]);
+			Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
+			Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
+			Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
+			Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
+			Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
+			Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
+		}
+		code = bytebits_to_byte(dest+idx,32);
+		code2 = bytebits_to_byte(dest+idx+32,32);
+		version = bytebits_to_byte(dest+idx+27,8); //14,4
+		facilitycode = bytebits_to_byte(dest+idx+18,8);
+		number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
+
+		Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
+		// if we're only looking for one tag
+		if (findone){
+			if (ledcontrol)	LED_A_OFF();
+			//LED_A_OFF();
+			*high=code;
+			*low=code2;
+			return;
 		}
+		code=code2=0;
+		version=facilitycode=0;
+		number=0;
+		idx=0;
+
 		WDT_HIT();
 	}
 	DbpString("Stopped");
@@ -891,10 +1024,12 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
  * To compensate antenna falling times shorten the write times
  * and enlarge the gap ones.
  */
-#define START_GAP 250
-#define WRITE_GAP 160
-#define WRITE_0   144 // 192
-#define WRITE_1   400 // 432 for T55x7; 448 for E5550
+#define START_GAP 31*8 // was 250 // SPEC:  1*8 to 50*8 - typ 15*8 (or 15fc)
+#define WRITE_GAP 20*8 // was 160 // SPEC:  1*8 to 20*8 - typ 10*8 (or 10fc)
+#define WRITE_0   18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
+#define WRITE_1   50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc)  432 for T55x7; 448 for E5550
+
+#define T55xx_SAMPLES_SIZE      12000 // 32 x 32 x 10  (32 bit times numofblock (7), times clock skip..)
 
 // Write one bit to card
 void T55xxWriteBit(int bit)
@@ -913,16 +1048,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)
 {
-	//unsigned int i;  //enio adjustment 12/10/14
-	uint32_t i;
+	uint32_t i = 0;
 
-	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
-	// 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);
@@ -955,30 +1085,28 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 }
 
+void TurnReadLFOn(){
+	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+	// Give it a bit of time for the resonant antenna to settle.
+	SpinDelayUs(8*150);
+}
+
+
 // Read one card block in page 0
 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
 {
-	uint8_t *dest = (uint8_t *)BigBuf;
-	//int m=0, i=0; //enio adjustment 12/10/14
-	uint32_t m=0, i=0;
-	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-	m = sizeof(BigBuf);
-	// Clear destination buffer before sending the command
-	memset(dest, 128, m);
-	// Connect the A/D to the peak-detected low-frequency path.
-	SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
-	// Now set up the SSC to get the ADC samples that are now streaming at us.
-	FpgaSetupSsc();
-
-	LED_D_ON();
-	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+	uint32_t i = 0;
+	uint8_t *dest = BigBuf_get_addr();
+	uint16_t bufferlength = BigBuf_max_traceLen();
+	if ( bufferlength > T55xx_SAMPLES_SIZE )
+		bufferlength = T55xx_SAMPLES_SIZE;
 
-	// Give it a bit of time for the resonant antenna to settle.
-	// And for the tag to fully power up
-	SpinDelay(150);
+	// Clear destination buffer before sending the command
+	memset(dest, 0x80, bufferlength);
 
-	// Now start writting
+	// Set up FPGA, 125kHz
+	// Wait for config.. (192+8190xPOW)x8 == 67ms
+	LFSetupFPGAForADC(0, true);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	SpinDelayUs(START_GAP);
 
@@ -997,53 +1125,40 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
 		T55xxWriteBit(Block & i);
 
 	// Turn field on to read the response
-	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
+	TurnReadLFOn();
 	// Now do the acquisition
 	i = 0;
 	for(;;) {
 		if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
 			AT91C_BASE_SSC->SSC_THR = 0x43;
+			LED_D_ON();
 		}
 		if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
 			dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-			// we don't care about actual value, only if it's more or less than a
-			// threshold essentially we capture zero crossings for later analysis
-			//			if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
 			i++;
-			if (i >= m) break;
+			LED_D_OFF();
+			if (i >= bufferlength) break;
 		}
 	}
 
+	cmd_send(CMD_ACK,0,0,0,0,0);    
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
 	LED_D_OFF();
-	DbpString("DONE!");
 }
 
 // Read card traceability data (page 1)
 void T55xxReadTrace(void){
-	uint8_t *dest = (uint8_t *)BigBuf;
-	int m=0, i=0;
+	
+	uint32_t i = 0;
+	uint8_t *dest = BigBuf_get_addr();
+	uint16_t bufferlength = BigBuf_max_traceLen();
+	if ( bufferlength > T55xx_SAMPLES_SIZE )
+		bufferlength= T55xx_SAMPLES_SIZE;
 
-	FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-	m = sizeof(BigBuf);
 	// Clear destination buffer before sending the command
-	memset(dest, 128, m);
-	// Connect the A/D to the peak-detected low-frequency path.
-	SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
-	// Now set up the SSC to get the ADC samples that are now streaming at us.
-	FpgaSetupSsc();
-
-	LED_D_ON();
-	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+	memset(dest, 0x80, bufferlength);
 
-	// Give it a bit of time for the resonant antenna to settle.
-	// And for the tag to fully power up
-	SpinDelay(150);
-
-	// Now start writting
+	LFSetupFPGAForADC(0, true);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
 	SpinDelayUs(START_GAP);
 
@@ -1052,25 +1167,26 @@ void T55xxReadTrace(void){
 	T55xxWriteBit(1); //Page 1
 
 	// Turn field on to read the response
-	FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-	FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+	TurnReadLFOn();
 
 	// Now do the acquisition
-	i = 0;
 	for(;;) {
 		if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
 			AT91C_BASE_SSC->SSC_THR = 0x43;
+			LED_D_ON();
 		}
 		if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
 			dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
 			i++;
-			if (i >= m) break;
+			LED_D_OFF();
+
+			if (i >= bufferlength) break;
 		}
 	}
 
+	cmd_send(CMD_ACK,0,0,0,0,0);
 	FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
 	LED_D_OFF();
-	DbpString("DONE!");
 }
 
 /*-------------- Cloning routines -----------*/
@@ -1291,39 +1407,39 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo)
 		Dbprintf("Clock rate: %d", clock);
 		switch (clock)
 		{
-			case 32:
-				clock = T55x7_BITRATE_RF_32;
-				break;
-			case 16:
-				clock = T55x7_BITRATE_RF_16;
-				break;
-			case 0:
-				// A value of 0 is assumed to be 64 for backwards-compatibility
-				// Fall through...
-			case 64:
-				clock = T55x7_BITRATE_RF_64;
-				break;
-			default:
-				Dbprintf("Invalid clock rate: %d", clock);
-				return;
+		case 32:
+			clock = T55x7_BITRATE_RF_32;
+			break;
+		case 16:
+			clock = T55x7_BITRATE_RF_16;
+			break;
+		case 0:
+			// A value of 0 is assumed to be 64 for backwards-compatibility
+			// Fall through...
+		case 64:
+			clock = T55x7_BITRATE_RF_64;
+			break;
+		default:
+			Dbprintf("Invalid clock rate: %d", clock);
+			return;
 		}
 
 		// Writing configuration for T55x7 tag
 		T55xxWriteBlock(clock	    |
-		    T55x7_MODULATION_MANCHESTER |
-		    2 << T55x7_MAXBLOCK_SHIFT,
-		    0, 0, 0);
+						T55x7_MODULATION_MANCHESTER |
+						2 << T55x7_MAXBLOCK_SHIFT,
+						0, 0, 0);
 	}
 	else
 		// Writing configuration for T5555(Q5) tag
 		T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT |
-		    T5555_MODULATION_MANCHESTER   |
-		    2 << T5555_MAXBLOCK_SHIFT,
-		    0, 0, 0);
+						T5555_MODULATION_MANCHESTER |
+						2 << T5555_MAXBLOCK_SHIFT,
+						0, 0, 0);
 
 	LED_D_OFF();
 	Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555",
-	    (uint32_t)(id >> 32), (uint32_t)id);
+			 (uint32_t)(id >> 32), (uint32_t)id);
 }
 
 // Clone Indala 64-bit tag by UID to T55x7
@@ -1336,9 +1452,9 @@ void CopyIndala64toT55x7(int hi, int lo)
 	T55xxWriteBlock(lo,2,0,0);
 	//Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2)
 	T55xxWriteBlock(T55x7_BITRATE_RF_32    |
-	    T55x7_MODULATION_PSK1 |
-	    2 << T55x7_MAXBLOCK_SHIFT,
-	    0, 0, 0);
+					T55x7_MODULATION_PSK1 |
+					2 << T55x7_MAXBLOCK_SHIFT,
+					0, 0, 0);
 	//Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
 	//	T5567WriteBlock(0x603E1042,0);
 
@@ -1360,9 +1476,9 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int
 	T55xxWriteBlock(uid7,7,0,0);
 	//Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7)
 	T55xxWriteBlock(T55x7_BITRATE_RF_32    |
-	    T55x7_MODULATION_PSK1 |
-	    7 << T55x7_MAXBLOCK_SHIFT,
-	    0,0,0);
+					T55x7_MODULATION_PSK1 |
+					7 << T55x7_MAXBLOCK_SHIFT,
+					0,0,0);
 	//Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data)
 	//	T5567WriteBlock(0x603E10E2,0);
 
@@ -1377,8 +1493,8 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int
 int DemodPCF7931(uint8_t **outBlocks) {
 	uint8_t BitStream[256];
 	uint8_t Blocks[8][16];
-	uint8_t *GraphBuffer = (uint8_t *)BigBuf;
-	int GraphTraceLen = sizeof(BigBuf);
+	uint8_t *GraphBuffer = BigBuf_get_addr();
+	int GraphTraceLen = BigBuf_max_traceLen();
 	int i, j, lastval, bitidx, half_switch;
 	int clock = 64;
 	int tolerance = clock / 8;
@@ -1388,7 +1504,9 @@ int DemodPCF7931(uint8_t **outBlocks) {
 	int lmin=128, lmax=128;
 	uint8_t dir;
 
-	AcquireRawAdcSamples125k(0);
+	LFSetupFPGAForADC(95, true);
+	DoAcquisition_default(0, 0);
+
 
 	lmin = 64;
 	lmax = 192;
@@ -1471,13 +1589,13 @@ int DemodPCF7931(uint8_t **outBlocks) {
 				if(bitidx == 128) {
 					for(j=0; j<16; j++) {
 						Blocks[num_blocks][j] = 128*BitStream[j*8+7]+
-						    64*BitStream[j*8+6]+
-						    32*BitStream[j*8+5]+
-						    16*BitStream[j*8+4]+
-						    8*BitStream[j*8+3]+
-						    4*BitStream[j*8+2]+
-						    2*BitStream[j*8+1]+
-						    BitStream[j*8];
+								64*BitStream[j*8+6]+
+								32*BitStream[j*8+5]+
+								16*BitStream[j*8+4]+
+								8*BitStream[j*8+3]+
+								4*BitStream[j*8+2]+
+								2*BitStream[j*8+1]+
+								BitStream[j*8];
 					}
 					num_blocks++;
 				}
@@ -1549,8 +1667,8 @@ void ReadPCF7931() {
 
 		for(i=0; i<n; i++)
 			Dbprintf("(dbg) %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
-			    tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
-			    tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
+					 tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
+					tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
 		if(!ident) {
 			for(i=0; i<n; i++) {
 				if(IsBlock0PCF7931(tmpBlocks[i])) {
@@ -1615,15 +1733,15 @@ void ReadPCF7931() {
 		tries++;
 		if (BUTTON_PRESS()) return;
 	} while (num_blocks != max_blocks);
-end:
+ end:
 	Dbprintf("-----------------------------------------");
 	Dbprintf("Memory content:");
 	Dbprintf("-----------------------------------------");
 	for(i=0; i<max_blocks; i++) {
 		if(Blocks[i][ALLOC]==1)
 			Dbprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
-			    Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
-			    Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
+					 Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
+					Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
 		else
 			Dbprintf("<missing block %d>", i);
 	}
@@ -1795,7 +1913,7 @@ void EM4xLogin(uint32_t Password) {
 void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
 
 	uint8_t fwd_bit_count;
-	uint8_t *dest = (uint8_t *)BigBuf;
+	uint8_t *dest = BigBuf_get_addr();
 	int m=0, i=0;
 
 	//If password mode do login
@@ -1805,7 +1923,7 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
 	fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
 	fwd_bit_count += Prepare_Addr( Address );
 
-	m = sizeof(BigBuf);
+	m = BigBuf_max_traceLen();
 	// Clear destination buffer before sending the command
 	memset(dest, 128, m);
 	// Connect the A/D to the peak-detected low-frequency path.