lf improvements
authormarshmellow42 <marshmellowrf@gmail.com>
Tue, 4 Apr 2017 15:52:10 +0000 (11:52 -0400)
committermarshmellow42 <marshmellowrf@gmail.com>
Tue, 4 Apr 2017 15:52:10 +0000 (11:52 -0400)
fix noralsy demod bug (st should be true)
fix sprint_bin_break bug (didn't print last bit)
add a function to save/restore demodbuffer
remove redundant countFC call in PSKDemod
clean up pskclockdetect functions
fix indala26decode bug (end of data sometimes not correct)
improve PSK detection / demodulation
improve NRZ detection
improve t55xx commands & fix a few bugs
add t55xx page1 detection - added it to lf search
added experimental t55xx testmode write

13 files changed:
CHANGELOG.md
armsrc/lfops.c
client/cmddata.c
client/cmddata.h
client/cmdlf.c
client/cmdlfnoralsy.c
client/cmdlft55xx.c
client/cmdlft55xx.h
client/graph.c
client/util.c
common/lfdemod.c
common/lfdemod.h
common/protocols.h

index eb4a62de11ff3f9e79f4b8a93927c1e075867f60..1942605db7273ad88110a29ca92efcf9dd628cac 100644 (file)
@@ -54,6 +54,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 - Added option c to 'hf list' (mark CRC bytes) (piwi)
 
 ### Changed
+- `lf t5 wakeup` has been adjusted to not need the p in front of the pwd arg.
 - `data psknexwatchdemod` has been moved to `lf nexwatch demod` (reads from graphbuffer)
 - `data fskparadoxdemod` has been moved to `lf paradox demod` (reads from graphbuffer)
 - `data fdxdemod` has been moved to `lf fdx demod` (reads from graphbuffer)
index 75aa134240aedffa1eb5b73f4482a76920ef637f..35cf90cad25abd63f8bc60015beb6ef058733e75 100644 (file)
@@ -1096,7 +1096,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
 void TurnReadLFOn(int delay) {
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
        // Give it a bit of time for the resonant antenna to settle.
-       SpinDelayUs(delay); //155*8 //50*8
+       WaitUS(delay); //155*8 //50*8
 }
 
 // Write one bit to card
@@ -1106,7 +1106,7 @@ void T55xxWriteBit(int bit) {
        else
                TurnReadLFOn(WRITE_1);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       SpinDelayUs(WRITE_GAP);
+       WaitUS(WRITE_GAP);
 }
 
 // Send T5577 reset command then read stream (see if we can identify the start of the stream)
@@ -1117,16 +1117,18 @@ void T55xxResetRead(void) {
 
        // Set up FPGA, 125kHz
        LFSetupFPGAForADC(95, true);
-
+       StartTicks();
+       // make sure tag is fully powered up...
+       WaitMS(5);
+       
        // Trigger T55x7 in mode.
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       SpinDelayUs(START_GAP);
+       WaitUS(START_GAP);
 
        // reset tag - op code 00
        T55xxWriteBit(0);
        T55xxWriteBit(0);
 
-       // Turn field on to read the response
        TurnReadLFOn(READ_GAP);
 
        // Acquisition
@@ -1143,18 +1145,22 @@ void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg
        LED_A_ON();
        bool PwdMode = arg & 0x1;
        uint8_t Page = (arg & 0x2)>>1;
+       bool testMode = arg & 0x4;
        uint32_t i = 0;
 
        // Set up FPGA, 125kHz
        LFSetupFPGAForADC(95, true);
-
+       StartTicks();
+       // make sure tag is fully powered up...
+       WaitMS(5);
        // Trigger T55x7 in mode.
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       SpinDelayUs(START_GAP);
+       WaitUS(START_GAP);
 
-       // Opcode 10
-       T55xxWriteBit(1);
-       T55xxWriteBit(Page); //Page 0
+       if (testMode) Dbprintf("TestMODE");
+       // Std Opcode 10
+       T55xxWriteBit(testMode ? 0 : 1);
+       T55xxWriteBit(testMode ? 1 : Page); //Page 0
        if (PwdMode){
                // Send Pwd
                for (i = 0x80000000; i != 0; i >>= 1)
@@ -1173,11 +1179,31 @@ void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg
 
        // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
        // so wait a little more)
-       TurnReadLFOn(20 * 1000);
+
+       // "there is a clock delay before programming" 
+       //  - programming takes ~5.6ms for t5577 ~18ms for E5550
+       //  so we should wait 1 clock + 5.6ms then read response? 
+       //  but we need to know we are dealing with t55x7 vs e5550 (or q5) marshmellow...
+       if (testMode) {
+               // Turn field on to read the response
+               TurnReadLFOn(READ_GAP);
+
+               // Acquisition
+               // Now do the acquisition
+               // Now do the acquisition
+               DoPartialAcquisition(20, true, 12000);
+
+               //doT55x7Acquisition(12000);
+       } else {
+               TurnReadLFOn(20 * 1000);
+       }
                //could attempt to do a read to confirm write took
                // as the tag should repeat back the new block 
                // until it is reset, but to confirm it we would 
-               // need to know the current block 0 config mode
+               // need to know the current block 0 config mode for
+               // modulation clock an other details to demod the response...
+               // response should be (for t55x7) a 0 bit then (ST if on) 
+               // block data written in on repeat until reset. 
 
        // turn field off
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -1206,10 +1232,12 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
 
        // Set up FPGA, 125kHz to power up the tag
        LFSetupFPGAForADC(95, true);
-
+       StartTicks();
+       // make sure tag is fully powered up...
+       WaitMS(5);
        // Trigger T55x7 Direct Access Mode with start gap
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       SpinDelayUs(START_GAP);
+       WaitUS(START_GAP);
 
        // Opcode 1[page]
        T55xxWriteBit(1);
@@ -1229,10 +1257,13 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
                        T55xxWriteBit(Block & i);               
 
        // Turn field on to read the response
-       TurnReadLFOn(READ_GAP);
+       TurnReadLFOn(135*8);
 
        // Acquisition
-       doT55x7Acquisition(12000);
+       // Now do the acquisition
+       DoPartialAcquisition(0, true, 12000);
+
+       //      doT55x7Acquisition(12000);
 
        // Turn the field off
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
@@ -1246,10 +1277,13 @@ void T55xxWakeUp(uint32_t Pwd){
        
        // Set up FPGA, 125kHz
        LFSetupFPGAForADC(95, true);
+       StartTicks();
+       // make sure tag is fully powered up...
+       WaitMS(5);
        
        // Trigger T55x7 Direct Access Mode
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       SpinDelayUs(START_GAP);
+       WaitUS(START_GAP);
        
        // Opcode 10
        T55xxWriteBit(1);
@@ -1367,7 +1401,7 @@ void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t
 // clone viking tag to T55xx
 void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5) {
        uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2};
-       if (Q5) data[0] = ( ((32-2)>>1) << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT;
+       if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT;
        // Program the data blocks for supplied ID and the block 0 config
        WriteT55xx(data, 0, 3);
        LED_D_OFF();
@@ -1451,8 +1485,7 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) {
                }
                data[0] = clock | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT);
        } else { //t5555 (Q5)
-               clock = (clock-2)>>1;  //n = (RF-2)/2
-               data[0] = (clock << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
+               data[0] = T5555_SET_BITRATE(clock) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
        }
 
        WriteT55xx(data, 0, 3);
index 0595dffaa71013f17baf0c41a5953aafe48743ac..b3e23cb6a30e28c77c1792b9231a75dd0e97b981 100644 (file)
@@ -51,6 +51,24 @@ void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx)
        return;
 }
 
