X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/d1057e7a2105d5e2696df185482176f22a5bd669..6a5d4e17f4afe29f84308fe5ca78782233d7b611:/armsrc/iso15693.c diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index 9a6ef9f0..c092b383 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -81,7 +81,10 @@ #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) {