]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iso15693.c
Merge pull request #658 from grauerfuchs/master
[proxmark3-svn] / armsrc / iso15693.c
index 9a6ef9f01220a5d52fe441b7e16ae82e70affcb7..c092b3834ccfbd112091edad498ea26383e116e7 100644 (file)
 #define AddCrc(data,datalen)  Iso15693AddCrc(data,datalen)
 #define sprintUID(target,uid)  Iso15693sprintUID(target,uid)
 
-int DEBUG=0;
+// approximate amplitude=sqrt(ci^2+cq^2) 
+#define AMPLITUDE(ci, cq) (MAX(ABS(ci), ABS(cq)) + (MIN(ABS(ci), ABS(cq))>>1))
+
+static int DEBUG = 0;
 
 
 // ---------------------------
@@ -224,26 +227,14 @@ static void TransmitTo15693Tag(const uint8_t *cmd, int len, int *samples, int *w
 {
     int c;
 
-//    FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_READER_MOD);
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
        if(*wait < 10) { *wait = 10; }
 
-//    for(c = 0; c < *wait;) {
-//        if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-//            AT91C_BASE_SSC->SSC_THR = 0x00;          // For exact timing!
-//            c++;
-//        }
-//        if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-//            volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
-//            (void)r;
-//        }
-//        WDT_HIT();
-//    }
-
     c = 0;
     for(;;) {
         if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-            AT91C_BASE_SSC->SSC_THR = cmd[c];
+            AT91C_BASE_SSC->SSC_THR = ~cmd[c];
             c++;
             if(c >= len) {
                 break;
@@ -297,40 +288,25 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
 {
        int c = 0;
        uint8_t *dest = BigBuf_get_addr();
-       int getNext = 0;
-
-       int8_t prev = 0;
 
 // NOW READ RESPONSE
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
-       //spindelay(60);        // greg - experiment to get rid of some of the 0 byte/failed reads
        c = 0;
-       getNext = FALSE;
        for(;;) {
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                       AT91C_BASE_SSC->SSC_THR = 0x43;
-               }
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       int8_t b;
-                       b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
-
+                       uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
                        // The samples are correlations against I and Q versions of the
-                       // tone that the tag AM-modulates, so every other sample is I,
-                       // every other is Q. We just want power, so abs(I) + abs(Q) is
-                       // close to what we want.
-                       if(getNext) {
-                               int8_t r = ABS(b) + ABS(prev);
-
-                               dest[c++] = (uint8_t)r;
+                       // tone that the tag AM-modulates. We just want power. 
+                       int8_t i = iq >> 8;
+                       int8_t q = iq;
+                       uint8_t r = AMPLITUDE(i, q);
 
-                               if(c >= 2000) {
-                                       break;
-                               }
-                       } else {
-                               prev = b;
+                       dest[c++] = r;
+                       
+                       if(c >= 4000) {
+                               break;
                        }
-
-                       getNext = !getNext;
                }
        }
 
@@ -341,12 +317,10 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
        int i, j;
        int max = 0, maxPos=0;
 
-       int skip = 4;
-
-       //      if(GraphTraceLen < 1000) return;        // THIS CHECKS FOR A BUFFER TO SMALL
+       int skip = 2;
 
        // First, correlate for SOF
-       for(i = 0; i < 100; i++) {
+       for(i = 0; i < 200; i++) {  // usually, SOF is found around i = 60
                int corr = 0;
                for(j = 0; j < arraylen(FrameSOF); j += skip) {
                        corr += FrameSOF[j]*dest[i+(j/skip)];
@@ -356,7 +330,7 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
                        maxPos = i;
                }
        }
-       //      DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
+       if (DEBUG) Dbprintf("SOF at %d, correlation %d", maxPos, max/(arraylen(FrameSOF)/skip));
 
        int k = 0; // this will be our return value
 
@@ -370,10 +344,15 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
                memset(outBuf, 0, sizeof(outBuf));
                uint8_t mask = 0x01;
                for(;;) {
-                       int corr0 = 0, corr1 = 0, corrEOF = 0;
+                       int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
                        for(j = 0; j < arraylen(Logic0); j += skip) {
                                corr0 += Logic0[j]*dest[i+(j/skip)];
                        }
+                       corr01 = corr00 = corr0;
+                       for(j = 0; j < arraylen(Logic0); j += skip) {
+                               corr00 += Logic0[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
+                               corr01 += Logic1[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
+                       }
                        for(j = 0; j < arraylen(Logic1); j += skip) {
                                corr1 += Logic1[j]*dest[i+(j/skip)];
                        }
@@ -381,11 +360,14 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
                                corrEOF += FrameEOF[j]*dest[i+(j/skip)];
                        }
                        // Even things out by the length of the target waveform.
+                       corr00 *= 2;
+                       corr01 *= 2;
                        corr0 *= 4;
                        corr1 *= 4;
        
-                       if(corrEOF > corr1 && corrEOF > corr0) {
-       //                      DbpString("EOF at %d", i);
+                       if(corrEOF > corr1 && corrEOF > corr00 && corrEOF > corr01) {
+                               if (DEBUG) Dbprintf("EOF at %d, correlation %d (corr01: %d, corr00: %d, corr1: %d, corr0: %d)", 
+                                       i, corrEOF, corr01, corr00, corr1, corr0);
                                break;
                        } else if(corr1 > corr0) {
                                i += arraylen(Logic1)/skip;
@@ -398,7 +380,7 @@ static int GetIso15693AnswerFromTag(uint8_t *receivedResponse, int maxLen, int *
                                k++;
                                mask = 0x01;
                        }
-                       if((i+(int)arraylen(FrameEOF)) >= 2000) {
+                       if((i+(int)arraylen(FrameEOF)/skip) >= 4000) {
                                DbpString("ran off end!");
                                break;
                        }
@@ -436,39 +418,26 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
 {
        int c = 0;
        uint8_t *dest = BigBuf_get_addr();
-       int getNext = 0;
-
-       int8_t prev = 0;
 
 // NOW READ RESPONSE
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        //spindelay(60);        // greg - experiment to get rid of some of the 0 byte/failed reads
        c = 0;
-       getNext = FALSE;
        for(;;) {
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                       AT91C_BASE_SSC->SSC_THR = 0x43;
-               }
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       int8_t b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
-
+                       uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
                        // The samples are correlations against I and Q versions of the
-                       // tone that the tag AM-modulates, so every other sample is I,
-                       // every other is Q. We just want power, so abs(I) + abs(Q) is
-                       // close to what we want.
-                       if(getNext) {
-                               int8_t r = ABS(b) + ABS(prev);
+                       // tone that the tag AM-modulates. We just want power, 
+                       // so abs(I) + abs(Q) is close to what we want.
+                       int8_t i = iq >> 8;
+                       int8_t q = iq;
+                       uint8_t r = AMPLITUDE(i, q);
 
-                               dest[c++] = (uint8_t)r;
+                       dest[c++] = r;
 
-                               if(c >= 20000) {
-                                       break;
-                               }
-                       } else {
-                               prev = b;
+                       if(c >= BIGBUF_SIZE) {
+                               break;
                        }
-
-                       getNext = !getNext;
                }
        }
 
@@ -479,12 +448,10 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
        int i, j;
        int max = 0, maxPos=0;
 
-       int skip = 4;
-
-//     if(GraphTraceLen < 1000) return;        // THIS CHECKS FOR A BUFFER TO SMALL
+       int skip = 2;
 
        // First, correlate for SOF
-       for(i = 0; i < 19000; i++) {
+       for(i = 0; i < 38000; i++) {
                int corr = 0;
                for(j = 0; j < arraylen(FrameSOF); j += skip) {
                        corr += FrameSOF[j]*dest[i+(j/skip)];
@@ -494,7 +461,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                        maxPos = i;
                }
        }
-//     DbpString("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
+       if (DEBUG) Dbprintf("SOF at %d, correlation %d", maxPos,max/(arraylen(FrameSOF)/skip));
 
        int k = 0; // this will be our return value
 
@@ -508,10 +475,15 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                memset(outBuf, 0, sizeof(outBuf));
                uint8_t mask = 0x01;
                for(;;) {
-                       int corr0 = 0, corr1 = 0, corrEOF = 0;
+                       int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
                        for(j = 0; j < arraylen(Logic0); j += skip) {
                                corr0 += Logic0[j]*dest[i+(j/skip)];
                        }
+                       corr01 = corr00 = corr0;
+                       for(j = 0; j < arraylen(Logic0); j += skip) {
+                               corr00 += Logic0[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
+                               corr01 += Logic1[j]*dest[i+arraylen(Logic0)/skip+(j/skip)];
+                       }
                        for(j = 0; j < arraylen(Logic1); j += skip) {
                                corr1 += Logic1[j]*dest[i+(j/skip)];
                        }
@@ -519,11 +491,14 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                                corrEOF += FrameEOF[j]*dest[i+(j/skip)];
                        }
                        // Even things out by the length of the target waveform.
+                       corr00 *= 2;
+                       corr01 *= 2;
                        corr0 *= 4;
                        corr1 *= 4;
        
-                       if(corrEOF > corr1 && corrEOF > corr0) {
-       //                      DbpString("EOF at %d", i);
+                       if(corrEOF > corr1 && corrEOF > corr00 && corrEOF > corr01) {
+                               if (DEBUG) Dbprintf("EOF at %d, correlation %d (corr01: %d, corr00: %d, corr1: %d, corr0: %d)", 
+                                       i, corrEOF, corr01, corr00, corr1, corr0);
                                break;
                        } else if(corr1 > corr0) {
                                i += arraylen(Logic1)/skip;
@@ -536,7 +511,7 @@ static int GetIso15693AnswerFromSniff(uint8_t *receivedResponse, int maxLen, int
                                k++;
                                mask = 0x01;
                        }
-                       if((i+(int)arraylen(FrameEOF)) >= 2000) {
+                       if((i+(int)arraylen(FrameEOF)/skip) >= BIGBUF_SIZE) {
                                DbpString("ran off end!");
                                break;
                        }
@@ -577,8 +552,6 @@ void AcquireRawAdcSamplesIso15693(void)
        uint8_t *dest = BigBuf_get_addr();
 
        int c = 0;
-       int getNext = 0;
-       int8_t prev = 0;
 
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        BuildIdentifyRequest();
@@ -590,54 +563,40 @@ void AcquireRawAdcSamplesIso15693(void)
        SpinDelay(100);
 
        // Now send the command
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_TX);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_TX);
 
        c = 0;
        for(;;) {
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                       AT91C_BASE_SSC->SSC_THR = ToSend[c];
+                       AT91C_BASE_SSC->SSC_THR = ~ToSend[c];
                        c++;
                        if(c == ToSendMax+3) {
                                break;
                        }
                }
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       volatile uint32_t r = AT91C_BASE_SSC->SSC_RHR;
-                       (void)r;
-               }
                WDT_HIT();
        }
 
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        c = 0;
-       getNext = FALSE;
        for(;;) {
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                       AT91C_BASE_SSC->SSC_THR = 0x43;
-               }
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       int8_t b;
-                       b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
-
+                       uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
                        // The samples are correlations against I and Q versions of the
-                       // tone that the tag AM-modulates, so every other sample is I,
-                       // every other is Q. We just want power, so abs(I) + abs(Q) is
-                       // close to what we want.
-                       if(getNext) {
-                               int8_t r = ABS(b) + ABS(prev);
+                       // tone that the tag AM-modulates. We just want power, 
+                       // so abs(I) + abs(Q) is close to what we want.
+                       int8_t i = iq >> 8;
+                       int8_t q = iq;
+                       uint8_t r = AMPLITUDE(i, q);
 
-                               dest[c++] = (uint8_t)r;
+                       dest[c++] = r;
 
-                               if(c >= 2000) {
-                                       break;
-                               }
-                       } else {
-                               prev = b;
+                       if(c >= 4000) {
+                               break;
                        }
-
-                       getNext = !getNext;
                }
        }
 }
@@ -648,16 +607,14 @@ void RecordRawAdcSamplesIso15693(void)
        uint8_t *dest = BigBuf_get_addr();
 
        int c = 0;
-       int getNext = 0;
-       int8_t prev = 0;
 
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
        // Setup SSC
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        // Start from off (no field generated)
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-       SpinDelay(200);
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       SpinDelay(200);
 
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
 
@@ -666,36 +623,24 @@ void RecordRawAdcSamplesIso15693(void)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        c = 0;
-       getNext = FALSE;
        for(;;) {
-               if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                       AT91C_BASE_SSC->SSC_THR = 0x43;
-               }
                if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                       int8_t b;
-                       b = (int8_t)AT91C_BASE_SSC->SSC_RHR;
-
+                       uint16_t iq = AT91C_BASE_SSC->SSC_RHR;
                        // The samples are correlations against I and Q versions of the
-                       // tone that the tag AM-modulates, so every other sample is I,
-                       // every other is Q. We just want power, so abs(I) + abs(Q) is
-                       // close to what we want.
-                       if(getNext) {
-                               int8_t r = ABS(b) + ABS(prev);
+                       // tone that the tag AM-modulates. We just want power, 
+                       // so abs(I) + abs(Q) is close to what we want.
+                       int8_t i = iq >> 8;
+                       int8_t q = iq;
+                       uint8_t r = AMPLITUDE(i, q);
 
-                               dest[c++] = (uint8_t)r;
+                       dest[c++] = r;
 
-                               if(c >= 7000) {
-                                       break;
-                               }
-                       } else {
-                               prev = b;
+                       if(c >= 14000) {
+                               break;
                        }
-
-                       getNext = !getNext;
-                       WDT_HIT();
                }
        }
-       Dbprintf("fin record");
+       Dbprintf("finished recording");
 }
 
 
@@ -716,7 +661,7 @@ void Iso15693InitReader() {
        SpinDelay(10);
 
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        // Give the tags time to energize
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
@@ -836,7 +781,7 @@ int SendDataTag(uint8_t *send, int sendlen, int init, int speed, uint8_t **recv)
        if (init) Iso15693InitReader();
 
        int answerLen=0;
-       uint8_t *answer = BigBuf_get_addr() + 3660;
+       uint8_t *answer = BigBuf_get_addr() + 4000;
        if (recv != NULL) memset(answer, 0, 100);
 
        if (!speed) {
@@ -957,7 +902,7 @@ void ReaderIso15693(uint32_t parameter)
 
        int answerLen1 = 0;
        int answerLen2 = 0;
-       int answerLen3 = 0;
+       // int answerLen3 = 0;
        int i = 0;
        int samples = 0;
        int tsamples = 0;
@@ -967,15 +912,15 @@ void ReaderIso15693(uint32_t parameter)
 
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
-       uint8_t *answer1 = BigBuf_get_addr() + 3660;
-       uint8_t *answer2 = BigBuf_get_addr() + 3760;
-       uint8_t *answer3 = BigBuf_get_addr() + 3860;
+       uint8_t *answer1 = BigBuf_get_addr() + 4000;
+       uint8_t *answer2 = BigBuf_get_addr() + 4100;
+       // uint8_t *answer3 = BigBuf_get_addr() + 4200;
        // Blank arrays
-       memset(answer1, 0x00, 300);
+       memset(answer1, 0x00, 200);
 
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
        // Setup SSC
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        // Start from off (no field generated)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -1025,21 +970,21 @@ void ReaderIso15693(uint32_t parameter)
                        TagUID[3],TagUID[2],TagUID[1],TagUID[0]);
 
 
-       Dbprintf("%d octets read from SELECT request:", answerLen2);
-       DbdecodeIso15693Answer(answerLen2,answer2);
-       Dbhexdump(answerLen2,answer2,true);
+       // Dbprintf("%d octets read from SELECT request:", answerLen2);
+       // DbdecodeIso15693Answer(answerLen2,answer2);
+       // Dbhexdump(answerLen2,answer2,true);
 
-       Dbprintf("%d octets read from XXX request:", answerLen3);
-       DbdecodeIso15693Answer(answerLen3,answer3);
-       Dbhexdump(answerLen3,answer3,true);
+       // Dbprintf("%d octets read from XXX request:", answerLen3);
+       // DbdecodeIso15693Answer(answerLen3,answer3);
+       // Dbhexdump(answerLen3,answer3,true);
 
        // read all pages
        if (answerLen1>=12 && DEBUG) {
                i=0;                    
                while (i<32) {  // sanity check, assume max 32 pages
                        BuildReadBlockRequest(TagUID,i);
-             TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);  
-         answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed);
+                       TransmitTo15693Tag(ToSend,ToSendMax,&tsamples, &wait);  
+                       answerLen2 = GetIso15693AnswerFromTag(answer2, 100, &samples, &elapsed);
                        if (answerLen2>0) {
                                Dbprintf("READ SINGLE BLOCK %d returned %d octets:",i,answerLen2);
                                DbdecodeIso15693Answer(answerLen2,answer2);
@@ -1073,11 +1018,11 @@ void SimTagIso15693(uint32_t parameter, uint8_t *uid)
 
        FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
 
-       uint8_t *buf = BigBuf_get_addr() + 3660;
+       uint8_t *buf = BigBuf_get_addr() + 4000;
        memset(buf, 0x00, 100);
        
        SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-       FpgaSetupSsc();
+       FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
 
        // Start from off (no field generated)
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -1177,7 +1122,7 @@ void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8
 
        if (recv) { 
                LED_B_ON();
-    cmd_send(CMD_ACK,recvlen>48?48:recvlen,0,0,recvbuf,48);
+               cmd_send(CMD_ACK,recvlen>48?48:recvlen,0,0,recvbuf,48);
                LED_B_OFF();    
                
                if (DEBUG) {
Impressum, Datenschutz