From cc15a1187b698d185a42fe956c0b68b9384eafdd Mon Sep 17 00:00:00 2001 From: marshmellow42 Date: Mon, 6 Apr 2015 23:17:30 -0400 Subject: [PATCH] lf cleanup - fixes more lf em em4x50read fixes adjust heavy clipping ask clock detection clean up t55xx minor items --- client/cmddata.c | 2 +- client/cmdlfem4x.c | 130 ++++++++++++++++++++-------------------- client/cmdlft55xx.c | 14 ++--- common/lfdemod.c | 142 ++++++++++++++++++++------------------------ common/lfdemod.h | 3 +- 5 files changed, 142 insertions(+), 149 deletions(-) diff --git a/client/cmddata.c b/client/cmddata.c index d4fc997b..18b59f21 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -2020,7 +2020,7 @@ int CmdLoad(const char *Cmd) int CmdLtrim(const char *Cmd) { int ds = atoi(Cmd); - + if (GraphTraceLen<=0) return 0; for (int i = ds; i < GraphTraceLen; ++i) GraphBuffer[i-ds] = GraphBuffer[i]; GraphTraceLen -= ds; diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 552c256e..e45c788a 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -27,7 +27,7 @@ static int CmdHelp(const char *Cmd); int CmdEMdemodASK(const char *Cmd) { char cmdp = param_getchar(Cmd, 0); - int findone = (cmdp == '1') ? 1 : 0; + int findone = (cmdp == '1') ? 1 : 0; UsbCommand c={CMD_EM410X_DEMOD}; c.arg[0]=findone; SendCommand(&c); @@ -237,7 +237,7 @@ bool EM_EndParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t col { if (rows*cols>size) return false; uint8_t colP=0; - //assume last row is a parity row and do not test + //assume last col is a parity and do not test for (uint8_t colNum = 0; colNum < cols-1; colNum++) { for (uint8_t rowNum = 0; rowNum < rows; rowNum++) { colP ^= BitStream[(rowNum*cols)+colNum]; @@ -270,7 +270,7 @@ uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool code = code<<8 | bytebits_to_byte(BitStream+27,8); if (verbose || g_debugMode){ for (uint8_t i = 0; i<5; i++){ - if (i == 4) PrintAndLog(""); + if (i == 4) PrintAndLog(""); //parity byte spacer PrintAndLog("%d%d%d%d%d%d%d%d %d -> 0x%02x", BitStream[i*9], BitStream[i*9+1], @@ -289,7 +289,6 @@ uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool else PrintAndLog("Parity Failed"); } - //PrintAndLog("Code: %08x",code); return code; } /* Read the transmitted data of an EM4x50 tag @@ -311,95 +310,103 @@ uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool * is stored in the blocks defined in the control word First and Last * Word Read values. UID is stored in block 32. */ + //completed by Marshmellow int EM4x50Read(const char *Cmd, bool verbose) { - uint8_t fndClk[]={0,8,16,32,40,50,64}; + uint8_t fndClk[] = {8,16,32,40,50,64,128}; int clk = 0; int invert = 0; - sscanf(Cmd, "%i %i", &clk, &invert); int tol = 0; int i, j, startblock, skip, block, start, end, low, high, minClk; - bool complete= false; + bool complete = false; int tmpbuff[MAX_GRAPH_TRACE_LEN / 64]; - save_restoreGB(1); uint32_t Code[6]; char tmp[6]; - char tmp2[20]; - high= low= 0; + high = low = 0; memset(tmpbuff, 0, MAX_GRAPH_TRACE_LEN / 64); - + + // get user entry if any + sscanf(Cmd, "%i %i", &clk, &invert); + + // save GraphBuffer - to restore it later + save_restoreGB(1); + // first get high and low values - for (i = 0; i < GraphTraceLen; i++) - { + for (i = 0; i < GraphTraceLen; i++) { if (GraphBuffer[i] > high) high = GraphBuffer[i]; else if (GraphBuffer[i] < low) low = GraphBuffer[i]; } - // populate a buffer with pulse lengths - i= 0; - j= 0; - minClk= 255; - while (i < GraphTraceLen) - { + i = 0; + j = 0; + minClk = 255; + // get to first full low to prime loop and skip incomplete first pulse + while ((GraphBuffer[i] < high) && (i < GraphTraceLen)) + ++i; + while ((GraphBuffer[i] > low) && (i < GraphTraceLen)) + ++i; + skip = i; + + // populate tmpbuff buffer with pulse lengths + while (i < GraphTraceLen) { // measure from low to low - while ((GraphBuffer[i] > low) && (i low) && (i < GraphTraceLen)) ++i; start= i; - while ((GraphBuffer[i] < high) && (i low) && (i low) && (i < GraphTraceLen)) ++i; if (j>=(MAX_GRAPH_TRACE_LEN/64)) { break; } tmpbuff[j++]= i - start; - if (i-start < minClk) minClk = i-start; + if (i-start < minClk && i < GraphTraceLen) { + minClk = i - start; + } } // set clock - if (!clk){ + if (!clk) { for (uint8_t clkCnt = 0; clkCnt<7; clkCnt++) { tol = fndClk[clkCnt]/8; - if (fndClk[clkCnt]-tol >= minClk) { + if (minClk >= fndClk[clkCnt]-tol && minClk <= fndClk[clkCnt]+1) { clk=fndClk[clkCnt]; break; } } + if (!clk) return 0; } else tol = clk/8; // look for data start - should be 2 pairs of LW (pulses of clk*3,clk*2) - start= -1; - skip= 0; - for (i= 0; i < j - 4 ; ++i) - { + start = -1; + for (i= 0; i < j - 4 ; ++i) { skip += tmpbuff[i]; - if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) - if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) - if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) - if (tmpbuff[i+3] >= clk-tol) + if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) //3 clocks + if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) //2 clocks + if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) //3 clocks + if (tmpbuff[i+3] >= clk-tol) //1.5 to 2 clocks - depends on bit following { start= i + 4; break; } } - startblock= i + 4; + startblock = i + 4; // skip over the remainder of LW skip += tmpbuff[i+1] + tmpbuff[i+2] + clk + clk/8; - int phaseoff = tmpbuff[i+3]-clk; // now do it again to find the end end = skip; - for (i += 3; i < j - 4 ; ++i) - { + for (i += 3; i < j - 4 ; ++i) { end += tmpbuff[i]; - if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3 + tol) - if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2 + tol) - if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3 + tol) - if (tmpbuff[i+3] >= clk-tol) + if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) //3 clocks + if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol) //2 clocks + if (tmpbuff[i+2] >= clk*3-tol && tmpbuff[i+2] <= clk*3+tol) //3 clocks + if (tmpbuff[i+3] >= clk-tol) //1.5 to 2 clocks - depends on bit following { complete= true; break; @@ -409,15 +416,11 @@ int EM4x50Read(const char *Cmd, bool verbose) // report back if (verbose || g_debugMode) { if (start >= 0) { - PrintAndLog("\nNote: should print 45 bits then 0177 (end of block)"); - PrintAndLog(" for each block"); - PrintAndLog(" Also, sometimes the demod gets out of sync and "); - PrintAndLog(" inverts the output - when this happens the 0177"); - PrintAndLog(" will be 3 extra 1's at the end"); - PrintAndLog(" 'data askedge' command may fix that"); + PrintAndLog("\nNote: one block = 50 bits (32 data, 12 parity, 6 marker)"); } else { - PrintAndLog("No data found!"); + PrintAndLog("No data found!, clock tried:%d",clk); PrintAndLog("Try again with more samples."); + PrintAndLog(" or after a 'data askedge' command to clean up the read"); return 0; } if (!complete) @@ -427,24 +430,22 @@ int EM4x50Read(const char *Cmd, bool verbose) PrintAndLog("Try again with more samples."); } } else if (start < 0) return 0; - start=skip; + start = skip; snprintf(tmp2, sizeof(tmp2),"%d %d 1000 %d", clk, invert, clk*47); // get rid of leading crap - snprintf(tmp, sizeof(tmp),"%i",skip); + snprintf(tmp, sizeof(tmp), "%i", skip); CmdLtrim(tmp); bool pTest; - bool AllPTest=true; + bool AllPTest = true; // now work through remaining buffer printing out data blocks block = 0; i = startblock; - while (block < 6) - { + while (block < 6) { if (verbose || g_debugMode) PrintAndLog("\nBlock %i:", block); skip = phaseoff; // look for LW before start of next block - for ( ; i < j - 4 ; ++i) - { + for ( ; i < j - 4 ; ++i) { skip += tmpbuff[i]; if (tmpbuff[i] >= clk*3-tol && tmpbuff[i] <= clk*3+tol) if (tmpbuff[i+1] >= clk-tol) @@ -453,7 +454,10 @@ int EM4x50Read(const char *Cmd, bool verbose) skip += clk; phaseoff = tmpbuff[i+1]-clk; i += 2; - if (ASKmanDemod(tmp2, false, false)<1) return 0; + if (ASKmanDemod(tmp2, false, false) < 1) { + save_restoreGB(0); + return 0; + } //set DemodBufferLen to just one block DemodBufferLen = skip/clk; //test parities @@ -461,26 +465,26 @@ int EM4x50Read(const char *Cmd, bool verbose) pTest &= EM_EndParityTest(DemodBuffer,DemodBufferLen,5,9,0); AllPTest &= pTest; //get output - Code[block]=OutputEM4x50_Block(DemodBuffer,DemodBufferLen,verbose, pTest); - if (g_debugMode) PrintAndLog("\nskipping %d samples, bits:%d",start, skip/clk); + Code[block] = OutputEM4x50_Block(DemodBuffer,DemodBufferLen,verbose, pTest); + if (g_debugMode) PrintAndLog("\nskipping %d samples, bits:%d", skip, skip/clk); //skip to start of next block snprintf(tmp,sizeof(tmp),"%i",skip); CmdLtrim(tmp); block++; - if (i>=end) break; //in case chip doesn't output 6 blocks + if (i >= end) break; //in case chip doesn't output 6 blocks } //print full code: if (verbose || g_debugMode || AllPTest){ - PrintAndLog("Found data at sample: %i - using clock: %i",skip,clk); - //PrintAndLog("\nSummary:"); - end=block; - for (block=0; block= high && waveHigh){ smplCnt++; @@ -360,7 +359,7 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max lastBit = start - *clk; for (i = start; i < *size; ++i) { - if (i - lastBit > *clk){ + if (i - lastBit == *clk){ if (BinStream[i] >= high) { BinStream[bitnum++] = *invert; } else if (BinStream[i] <= low) { @@ -373,13 +372,12 @@ int askrawdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int max } midBit = 0; lastBit += *clk; - } else if (i-lastBit > (*clk/2) && midBit == 0){ + } 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++; } @@ -687,11 +685,11 @@ int PyramiddemodFSK(uint8_t *dest, size_t *size) } -uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low) +uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, uint8_t low) { uint16_t allPeaks=1; uint16_t cntPeaks=0; - size_t loopEnd = 572; + size_t loopEnd = 512+60; if (loopEnd > size) loopEnd = size; for (size_t i=60; ilow && dest[i]128) { - if (!high){ - high=1; - if (cnt > highCnt){ - if (highCnt != 0) highCnt2 = highCnt; - highCnt = cnt; - } else if (cnt > highCnt2) { - highCnt2 = cnt; - } - cnt=1; - } else { - cnt++; - } - } else if (dest[idx] <= 128){ - if (high) { - high=0; - if (cnt > highCnt) { - if (highCnt != 0) highCnt2 = highCnt; - highCnt = cnt; - } else if (cnt > highCnt2) { - highCnt2 = cnt; - } - cnt=1; - } else { - cnt++; - } - } + uint8_t fndClk[] = {8,16,32,40,50,64,128}; + size_t startwave; + size_t i = 0; + size_t minClk = 255; + // get to first full low to prime loop and skip incomplete first pulse + while ((dest[i] < high) && (i < size)) + ++i; + while ((dest[i] > low) && (i < size)) + ++i; + + // loop through all samples + while (i < size) { + // measure from low to low + while ((dest[i] > low) && (i < size)) + ++i; + startwave= i; + while ((dest[i] < high) && (i < size)) + ++i; + while ((dest[i] > low) && (i < size)) + ++i; + //get minimum measured distance + if (i-startwave < minClk && i < size) + minClk = i - startwave; } - uint8_t tol; - for (idx=8; idx>0; idx--){ - tol = clk[idx]/8; - if (clk[idx] >= highCnt - tol && clk[idx] <= highCnt + tol) - return clk[idx]; - if (clk[idx] >= highCnt2 - tol && clk[idx] <= highCnt2 + tol) - return clk[idx]; + // set clock + for (uint8_t clkCnt = 0; clkCnt<7; clkCnt++) { + if (minClk >= fndClk[clkCnt]-(fndClk[clkCnt]/8) && minClk <= fndClk[clkCnt]+1) + return fndClk[clkCnt]; } - return -1; + return 0; } // by marshmellow @@ -763,15 +747,15 @@ int DetectStrongAskClock(uint8_t dest[], size_t size) int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) { size_t i=1; - uint8_t clk[]={255,8,16,32,40,50,64,100,128,255}; + uint8_t clk[] = {255,8,16,32,40,50,64,100,128,255}; + uint8_t clkEnd = 9; uint8_t loopCnt = 255; //don't need to loop through entire array... - if (size==0) return -1; - if (size <= loopCnt) loopCnt = size-1; //not enough samples + if (size <= loopCnt) return -1; //not enough samples //if we already have a valid clock uint8_t clockFnd=0; - for (;i<9;++i) - if (clk[i] == *clock) clockFnd=i; + for (;i1; i--){ - if (clk[i] == ans) { - *clock = ans; - //clockFnd = i; - return 0; // for strong waves i don't use the 'best start position' yet... - //break; //clock found but continue to find best startpos [not yet] + if (!clockFnd){ + if (DetectCleanAskWave(dest, size, peak, low)==1){ + int ans = DetectStrongAskClock(dest, size, peak, low); + for (i=clkEnd-1; i>0; i--){ + if (clk[i] == ans) { + *clock = ans; + //clockFnd = i; + return 0; // for strong waves i don't use the 'best start position' yet... + //break; //clock found but continue to find best startpos [not yet] + } } } } + uint8_t ii; uint8_t clkCnt, tol = 0; uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000}; uint8_t bestStart[]={0,0,0,0,0,0,0,0,0}; size_t errCnt = 0; size_t arrLoc, loopEnd; - //test each valid clock from smallest to greatest to see which lines up - uint8_t clkEnd=9; - if (clockFnd>0) clkEnd=clockFnd+1; - else clockFnd=1; - for(clkCnt=clockFnd; clkCnt < clkEnd; clkCnt++){ + if (clockFnd>0) { + clkCnt = clockFnd; + clkEnd = clockFnd+1; + } + else clkCnt=1; + + //test each valid clock from smallest to greatest to see which lines up + for(; clkCnt < clkEnd; clkCnt++){ if (clk[clkCnt] == 32){ tol=1; }else{ tol=0; } //if no errors allowed - keep start within the first clock - if (!maxErr && size > clk[clkCnt]*3 + tol) loopCnt=clk[clkCnt]*2; + if (!maxErr && size > clk[clkCnt]*2 + tol && clk[clkCnt]<128) loopCnt=clk[clkCnt]*2; bestErr[clkCnt]=1000; //try lining up the peaks by moving starting point (try first few clocks) - for (ii=0; ii < loopCnt-clk[clkCnt]; ii++){ + for (ii=0; ii < loopCnt; ii++){ if (dest[ii] < peak && dest[ii] > low) continue; errCnt=0; @@ -826,11 +816,11 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) errCnt++; } } - //if we found no errors then we can stop here + //if we found no errors then we can stop here and a low clock (common clocks) // this is correct one - return this clock //PrintAndLog("DEBUG: clk %d, err %d, ii %d, i %d",clk[clkCnt],errCnt,ii,i); - if(errCnt==0 && clkCnt<6) { - *clock = clk[clkCnt]; + if(errCnt==0 && clkCnt<7) { + if (!clockFnd) *clock = clk[clkCnt]; return ii; } //if we found errors see if it is lowest so far and save it as best run @@ -840,9 +830,9 @@ int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr) } } } - uint8_t iii=0; + uint8_t iii; uint8_t best=0; - for (iii=0; iii<8; ++iii){ + for (iii=1; iii maxErr) return -1; - *clock = clk[best]; + if (!clockFnd) *clock = clk[best]; return bestStart[best]; } diff --git a/common/lfdemod.h b/common/lfdemod.h index 15121cbf..0a4ceed9 100644 --- a/common/lfdemod.h +++ b/common/lfdemod.h @@ -16,7 +16,8 @@ #include int DetectASKClock(uint8_t dest[], size_t size, int *clock, int maxErr); -uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, int high, int low); +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);