+// option '1' to save DemodBuffer any other to restore
+void save_restoreDB(uint8_t saveOpt)
+{
+       static uint8_t SavedDB[MAX_GRAPH_TRACE_LEN];
+       static size_t SavedDBlen;
+       static bool DB_Saved = false;
+
+       if (saveOpt==1) { //save
+               memcpy(SavedDB, DemodBuffer, sizeof(DemodBuffer));
+               SavedDBlen = DemodBufferLen;
+               DB_Saved=true;
+       } else if (DB_Saved){ //restore
+               memcpy(DemodBuffer, SavedDB, sizeof(DemodBuffer));
+               DemodBufferLen = SavedDBlen;
+       }
+       return;
+}
+
 int CmdSetDebugMode(const char *Cmd)
 {
        int demod=0;
@@ -200,6 +218,11 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType,
                CursorCPos = ststart;
                CursorDPos = stend;
                if (verbose || g_debugMode) PrintAndLog("\nFound Sequence Terminator - First one is shown by orange and blue graph markers");
+               //Graph ST trim (for testing)
+               //for (int i = 0; i < BitLen; i++) {
+               //      GraphBuffer[i] = BitStream[i]-128;
+               //}
+               //RepaintGraphWindow();
        }
        int errCnt = askdemod(BitStream, &BitLen, &clk, &invert, maxErr, askamp, askType);
        if (errCnt<0 || BitLen<16){  //if fatal error (or -1)
@@ -818,14 +841,6 @@ int PSKDemod(const char *Cmd, bool verbose)
        uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
        size_t BitLen = getFromGraphBuf(BitStream);
        if (BitLen==0) return 0;
-       uint8_t carrier=countFC(BitStream, BitLen, 0);
-       if (carrier!=2 && carrier!=4 && carrier!=8){
-               //invalid carrier
-               return 0;
-       }
-       if (g_debugMode){
-               PrintAndLog("Carrier: rf/%d",carrier);
-       }
        int errCnt=0;
        errCnt = pskRawDemod(BitStream, &BitLen, &clk, &invert);
        if (errCnt > maxErr){
index e03ab02cb3d171c358c8c9003b1c3c0607086fbc..7e77d3132afda9ef025f4bcd862066e41131605d 100644 (file)
@@ -22,6 +22,7 @@ command_t * CmdDataCommands();
 int CmdData(const char *Cmd);
 void printDemodBuff(void);
 void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
+void save_restoreDB(uint8_t saveOpt);// option '1' to save DemodBuffer any other to restore
 int CmdPrintDemodBuff(const char *Cmd);
 int Cmdaskrawdemod(const char *Cmd);
 int Cmdaskmandemod(const char *Cmd);
@@ -68,6 +69,8 @@ int getSamples(const char *Cmd, bool silent);
 extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
 extern size_t DemodBufferLen;
 extern uint8_t g_debugMode;
+//extern size_t g_demodStartIdx;
+//extern uint8_t g_demodClock;
 #define BIGBUF_SIZE 40000
 
 #endif
index 005aa0e2a48158f0a48a03e4e67b7b367cd9aade..f78b380151d87cdacfe6855765b2dd0e67eab15e 100644 (file)
@@ -863,16 +863,25 @@ int CheckChipType(char cmdp) {
 
        //check for em4x05/em4x69 chips first
        save_restoreGB(1);
+       save_restoreDB(1);
        if ((!offline && (cmdp != '1')) && EM4x05Block0Test(&wordData)) {
                PrintAndLog("\nValid EM4x05/EM4x69 Chip Found\nTry lf em 4x05... commands\n");
                save_restoreGB(0);
+               save_restoreDB(0);
                return 1;
        }
 
        //TODO check for t55xx chip...
 
+       if ((!offline && (cmdp != '1')) && tryDetectP1(true)) {
+               PrintAndLog("\nValid T55xx Chip Found\nTry lf t55xx ... commands\n");
+               save_restoreGB(0);
+               save_restoreDB(0);
+               return 1;               
+       }
        save_restoreGB(0);
-       return 1;
+       save_restoreDB(0);
+       return 0;
 }
 
 //by marshmellow
@@ -924,7 +933,7 @@ int CmdLFfind(const char *Cmd)
                                return 1;
                        }
                        ans=CmdCOTAGRead("");
-                       if (ans>0){
+                       if (ans>0) {
                                PrintAndLog("\nValid COTAG ID Found!");
                                return 1;
                        }
@@ -932,6 +941,8 @@ int CmdLFfind(const char *Cmd)
                return 0;
        }
 
+       // TODO test for modulation then only test formats that use that modulation
+
        ans=CmdFSKdemodIO("");
        if (ans>0) {
                PrintAndLog("\nValid IO Prox ID Found!");
@@ -980,13 +991,13 @@ int CmdLFfind(const char *Cmd)
                return CheckChipType(cmdp);
        }
 
-       ans=CmdFdxDemod("");
+       ans=CmdFdxDemod(""); //biphase
        if (ans>0) {
                PrintAndLog("\nValid FDX-B ID Found!");
                return CheckChipType(cmdp);
        }
 
-       ans=EM4x50Read("", false);
+       ans=EM4x50Read("", false); //ask
        if (ans>0) {
                PrintAndLog("\nValid EM4x50 ID Found!");
                return 1;
@@ -1016,7 +1027,7 @@ int CmdLFfind(const char *Cmd)
                return CheckChipType(cmdp);
        }
 
-       ans=CmdIndalaDecode("");
+       ans=CmdIndalaDecode(""); //psk
        if (ans>0) {
                PrintAndLog("\nValid Indala ID Found!");
                return CheckChipType(cmdp);
@@ -1029,14 +1040,14 @@ int CmdLFfind(const char *Cmd)
        }
 
        PrintAndLog("\nNo Known Tags Found!\n");
-       if (testRaw=='u' || testRaw=='U'){
+       if (testRaw=='u' || testRaw=='U') {
                ans=CheckChipType(cmdp);
                //test unknown tag formats (raw mode)0
                PrintAndLog("\nChecking for Unknown tags:\n");
                ans=AutoCorrelate(4000, false, false);
                if (ans > 0) PrintAndLog("Possible Auto Correlation of %d repeating samples",ans);
                ans=GetFskClock("",false,false); 
-               if (ans != 0){ //fsk
+               if (ans != 0) { //fsk
                        ans=FSKrawDemod("",true);
                        if (ans>0) {
                                PrintAndLog("\nUnknown FSK Modulated Tag Found!");
index db450a4491735e0ead609c0c1ea0fcfebc643f38..b806f29220d3e8a2dc47b2ef7fd63751d62ed997 100644 (file)
@@ -111,7 +111,7 @@ int NoralsyDemod_AM(uint8_t *dest, size_t *size) {
 int CmdNoralsyDemod(const char *Cmd) {
 
        //ASK / Manchester
-       bool st = false;
+       bool st = true;
        if (!ASKDemod_ext("32 0 0", false, false, 1, &st)) {
                if (g_debugMode) PrintAndLog("DEBUG: Error - Noralsy: ASK/Manchester Demod failed");
                return 0;
index b287ce28efec268a710783ee506e159d8d8c7273..72345c9d2a75d708aa2ccd829050d00543795b93 100644 (file)
@@ -24,6 +24,7 @@
 #include "data.h"\r
 #include "lfdemod.h"\r
 #include "cmdhf14a.h" //for getTagInfo\r
+#include "protocols.h"\r
 \r
 #define T55x7_CONFIGURATION_BLOCK 0x00\r
 #define T55x7_PAGE0 0x00\r
@@ -78,12 +79,13 @@ int usage_t55xx_read(){
        return 0;\r
 }\r
 int usage_t55xx_write(){\r
-       PrintAndLog("Usage:  lf t55xx write [b <block>] [d <data>] [p <password>] [1]");\r
+       PrintAndLog("Usage:  lf t55xx write [b <block>] [d <data>] [p <password>] [1] [t]");\r
        PrintAndLog("Options:");\r
        PrintAndLog("     b <block>    - block number to write. Between 0-7");\r
        PrintAndLog("     d <data>     - 4 bytes of data to write (8 hex characters)");\r
        PrintAndLog("     p <password> - OPTIONAL password 4bytes (8 hex characters)");\r
        PrintAndLog("     1            - OPTIONAL write Page 1 instead of Page 0");\r
+       PrintAndLog("     t            - OPTIONAL test mode write - ****DANGER****");   \r
        PrintAndLog("");\r
        PrintAndLog("Examples:");\r
        PrintAndLog("      lf t55xx write b 3 d 11223344            - write 11223344 to block 3");\r
@@ -138,15 +140,28 @@ int usage_t55xx_detect(){
        PrintAndLog("");\r
        return 0;\r
 }\r
+int usage_t55xx_detectP1(){\r
+       PrintAndLog("Usage:  lf t55xx page1detect [1] [p <password>]");\r
+       PrintAndLog("Options:");\r
+       PrintAndLog("     1             - if set, use Graphbuffer otherwise read data from tag.");\r
+       PrintAndLog("     p <password>  - OPTIONAL password (8 hex characters)");\r
+       PrintAndLog("");\r
+       PrintAndLog("Examples:");\r
+       PrintAndLog("      lf t55xx page1detect");\r
+       PrintAndLog("      lf t55xx page1detect 1");\r
+       PrintAndLog("      lf t55xx page1detect p 11223344");\r
+       PrintAndLog("");\r
+       return 0;\r
+}\r
 int usage_t55xx_wakup(){\r
-       PrintAndLog("Usage:  lf t55xx wakeup [h] <password>");\r
+       PrintAndLog("Usage:  lf t55xx wakeup [h] <password>");\r
        PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards.");\r
        PrintAndLog("Options:");\r
        PrintAndLog("     h             - this help");\r
-       PrintAndLog("     p <password>  - password 4bytes (8 hex symbols)");\r
+       PrintAndLog("     <password>  - [required] password 4bytes (8 hex symbols)");\r
        PrintAndLog("");\r
        PrintAndLog("Examples:");\r
-               PrintAndLog("      lf t55xx wakeup 11223344  - send wakeup password");\r
+               PrintAndLog("      lf t55xx wakeup 11223344  - send wakeup password");\r
        return 0;\r
 }\r
 int usage_t55xx_bruteforce(){\r
@@ -490,9 +505,10 @@ bool tryDetectModulation(){
        uint8_t hits = 0;\r
        t55xx_conf_block_t tests[15];\r
        int bitRate=0;\r
-       uint8_t fc1 = 0, fc2 = 0, clk=0;\r
-       if (GetFskClock("", false, false)){ \r
-               fskClocks(&fc1, &fc2, &clk, false);\r
+       uint8_t fc1 = 0, fc2 = 0, ans = 0;\r
+       int clk=0;\r
+       ans = fskClocks(&fc1, &fc2, (uint8_t *)&clk, false);\r
+       if (ans && ((fc1==10 && fc2==8) || (fc1==8 && fc2==5))) {\r
                if ( FSKrawDemod("0 0", false) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {\r
                        tests[hits].modulation = DEMOD_FSK;\r
                        if (fc1==8 && fc2 == 5)\r
@@ -553,8 +569,6 @@ bool tryDetectModulation(){
                                ++hits;\r
                        }\r
                }\r
-               //undo trim from ask\r
-               //save_restoreGB(0);\r
                clk = GetNrzClock("", false, false);\r
                if (clk>0) {\r
                        if ( NRZrawDemod("0 0 1", false)  && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {\r
@@ -576,12 +590,12 @@ bool tryDetectModulation(){
                        }\r
                }\r
                \r
-               // allow undo\r
-               // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)\r
-               save_restoreGB(1);\r
-               CmdLtrim("160");\r
                clk = GetPskClock("", false, false);\r
                if (clk>0) {\r
+                       // allow undo\r
+                       save_restoreGB(1);\r
+                       // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)\r
+                       CmdLtrim("160");\r
                        if ( PSKDemod("0 0 6", false) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {\r
                                tests[hits].modulation = DEMOD_PSK1;\r
                                tests[hits].bitrate = bitRate;\r
@@ -622,9 +636,9 @@ bool tryDetectModulation(){
                                        ++hits;\r
                                }\r
                        } // inverse waves does not affect this demod\r
+                       //undo trim samples\r
+                       save_restoreGB(0);\r
                }\r
-               //undo trim samples\r
-               save_restoreGB(0);\r
        }       \r
        if ( hits == 1) {\r
                config.modulation = tests[0].modulation;\r
@@ -780,9 +794,7 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
                // moved test to here, since this gets most faults first.\r
                if ( resv > 0x00) continue;\r
 \r
-               uint8_t xtRate   = PackBits(si, 3, DemodBuffer); si += 3;     //extended mode part of rate\r
-               int bitRate      = PackBits(si, 3, DemodBuffer); si += 3;     //bit rate\r
-               if (bitRate > 7) continue;\r
+               int bitRate      = PackBits(si, 6, DemodBuffer); si += 6;     //bit rate (includes extended mode part of rate)\r
                uint8_t extend   = PackBits(si, 1, DemodBuffer); si += 1;     //bit 15 extended mode\r
                uint8_t modread  = PackBits(si, 5, DemodBuffer); si += 5+2+1; \r
                //uint8_t pskcr   = PackBits(si, 2, DemodBuffer); si += 2+1;  //could check psk cr\r
@@ -792,12 +804,14 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
                //if extended mode\r
                bool extMode =( (safer == 0x6 || safer == 0x9) && extend) ? true : false;\r
 \r
-               if (!extMode){\r
-                       if (xtRate) continue;  //nml01 || nml02 ||  caused issues on noralys tags\r
+               if (!extMode) {\r
+                       if (bitRate > 7) continue;\r
+                       if (!testBitRate(bitRate, clk)) continue;\r
+               } else { //extended mode bitrate = same function to calc bitrate as em4x05\r
+                       if (EM4x05_GET_BITRATE(bitRate) != clk) continue;\r
                }\r
                //test modulation\r
                if (!testModulation(mode, modread)) continue;\r
-               if (!testBitRate(bitRate, clk)) continue;\r
                *fndBitRate = bitRate;\r
                *offset = idx;\r
                *Q5 = false;\r
@@ -854,7 +868,7 @@ int special(const char *Cmd) {
 int printConfiguration( t55xx_conf_block_t b){\r
        PrintAndLog("Chip Type  : %s", (b.Q5) ? "T5555(Q5)" : "T55x7");\r
        PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );\r
-       PrintAndLog("Bit Rate   : %s", GetBitRateStr(b.bitrate) );\r
+       PrintAndLog("Bit Rate   : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE)) );\r
        PrintAndLog("Inverted   : %s", (b.inverted) ? "Yes" : "No" );\r
        PrintAndLog("Offset     : %d", b.offset);\r
        PrintAndLog("Seq. Term. : %s", (b.ST) ? "Yes" : "No" );\r
@@ -865,26 +879,11 @@ int printConfiguration( t55xx_conf_block_t b){
 \r
 int CmdT55xxWakeUp(const char *Cmd) {\r
        uint32_t password = 0;\r
-       uint8_t cmdp = 0;\r
-       bool errors = true;\r
-       while(param_getchar(Cmd, cmdp) != 0x00) {\r
-               switch(param_getchar(Cmd, cmdp)) {\r
-               case 'h':\r
-               case 'H':\r
-                       return usage_t55xx_wakup();\r
-               case 'p':\r
-               case 'P':\r
-                       password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16);\r
-                       cmdp += 2;\r
-                       errors = false;\r
-                       break;\r
-               default:\r
-                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
-                       errors = true;\r
-                       break;\r
-               }\r
-       }\r
-       if (errors) return usage_t55xx_wakup();\r
+       if ( strlen(Cmd) <= 0 ) return usage_t55xx_wakup();\r
+       char cmdp = param_getchar(Cmd, 0);\r
+       if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_wakup();\r
+\r
+       password = param_get32ex(Cmd, 0, 0, 16);\r
 \r
        UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}};\r
        clearCommandBuffer();\r
@@ -900,6 +899,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
        bool usepwd = false;\r
        bool page1 = false;     \r
        bool gotdata = false;\r
+       bool testMode = false;\r
        bool errors = false;\r
        uint8_t cmdp = 0;\r
        while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {\r
@@ -924,6 +924,11 @@ int CmdT55xxWriteBlock(const char *Cmd) {
                        usepwd = true;\r
                        cmdp += 2;\r
                        break;\r
+               case 't':\r
+               case 'T':\r
+                       testMode = true;\r
+                       cmdp++;\r
+                       break;\r
                case '1':\r
                        page1 = true;\r
                        cmdp++;\r
@@ -944,6 +949,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
        UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};\r
        UsbCommand resp;\r
        c.d.asBytes[0] = (page1) ? 0x2 : 0; \r
+       c.d.asBytes[0] |= (testMode) ? 0x4 : 0; \r
 \r
        char pwdStr[16] = {0};\r
        snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password);\r
@@ -1168,7 +1174,7 @@ int CmdT55xxInfo(const char *Cmd){
        PrintAndLog("-------------------------------------------------------------");\r
        PrintAndLog(" Safer key                 : %s", GetSaferStr(safer));\r
        PrintAndLog(" reserved                  : %d", resv);\r
-       PrintAndLog(" Data bit rate             : %s", GetBitRateStr(dbr));\r
+       PrintAndLog(" Data bit rate             : %s", GetBitRateStr(dbr, extend));\r
        PrintAndLog(" eXtended mode             : %s", (extend) ? "Yes - Warning":"No");\r
        PrintAndLog(" Modulation                : %s", GetModulationStr(datamod));\r
        PrintAndLog(" PSK clock frequency       : %d", pskcf);\r
@@ -1195,7 +1201,7 @@ int CmdT55xxDump(const char *Cmd){
        bool override = false;\r
        if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_dump();\r
 \r
-       bool usepwd = ( strlen(Cmd) > 0);       \r
+       bool usepwd = ( strlen(Cmd) > 0);\r
        if ( usepwd ){\r
                password = param_get32ex(Cmd, 0, 0, 16);\r
                if (param_getchar(Cmd, 1) =='o' )\r
@@ -1234,20 +1240,24 @@ int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
        return 1;\r
 }\r
 \r
-char * GetBitRateStr(uint32_t id) {\r
+char * GetBitRateStr(uint32_t id, bool xmode) {\r
        static char buf[25];\r
 \r
        char *retStr = buf;\r
-       switch (id) {\r
-               case 0:   snprintf(retStr,sizeof(buf),"%d - RF/8",id);   break;\r
-               case 1:   snprintf(retStr,sizeof(buf),"%d - RF/16",id);  break;\r
-               case 2:   snprintf(retStr,sizeof(buf),"%d - RF/32",id);  break;\r
-               case 3:   snprintf(retStr,sizeof(buf),"%d - RF/40",id);  break;\r
-               case 4:   snprintf(retStr,sizeof(buf),"%d - RF/50",id);  break;\r
-               case 5:   snprintf(retStr,sizeof(buf),"%d - RF/64",id);  break;\r
-               case 6:   snprintf(retStr,sizeof(buf),"%d - RF/100",id); break;\r
-               case 7:   snprintf(retStr,sizeof(buf),"%d - RF/128",id); break;\r
-               default:  snprintf(retStr,sizeof(buf),"%d - (Unknown)",id); break;\r
+       if (xmode) { //xmode bitrate calc is same as em4x05 calc\r
+               snprintf(retStr,sizeof(buf),"%d - RF/%d", id, EM4x05_GET_BITRATE(id));\r
+       } else {\r
+               switch (id) {\r
+                       case 0:   snprintf(retStr,sizeof(buf),"%d - RF/8",id);   break;\r
+                       case 1:   snprintf(retStr,sizeof(buf),"%d - RF/16",id);  break;\r
+                       case 2:   snprintf(retStr,sizeof(buf),"%d - RF/32",id);  break;\r
+                       case 3:   snprintf(retStr,sizeof(buf),"%d - RF/40",id);  break;\r
+                       case 4:   snprintf(retStr,sizeof(buf),"%d - RF/50",id);  break;\r
+                       case 5:   snprintf(retStr,sizeof(buf),"%d - RF/64",id);  break;\r
+                       case 6:   snprintf(retStr,sizeof(buf),"%d - RF/100",id); break;\r
+                       case 7:   snprintf(retStr,sizeof(buf),"%d - RF/128",id); break;\r
+                       default:  snprintf(retStr,sizeof(buf),"%d - (Unknown)",id); break;\r
+               }               \r
        }\r
        return buf;\r
 }\r
@@ -1540,11 +1550,160 @@ int CmdT55xxBruteForce(const char *Cmd) {
        return 0;\r
 }\r
 \r
+// note length of data returned is different for different chips.  \r
+//   some return all page 1 (64 bits) and others return just that block (32 bits) \r
+//   unfortunately the 64 bits makes this more likely to get a false positive...\r
+bool tryDetectP1(bool getData) {\r
+       uint8_t preamble[] = {1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,1};\r
+       size_t startIdx = 0;\r
+       uint8_t fc1 = 0, fc2 = 0, ans = 0;\r
+       int clk = 0;\r
+       bool st = true;\r
+\r
+       if ( getData ) {\r
+               if ( !AquireData(T55x7_PAGE1, 1, false, 0) )\r
+                       return false;\r
+       }\r
+\r
+       // try fsk clock detect. if successful it cannot be any other type of modulation...  (in theory...)\r
+       ans = fskClocks(&fc1, &fc2, (uint8_t *)&clk, false);\r
+       if (ans && ((fc1==10 && fc2==8) || (fc1==8 && fc2==5))) {\r
+               if ( FSKrawDemod("0 0", false) && \r
+                         preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                         (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                       return true;\r
+               }\r
+               if ( FSKrawDemod("0 1", false) && \r
+                         preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                         (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                       return true;\r
+               }\r
+               return false;\r
+       }\r
+\r
+       // try psk clock detect. if successful it cannot be any other type of modulation... (in theory...)\r
+       clk = GetPskClock("", false, false);\r
+       if (clk>0) {\r
+               // allow undo\r
+               // save_restoreGB(1);\r
+               // skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)\r
+               //CmdLtrim("160");\r
+               if ( PSKDemod("0 0 6", false) &&\r
+                         preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                         (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                       //save_restoreGB(0);\r
+                       return true;\r
+               }\r
+               if ( PSKDemod("0 1 6", false) &&\r
+                         preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                         (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                       //save_restoreGB(0);\r
+                       return true;\r
+               }\r
+               // PSK2 - needs a call to psk1TOpsk2.\r
+               if ( PSKDemod("0 0 6", false)) {\r
+                       psk1TOpsk2(DemodBuffer, DemodBufferLen);\r
+                       if (preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                                 (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                               //save_restoreGB(0);\r
+                               return true;\r
+                       }\r
+               } // inverse waves does not affect PSK2 demod\r
+               //undo trim samples\r
+               //save_restoreGB(0); \r
+               // no other modulation clocks = 2 or 4 so quit searching\r
+               if (fc1 != 8) return false;\r
+       }\r
+\r
+       // try ask clock detect.  it could be another type even if successful.\r
+       clk = GetAskClock("", false, false);\r
+       if (clk>0) {\r
+               if ( ASKDemod_ext("0 0 1", false, false, 1, &st) &&\r
+                         preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                         (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                       return true;\r
+               }\r
+               st = true;\r
+               if ( ASKDemod_ext("0 1 1", false, false, 1, &st)  &&\r
+                         preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                         (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                       return true;\r
+               }\r
+               if ( ASKbiphaseDemod("0 0 0 2", false) &&\r
+                         preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                         (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                       return true;\r
+               }\r
+               if ( ASKbiphaseDemod("0 0 1 2", false) &&\r
+                         preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                         (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                       return true;\r
+               }\r
+       }\r
+\r
+       // try NRZ clock detect.  it could be another type even if successful.\r
+       clk = GetNrzClock("", false, false); //has the most false positives :(\r
+       if (clk>0) {\r
+               if ( NRZrawDemod("0 0 1", false)  &&\r
+                         preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                         (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                       return true;\r
+               }\r
+               if ( NRZrawDemod("0 1 1", false)  &&\r
+                         preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) && \r
+                         (DemodBufferLen == 32 || DemodBufferLen == 64) ) {\r
+                       return true;\r
+               }\r
+       }\r
+       return false;\r
+}\r
+//  does this need to be a callable command?\r
+int CmdT55xxDetectPage1(const char *Cmd){\r
+       bool errors = false;\r
+       bool useGB = false;\r
+       bool usepwd = false;\r
+       uint32_t password = 0;\r
+       uint8_t cmdp = 0;\r
+\r
+       while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {\r
+               switch(param_getchar(Cmd, cmdp)) {\r
+               case 'h':\r
+               case 'H':\r
+                       return usage_t55xx_detectP1();\r
+               case 'p':\r
+               case 'P':\r
+                       password = param_get32ex(Cmd, cmdp+1, 0, 16);\r
+                       usepwd = true;\r
+                       cmdp += 2;\r
+                       break;\r
+               case '1':\r
+                       // use Graphbuffer data\r
+                       useGB = true;\r
+                       cmdp++;\r
+                       break;\r
+               default:\r
+                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
+                       errors = true;\r
+                       break;\r
+               }\r
+       }\r
+       if (errors) return usage_t55xx_detectP1();\r
+\r
+       if ( !useGB ) {\r
+               if ( !AquireData(T55x7_PAGE1, 1, usepwd, password) )\r
+                       return false;\r
+       }\r
+       bool success = tryDetectP1(false);\r
+       if (success) PrintAndLog("T55xx chip found!");\r
+       return success;\r
+}\r
+\r
 static command_t CommandTable[] = {\r
   {"help",      CmdHelp,           1, "This help"},\r
        {"bruteforce",CmdT55xxBruteForce,0, "<start password> <end password> [i <*.dic>] Simple bruteforce attack to find password"},\r
   {"config",    CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},\r
   {"detect",    CmdT55xxDetect,    1, "[1] Try detecting the tag modulation from reading the configuration block."},\r
+  {"p1detect",  CmdT55xxDetectPage1,1, "[1] Try detecting if this is a t55xx tag by reading page 1"},\r
   {"read",      CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},\r
   {"resetread", CmdResetRead,      0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},\r
   {"write",     CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},\r
index 5c2ec79d11eb8d2c3afcdaf0bdfe9e05cc21eb55..4f0fd21d34aba79cc7e28efafd1070a93dbca25e 100644 (file)
@@ -36,18 +36,18 @@ typedef struct {
 \r
 typedef struct {\r
        enum {\r
-               DEMOD_NRZ  = 0x00,    \r
+               DEMOD_NRZ  = 0x00,\r
                DEMOD_PSK1 = 0x01,\r
                DEMOD_PSK2 = 0x02,\r
                DEMOD_PSK3 = 0x03,\r
-               DEMOD_FSK1  = 0x04,     \r
-               DEMOD_FSK1a = 0x05,     \r
-               DEMOD_FSK2  = 0x06,     \r
+               DEMOD_FSK1  = 0x04,\r
+               DEMOD_FSK1a = 0x05,\r
+               DEMOD_FSK2  = 0x06,\r
                DEMOD_FSK2a = 0x07, \r
                DEMOD_FSK   = 0xF0, //generic FSK (auto detect FCs)    \r
                DEMOD_ASK  = 0x08,\r
                DEMOD_BI   = 0x10,\r
-               DEMOD_BIa  = 0x18,              \r
+               DEMOD_BIa  = 0x18\r
        }  modulation;\r
        bool inverted;\r
        uint8_t offset;\r
@@ -60,27 +60,27 @@ typedef struct {
                RF_50 = 0x04,\r
                RF_64 = 0x05,\r
                RF_100 = 0x06,\r
-               RF_128 = 0x07,\r
+               RF_128 = 0x07\r
        } bitrate;\r
        bool Q5;\r
        bool ST;\r
 } t55xx_conf_block_t;\r
-t55xx_conf_block_t Get_t55xx_Config();\r
-void Set_t55xx_Config(t55xx_conf_block_t conf);\r
 \r
+t55xx_conf_block_t Get_t55xx_Config(void);\r
+void Set_t55xx_Config(t55xx_conf_block_t conf);\r
 \r
-int CmdLFT55XX(const char *Cmd);\r
-int CmdT55xxBruteForce(const char *Cmd);\r
-int CmdT55xxSetConfig(const char *Cmd);\r
-int CmdT55xxReadBlock(const char *Cmd);\r
-int CmdT55xxWriteBlock(const char *Cmd);\r
-int CmdT55xxReadTrace(const char *Cmd);\r
-int CmdT55xxInfo(const char *Cmd);\r
-int CmdT55xxDetect(const char *Cmd);\r
-int CmdResetRead(const char *Cmd);\r
-int CmdT55xxWipe(const char *Cmd);\r
+extern int CmdLFT55XX(const char *Cmd);\r
+extern int CmdT55xxBruteForce(const char *Cmd);\r
+extern int CmdT55xxSetConfig(const char *Cmd);\r
+extern int CmdT55xxReadBlock(const char *Cmd);\r
+extern int CmdT55xxWriteBlock(const char *Cmd);\r
+extern int CmdT55xxReadTrace(const char *Cmd);\r
+extern int CmdT55xxInfo(const char *Cmd);\r
+extern int CmdT55xxDetect(const char *Cmd);\r
+extern int CmdResetRead(const char *Cmd);\r
+extern int CmdT55xxWipe(const char *Cmd);\r
 \r
-char * GetBitRateStr(uint32_t id);\r
+char * GetBitRateStr(uint32_t id, bool xmode);\r
 char * GetSaferStr(uint32_t id);\r
 char * GetModulationStr( uint32_t id);\r
 char * GetModelStrFromCID(uint32_t cid);\r
@@ -90,8 +90,9 @@ void printT5xxHeader(uint8_t page);
 void printT55xxBlock(const char *demodStr);\r
 int printConfiguration( t55xx_conf_block_t b);\r
 \r
-bool DecodeT55xxBlock();\r
-bool tryDetectModulation();\r
+bool DecodeT55xxBlock(void);\r
+bool tryDetectModulation(void);\r
+extern bool tryDetectP1(bool getData);\r
 bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);\r
 int special(const char *Cmd);\r
 int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );\r
index 995a32da6a451cba3e57eb34ec8503f98c15c213..c09820674d4d01cf665df940a4c799f2a5292da0 100644 (file)
@@ -166,11 +166,12 @@ uint8_t GetPskCarrier(const char str[], bool printAns, bool verbose)
                        PrintAndLog("Failed to copy from graphbuffer");
                return 0;
        }
-       //uint8_t countPSK_FC(uint8_t *BitStream, size_t size)
-
-       carrier = countFC(grph,size,0);
+       uint16_t fc = countFC(grph,size,0);
+       carrier = fc & 0xFF;
+       if (carrier != 2 && carrier != 4 && carrier != 8) return 0;
+       if ((fc>>8) == 10 && carrier == 8) return 0;
        // Only print this message if we're not looping something
-       if (printAns){
+       if (printAns) {
                PrintAndLog("Auto-detected PSK carrier rate: %d", carrier);
        }
        return carrier;
@@ -193,7 +194,9 @@ int GetPskClock(const char str[], bool printAns, bool verbose)
                        PrintAndLog("Failed to copy from graphbuffer");
                return -1;
        }
-       clock = DetectPSKClock(grph,size,0);
+       size_t firstPhaseShiftLoc = 0;
+       uint8_t curPhase = 0, fc = 0;
+       clock = DetectPSKClock(grph, size, 0, &firstPhaseShiftLoc, &curPhase, &fc);
        // Only print this message if we're not looping something
        if (printAns){
                PrintAndLog("Auto-detected clock rate: %d", clock);
index d4e59165794381ee5bf1fa39036c199eb0cb2d49..593eaa526864f21600bf501207540fba02f05638 100644 (file)
@@ -169,7 +169,7 @@ char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t brea
 
        size_t in_index = 0;
        // loop through the out_index to make sure we don't go too far
-       for (size_t out_index=0; out_index < max_len-1; out_index++) {
+       for (size_t out_index=0; out_index < max_len; out_index++) {
                // set character - (should be binary but verify it isn't more than 1 digit)
                if (data[in_index]<10)
                        sprintf(tmp++, "%u", (unsigned int) data[in_index]);
index c56301c07f07ab75c0da0499fbf59d504e204859..49838f5e2be22e694015a181a0e36438c74b4561 100644 (file)
@@ -33,6 +33,7 @@
 //-----------------------------------------------------------------------------
 
 #include <string.h>  // for memset, memcmp and size_t
+#include "lfdemod.h"
 #include <stdint.h>  // for uint_32+
 #include <stdbool.h> // for bool
 #include "parity.h"  // for parity test
@@ -277,6 +278,33 @@ bool loadWaveCounters(uint8_t samples[], size_t size, int lowToLowWaveLen[], int
        return true;
 }
 
+size_t pskFindFirstPhaseShift(uint8_t samples[], size_t size, uint8_t *curPhase, size_t waveStart, uint16_t fc, uint16_t *fullWaveLen) {
+       uint16_t loopCnt = (size+3 < 4096) ? size : 4096;  //don't need to loop through entire array...
+
+       uint16_t avgWaveVal=0, lastAvgWaveVal=0;
+       size_t i = waveStart, waveEnd, waveLenCnt, firstFullWave;
+       for (; i<loopCnt; i++) {
+               // find peak // was "samples[i] + fc" but why?  must have been used to weed out some wave error... removed..
+               if (samples[i] < samples[i+1] && samples[i+1] >= samples[i+2]){
+                       waveEnd = i+1;
+                       if (g_debugMode == 2) prnt("DEBUG PSK: waveEnd: %u, waveStart: %u", waveEnd, waveStart);
+                       waveLenCnt = waveEnd-waveStart;
+                       if (waveLenCnt > fc && waveStart > fc && !(waveLenCnt > fc+8)){ //not first peak and is a large wave but not out of whack
+                               lastAvgWaveVal = avgWaveVal/(waveLenCnt);
+                               firstFullWave = waveStart;
+                               *fullWaveLen = waveLenCnt;
+                               //if average wave value is > graph 0 then it is an up wave or a 1 (could cause inverting)
+                               if (lastAvgWaveVal > FSK_PSK_THRESHOLD) *curPhase ^= 1;
+                               return firstFullWave;
+                       }
+                       waveStart = i+1;
+                       avgWaveVal = 0;
+               }
+               avgWaveVal += samples[i+2];
+       }
+       return 0;
+}
+
 //by marshmellow
 //amplify based on ask edge detection  -  not accurate enough to use all the time
 void askAmp(uint8_t *BitStream, size_t size) {
@@ -520,7 +548,7 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx
 
        //get high and low peak
        int peak, low;
-       if (getHiLo(dest, loopCnt, &peak, &low, 75, 75) < 1) return 0;
+       if (getHiLo(dest, loopCnt, &peak, &low, 85, 85) < 1) return 0;
 
        int lowestTransition = DetectStrongNRZClk(dest, size-20, peak, low);
        size_t ii;
@@ -529,26 +557,24 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx
        uint16_t smplCnt = 0;
        int16_t peakcnt = 0;
        int16_t peaksdet[] = {0,0,0,0,0,0,0,0};
-       uint16_t maxPeak = 255;
-       bool firstpeak = false;
-       //test for large clipped waves
-       for (i=0; i<loopCnt; i++){
-               if (dest[i] >= peak || dest[i] <= low){
-                       if (!firstpeak) continue;
+       uint16_t minPeak = 255;
+       bool firstpeak = true;
+       //test for large clipped waves - ignore first peak
+       for (i=0; i<loopCnt; i++) {
+               if (dest[i] >= peak || dest[i] <= low) {
+                       if (firstpeak) continue;
                        smplCnt++;
                } else {
-                       firstpeak=true;
-                       if (smplCnt > 6 ){
-                               if (maxPeak > smplCnt){
-                                       maxPeak = smplCnt;
-                                       //prnt("maxPk: %d",maxPeak);
-                               }
+                       firstpeak = false;
+                       if (smplCnt > 0) {
+                               if (minPeak > smplCnt && smplCnt > 7) minPeak = smplCnt;
                                peakcnt++;
-                               //prnt("maxPk: %d, smplCnt: %d, peakcnt: %d",maxPeak,smplCnt,peakcnt);
-                               smplCnt=0;
+                               if (g_debugMode == 2) prnt("DEBUG NRZ: minPeak: %d, smplCnt: %d, peakcnt: %d",minPeak,smplCnt,peakcnt);
+                               smplCnt = 0;                            
                        }
                }
        }
+       if (minPeak < 8) return 0;
        bool errBitHigh = 0;
        bool bitHigh = 0;
        uint8_t ignoreCnt = 0;
@@ -558,12 +584,12 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx
        size_t bestStart[]={0,0,0,0,0,0,0,0,0};
        peakcnt=0;
        //test each valid clock from smallest to greatest to see which lines up
-       for(clkCnt=0; clkCnt < 8; ++clkCnt){
+       for(clkCnt=0; clkCnt < 8; ++clkCnt) {
                //ignore clocks smaller than smallest peak
-               if (clk[clkCnt] < maxPeak - (clk[clkCnt]/4)) continue;
+               if (clk[clkCnt] < minPeak - (clk[clkCnt]/4)) continue;
                //try lining up the peaks by moving starting point (try first 256)
-               for (ii=20; ii < loopCnt; ++ii){
-                       if ((dest[ii] >= peak) || (dest[ii] <= low)){
+               for (ii=20; ii < loopCnt; ++ii) {
+                       if ((dest[ii] >= peak) || (dest[ii] <= low)) {
                                peakcnt = 0;
                                bitHigh = false;
                                ignoreCnt = 0;
@@ -587,8 +613,8 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx
                                                        lastBit += clk[clkCnt];
                                                }
                                        //else if not a clock bit and no peaks
-                                       } else if (dest[i] < peak && dest[i] > low){
-                                               if (ignoreCnt==0){
+                                       } else if (dest[i] < peak && dest[i] > low) {
+                                               if (ignoreCnt==0) {
                                                        bitHigh=false;
                                                        if (errBitHigh==true) peakcnt--;
                                                        errBitHigh=false;
@@ -610,15 +636,15 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx
        }
        int iii=7;
        uint8_t best=0;
-       for (iii=7; iii > 0; iii--){
+       for (iii=7; iii > 0; iii--) {
                if ((peaksdet[iii] >= (peaksdet[best]-1)) && (peaksdet[iii] <= peaksdet[best]+1) && lowestTransition) {
                        if (clk[iii] > (lowestTransition - (clk[iii]/8)) && clk[iii] < (lowestTransition + (clk[iii]/8))) {
                                best = iii;
                        }
-               } else if (peaksdet[iii] > peaksdet[best]){
+               } else if (peaksdet[iii] > peaksdet[best]) {
                        best = iii;
                }
-               if (g_debugMode==2) prnt("DEBUG NRZ: Clk: %d, peaks: %d, maxPeak: %d, bestClk: %d, lowestTrs: %d",clk[iii],peaksdet[iii],maxPeak, clk[best], lowestTransition);
+               if (g_debugMode==2) prnt("DEBUG NRZ: Clk: %d, peaks: %d, minPeak: %d, bestClk: %d, lowestTrs: %d",clk[iii],peaksdet[iii],minPeak, clk[best], lowestTransition);
        }
        *clockStartIdx  = bestStart[best];
        return clk[best];
@@ -691,6 +717,7 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) {
                        best3=i;
                }
                if (g_debugMode==2) prnt("DEBUG countfc: FC %u, Cnt %u, best fc: %u, best2 fc: %u",fcLens[i],fcCnts[i],fcLens[best1],fcLens[best2]);
+               if (fcLens[i]==0) break;
        }
        if (fcLens[best1]==0) return 0;
        uint8_t fcH=0, fcL=0;
@@ -708,18 +735,24 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) {
        // TODO: take top 3 answers and compare to known Field clocks to get top 2
 
        uint16_t fcs = (((uint16_t)fcH)<<8) | fcL;
-       if (fskAdj) return fcs; 
-       return fcLens[best1];
+       if (fskAdj) return fcs;
+       return (uint16_t)fcLens[best2] << 8 | fcLens[best1];
 }
 
 //by marshmellow
 //detect psk clock by reading each phase shift
 // a phase shift is determined by measuring the sample length of each wave
-int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseShift) {
+int DetectPSKClock(uint8_t dest[], size_t size, int clock, size_t *firstPhaseShift, uint8_t *curPhase, uint8_t *fc) {
        uint8_t clk[]={255,16,32,40,50,64,100,128,255}; //255 is not a valid clock
        uint16_t loopCnt = 4096;  //don't need to loop through entire array...
        if (size == 0) return 0;
-       if (size<loopCnt) loopCnt = size-20;
+       if (size+3<loopCnt) loopCnt = size-20;
+
+       uint16_t fcs = countFC(dest, size, 0);
+       *fc = fcs & 0xFF;
+       if (g_debugMode==2) prnt("DEBUG PSK: FC: %d, FC2: %d",*fc, fcs>>8);
+       if ((fcs>>8) == 10 && *fc == 8) return -1;
+       if (*fc!=2 && *fc!=4 && *fc!=8) return -1;
 
        //if we already have a valid clock quit
        size_t i=1;
@@ -727,37 +760,28 @@ int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseSh
                if (clk[i] == clock) return clock;
 
        size_t waveStart=0, waveEnd=0, firstFullWave=0, lastClkBit=0;
-       uint8_t clkCnt, fc=0, fullWaveLen=0, tol=1;
-       uint16_t peakcnt=0, errCnt=0, waveLenCnt=0;
+
+       uint8_t clkCnt, tol=1;
+       uint16_t peakcnt=0, errCnt=0, waveLenCnt=0, fullWaveLen=0;
        uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
        uint16_t peaksdet[]={0,0,0,0,0,0,0,0,0};
-       fc = countFC(dest, size, 0);
-       if (fc!=2 && fc!=4 && fc!=8) return -1;
-       if (g_debugMode==2) prnt("DEBUG PSK: FC: %d",fc);
 
-       //find first full wave
-       for (i=160; i<loopCnt; i++){
-               if (dest[i] < dest[i+1] && dest[i+1] >= dest[i+2]){
-                       if (waveStart == 0) {
-                               waveStart = i+1;
-                               //prnt("DEBUG: waveStart: %d",waveStart);
-                       } else {
-                               waveEnd = i+1;
-                               //prnt("DEBUG: waveEnd: %d",waveEnd);
-                               waveLenCnt = waveEnd-waveStart;
-                               if (waveLenCnt > fc){
-                                       firstFullWave = waveStart;
-                                       fullWaveLen=waveLenCnt;
-                                       break;
-                               } 
-                               waveStart=0;
-                       }
-               }
+       //find start of modulating data in trace 
+       i = findModStart(dest, size, *fc);
+
+       firstFullWave = pskFindFirstPhaseShift(dest, size, curPhase, i, *fc, &fullWaveLen);
+       if (firstFullWave == 0) {
+               // no phase shift detected - could be all 1's or 0's - doesn't matter where we start
+               // so skip a little to ensure we are past any Start Signal
+               firstFullWave = 160;
+               fullWaveLen = 0;
        }
+
        *firstPhaseShift = firstFullWave;
        if (g_debugMode ==2) prnt("DEBUG PSK: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen);
        //test each valid clock from greatest to smallest to see which lines up
-       for(clkCnt=7; clkCnt >= 1 ; clkCnt--){
+       for(clkCnt=7; clkCnt >= 1 ; clkCnt--) {
+               tol = *fc/2;
                lastClkBit = firstFullWave; //set end of wave as clock align
                waveStart = 0;
                errCnt=0;
@@ -773,9 +797,9 @@ int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseSh
                                } else { //waveEnd
                                        waveEnd = i+1;
                                        waveLenCnt = waveEnd-waveStart;
-                                       if (waveLenCnt > fc){ 
+                                       if (waveLenCnt > *fc){ 
                                                //if this wave is a phase shift
-                                               if (g_debugMode == 2) prnt("DEBUG PSK: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,i+1,fc);
+                                               if (g_debugMode == 2) prnt("DEBUG PSK: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,i+1,*fc);
                                                if (i+1 >= lastClkBit + clk[clkCnt] - tol){ //should be a clock bit
                                                        peakcnt++;
                                                        lastClkBit+=clk[clkCnt];
@@ -784,7 +808,7 @@ int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseSh
                                                } else { //phase shift before supposed to based on clock
                                                        errCnt++;
                                                }
-                                       } else if (i+1 > lastClkBit + clk[clkCnt] + tol + fc){
+                                       } else if (i+1 > lastClkBit + clk[clkCnt] + tol + *fc){
                                                lastClkBit+=clk[clkCnt]; //no phase shift but clock bit
                                        }
                                        waveStart=i+1;
@@ -809,10 +833,11 @@ int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseSh
        return clk[best];
 }
 
-int DetectPSKClock(uint8_t dest[], size_t size, int clock) {
-       int firstPhaseShift = 0;
-       return DetectPSKClock_ext(dest, size, clock, &firstPhaseShift);
-}
+//int DetectPSKClock(uint8_t dest[], size_t size, int clock) {
+//     size_t firstPhaseShift = 0;
+//     uint8_t curPhase = 0;
+//     return DetectPSKClock_ext(dest, size, clock, &firstPhaseShift, &curPhase);
+//}
 
 //by marshmellow
 //detects the bit clock for FSK given the high and low Field Clocks
@@ -955,7 +980,7 @@ bool DetectST_ext(uint8_t buffer[], size_t *size, int *foundclock, size_t *ststa
        //need to loop through all samples and identify our clock, look for the ST pattern
        int clk = 0; 
        int tol = 0;
-       int j, high, low, skip, start, end, minClk=255;
+       int j=0, high, low, skip=0, start=0, end=0, minClk=255;
        size_t i = 0;
        //probably should malloc... || test if memory is available ... handle device side? memory danger!!! [marshmellow]
        int tmpbuff[bufsize / LOWEST_DEFAULT_CLOCK]; // low to low wave count //guess rf/32 clock, if click is smaller we will only have room for a fraction of the samples captured
@@ -1023,9 +1048,9 @@ bool DetectST_ext(uint8_t buffer[], size_t *size, int *foundclock, size_t *ststa
                return false;
        }
        size_t dataloc = start;
-       if (buffer[dataloc-(clk*4)-(clk/8)] <= low && buffer[dataloc] <= low && buffer[dataloc-(clk*4)] >= high) {
+       if (buffer[dataloc-(clk*4)-(clk/4)] <= low && buffer[dataloc] <= low && buffer[dataloc-(clk*4)] >= high) {
                //we have low drift (and a low just before the ST and a low just after the ST) - compensate by backing up the start 
-               for ( i=0; i <= (clk/8); ++i ) {
+               for ( i=0; i <= (clk/4); ++i ) {
                        if ( buffer[dataloc - (clk*4) - i] <= low ) {
                                dataloc -= i;
                                break;
@@ -1040,14 +1065,15 @@ bool DetectST_ext(uint8_t buffer[], size_t *size, int *foundclock, size_t *ststa
        // warning - overwriting buffer given with raw wave data with ST removed...
        while ( dataloc < bufsize-(clk/2) ) {
                //compensate for long high at end of ST not being high due to signal loss... (and we cut out the start of wave high part)
-               if (buffer[dataloc]<high && buffer[dataloc]>low && buffer[dataloc+3]<high && buffer[dataloc+3]>low) {
+               if (buffer[dataloc]<high && buffer[dataloc]>low && buffer[dataloc+clk/4]<high && buffer[dataloc+clk/4]>low) {
                        for(i=0; i < clk/2-tol; ++i) {
                                buffer[dataloc+i] = high+5;
                        }
-               } //test for single sample outlier (high between two lows) in the case of very strong waves
-               if (buffer[dataloc] >= high && buffer[dataloc+2] <= low) {
-                       buffer[dataloc] = buffer[dataloc+2];
-                       buffer[dataloc+1] = buffer[dataloc+2];
+               } //test for small spike outlier (high between two lows) in the case of very strong waves
+               if (buffer[dataloc] > low && buffer[dataloc+clk/4] <= low) {
+                       for(i=0; i < clk/4; ++i) {
+                               buffer[dataloc+i] = buffer[dataloc+clk/4];
+                       }
                }
                if (firstrun) {
                        *stend = dataloc;
@@ -1521,60 +1547,34 @@ void psk2TOpsk1(uint8_t *BitStream, size_t size) {
        return;
 }
 
-size_t pskFindFirstPhaseShift(uint8_t samples[], size_t size, uint8_t *curPhase, size_t waveStart, uint16_t fc, uint16_t *fullWaveLen) {
-       uint16_t loopCnt = (size+3 < 4096) ? size : 4096;  //don't need to loop through entire array...
-
-       uint16_t avgWaveVal=0, lastAvgWaveVal=0;
-       size_t i = waveStart, waveEnd, waveLenCnt, firstFullWave;
-       for (; i<loopCnt; i++) {
-               // find peak 
-               if (samples[i]+fc < samples[i+1] && samples[i+1] >= samples[i+2]){
-                       waveEnd = i+1;
-                       if (g_debugMode == 2) prnt("DEBUG PSK: waveEnd: %u, waveStart: %u", waveEnd, waveStart);
-                       waveLenCnt = waveEnd-waveStart;
-                       if (waveLenCnt > fc && waveStart > fc && !(waveLenCnt > fc+8)){ //not first peak and is a large wave but not out of whack
-                               lastAvgWaveVal = avgWaveVal/(waveLenCnt);
-                               firstFullWave = waveStart;
-                               *fullWaveLen = waveLenCnt;
-                               //if average wave value is > graph 0 then it is an up wave or a 1 (could cause inverting)
-                               if (lastAvgWaveVal > FSK_PSK_THRESHOLD) *curPhase ^= 1;
-                               return firstFullWave;
-                       }
-                       waveStart = i+1;
-                       avgWaveVal = 0;
-               }
-               avgWaveVal += samples[i+2];
-       }
-       return 0;
-}
-
 //by marshmellow - demodulate PSK1 wave 
 //uses wave lengths (# Samples) 
 int pskRawDemod_ext(uint8_t dest[], size_t *size, int *clock, int *invert, int *startIdx) {
        if (*size < 170) return -1;
 
        uint8_t curPhase = *invert;
+       uint8_t fc=0;
        size_t i=0, numBits=0, waveStart=1, waveEnd=0, firstFullWave=0, lastClkBit=0;
-       uint16_t fc=0, fullWaveLen=0, waveLenCnt=0, avgWaveVal, tol=1;
+       uint16_t fullWaveLen=0, waveLenCnt=0, avgWaveVal;
        uint16_t errCnt=0, errCnt2=0;
        
-       fc = countFC(dest, *size, 1);
-       if ((fc >> 8) == 10) return -1; //fsk found - quit
-       fc = fc & 0xFF;
-       if (fc!=2 && fc!=4 && fc!=8) return -1;
-       *clock = DetectPSKClock(dest, *size, *clock);
+       *clock = DetectPSKClock(dest, *size, *clock, &firstFullWave, &curPhase, &fc);
        if (*clock == 0) return -1;
-
-       //find start of modulating data in trace 
-       i = findModStart(dest, *size, fc);
-
-       //find first phase shift
-       firstFullWave = pskFindFirstPhaseShift(dest, *size, &curPhase, i, fc, &fullWaveLen);
+       //if clock detect found firstfullwave...
+       uint16_t tol = fc/2;
        if (firstFullWave == 0) {
-               // no phase shift detected - could be all 1's or 0's - doesn't matter where we start
-               // so skip a little to ensure we are past any Start Signal
-               firstFullWave = 160;
-               memset(dest, curPhase, firstFullWave / *clock);
+               //find start of modulating data in trace 
+               i = findModStart(dest, *size, fc);
+               //find first phase shift
+               firstFullWave = pskFindFirstPhaseShift(dest, *size, &curPhase, i, fc, &fullWaveLen);
+               if (firstFullWave == 0) {
+                       // no phase shift detected - could be all 1's or 0's - doesn't matter where we start
+                       // so skip a little to ensure we are past any Start Signal
+                       firstFullWave = 160;
+                       memset(dest, curPhase, firstFullWave / *clock);
+               } else {
+                       memset(dest, curPhase^1, firstFullWave / *clock);
+               }
        } else {
                memset(dest, curPhase^1, firstFullWave / *clock);
        }
@@ -1587,9 +1587,9 @@ int pskRawDemod_ext(uint8_t dest[], size_t *size, int *clock, int *invert, int *
        if (g_debugMode==2) prnt("DEBUG PSK: clk: %d, lastClkBit: %u, fc: %u", *clock, lastClkBit,(unsigned int) fc);
        waveStart = 0;
        dest[numBits++] = curPhase; //set first read bit
-       for (i = firstFullWave + fullWaveLen - 1; i < *size-3; i++){
+       for (i = firstFullWave + fullWaveLen - 1; i < *size-3; i++) {
                //top edge of wave = start of new wave 
-               if (dest[i]+fc < dest[i+1] && dest[i+1] >= dest[i+2]){
+               if (dest[i]+fc < dest[i+1] && dest[i+1] >= dest[i+2]) {
                        if (waveStart == 0) {
                                waveStart = i+1;
                                waveLenCnt = 0;
@@ -1597,25 +1597,27 @@ int pskRawDemod_ext(uint8_t dest[], size_t *size, int *clock, int *invert, int *
                        } else { //waveEnd
                                waveEnd = i+1;
                                waveLenCnt = waveEnd-waveStart;
-                               if (waveLenCnt > fc){
+                               if (waveLenCnt > fc) {
                                        //this wave is a phase shift
                                        //PrintAndLog("DEBUG: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+*clock-tol,i+1,fc);
-                                       if (i+1 >= lastClkBit + *clock - tol){ //should be a clock bit
+                                       if (i+1 >= lastClkBit + *clock - tol) { //should be a clock bit
                                                curPhase ^= 1;
                                                dest[numBits++] = curPhase;
                                                lastClkBit += *clock;
-                                       } else if (i < lastClkBit+10+fc){
+                                       } else if (i < lastClkBit+10+fc) {
                                                //noise after a phase shift - ignore
                                        } else { //phase shift before supposed to based on clock
                                                errCnt++;
                                                dest[numBits++] = 7;
                                        }
-                               } else if (i+1 > lastClkBit + *clock + tol + fc){
+                               } else if (i+1 > lastClkBit + *clock + tol + fc) {
                                        lastClkBit += *clock; //no phase shift but clock bit
                                        dest[numBits++] = curPhase;
                                } else if (waveLenCnt < fc - 1) { //wave is smaller than field clock (shouldn't happen often)
                                        errCnt2++;
                                        if(errCnt2 > 101) return errCnt2;
+                                       avgWaveVal += dest[i+1];
+                                       continue;
                                }
                                avgWaveVal = 0;
                                waveStart = i+1;
@@ -1800,7 +1802,7 @@ int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert) {
        } 
        if (*size != 64 && *size != 224) return -2;
        if (*invert==1)
-               for (size_t i = startidx; i < *size; i++)
+               for (size_t i = startidx; i < *size + startidx; i++) 
                        bitStream[i] ^= 1;
 
        return (int) startidx;
index a881fa181d0649f150729a306e0bb1064e17169d..697b78cb1a0dc4323ec36992a827e0bc11016f6c 100644 (file)
@@ -30,8 +30,7 @@ extern uint8_t  DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, ui
 extern uint8_t  detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
 extern uint8_t  detectFSKClk_ext(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow, int *firstClockEdge);
 extern int      DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx);
-extern int      DetectPSKClock(uint8_t dest[], size_t size, int clock);
-extern int      DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseShift);
+extern int      DetectPSKClock(uint8_t dest[], size_t size, int clock, size_t *firstPhaseShift, uint8_t *curPhase, uint8_t *fc);
 extern int      DetectStrongAskClock(uint8_t dest[], size_t size, int high, int low, int *clock);
 extern bool     DetectST(uint8_t buffer[], size_t *size, int *foundclock);
 extern bool     DetectST_ext(uint8_t buffer[], size_t *size, int *foundclock, size_t *ststart, size_t *stend);
@@ -42,7 +41,7 @@ extern uint32_t manchesterEncode2Bytes(uint16_t datain);
 extern int      ManchesterEncode(uint8_t *BitStream, size_t size);
 extern int      manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert, uint8_t *alignPos);
 extern int      nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx);
-extern uint8_t  parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
+extern bool     parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
 extern uint8_t  preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
 extern bool     preambleSearchEx(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx, bool findone);
 extern int      pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
index bb888d3ddf52f25945cfd1b37d778508bb1590ad..31252ad380fd3dc153518c91001ac46f42e22b97 100644 (file)
@@ -238,6 +238,7 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *
 #define T55x7_MODULATION_MANCHESTER 0x00008000
 #define T55x7_MODULATION_BIPHASE    0x00010000
 #define T55x7_MODULATION_DIPHASE    0x00018000
+#define T55x7_X_MODE                0x00020000
 #define T55x7_BITRATE_RF_8          0
 #define T55x7_BITRATE_RF_16         0x00040000
 #define T55x7_BITRATE_RF_32         0x00080000
Impressum, Datenschutz