X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/cd07302754ff43868ccb836376341ba9902a804f..f14c9bf915f883b5dfa8645dcaf1ded8d5978b90:/armsrc/lfops.c?ds=sidebyside diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 5b0b4904..4a0dca16 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -73,8 +73,6 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, DoAcquisition_config(false); } - - /* blank r/w tag data stream ...0000000000000000 01111111 1010101010101010101010101010101010101010101010101010101010101010 @@ -90,9 +88,9 @@ void ReadTItag(void) // when we read a TI tag we sample the zerocross line at 2Mhz // TI tags modulate a 1 as 16 cycles of 123.2Khz // TI tags modulate a 0 as 16 cycles of 134.2Khz - #define FSAMPLE 2000000 - #define FREQLO 123200 - #define FREQHI 134200 + #define FSAMPLE 2000000 + #define FREQLO 123200 + #define FREQHI 134200 signed char *dest = (signed char *)BigBuf_get_addr(); uint16_t n = BigBuf_max_traceLen(); @@ -244,11 +242,13 @@ void AcquireTiType(void) int i, j, n; // tag transmission is <20ms, sampling at 2M gives us 40K samples max // each sample is 1 bit stuffed into a uint32_t so we need 1250 uint32_t - #define TIBUFLEN 1250 + #define TIBUFLEN 1250 // clear buffer - uint32_t *BigBuf = (uint32_t *)BigBuf_get_addr(); - memset(BigBuf,0,BigBuf_max_traceLen()/sizeof(uint32_t)); + uint32_t *buf = (uint32_t *)BigBuf_get_addr(); + + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); // Set up the synchronous serial port AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN; @@ -286,7 +286,7 @@ void AcquireTiType(void) i = 0; for(;;) { if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer + buf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer i++; if(i >= TIBUFLEN) break; } WDT_HIT(); @@ -297,11 +297,12 @@ void AcquireTiType(void) AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT; char *dest = (char *)BigBuf_get_addr(); - n = TIBUFLEN*32; + n = TIBUFLEN * 32; + // unpack buffer - for (i=TIBUFLEN-1; i>=0; i--) { - for (j=0; j<32; j++) { - if(BigBuf[i] & (1 << j)) { + for (i = TIBUFLEN-1; i >= 0; i--) { + for (j = 0; j < 32; j++) { + if(buf[i] & (1 << j)) { dest[--n] = 1; } else { dest[--n] = -1; @@ -326,8 +327,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) crc = update_crc16(crc, (idhi>>16)&0xff); crc = update_crc16(crc, (idhi>>24)&0xff); } - Dbprintf("Writing to tag: %x%08x, crc=%x", - (unsigned int) idhi, (unsigned int) idlo, crc); + Dbprintf("Writing to tag: %x%08x, crc=%x", (unsigned int) idhi, (unsigned int) idlo, crc); // TI tags charge at 134.2Khz FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz @@ -391,33 +391,31 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; #define SHORT_COIL() LOW(GPIO_SSC_DOUT) - #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) + #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) i = 0; for(;;) { //wait until SSC_CLK goes HIGH while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { - if(BUTTON_PRESS() || usb_poll()) { + if(BUTTON_PRESS() || (usb_poll_validate_length() )) { DbpString("Stopped"); return; } WDT_HIT(); } - if (ledcontrol) - LED_D_ON(); + if (ledcontrol) LED_D_ON(); if(tab[i]) OPEN_COIL(); else SHORT_COIL(); - if (ledcontrol) - LED_D_OFF(); + if (ledcontrol) LED_D_OFF(); + //wait until SSC_CLK goes LOW while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { if(BUTTON_PRESS()) { @@ -571,12 +569,9 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol) } } - if (ledcontrol) - LED_A_ON(); + if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); - - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) LED_A_OFF(); } // prepare a waveform pattern in the buffer based on the ID given then @@ -651,7 +646,7 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) int ledcontrol = 1; int n=0, i=0; uint8_t clk = (arg1 >> 8) & 0xFF; - uint8_t encoding = arg1 & 1; + uint8_t encoding = arg1 & 0xFF; uint8_t separator = arg2 & 1; uint8_t invert = (arg2 >> 8) & 1; @@ -679,21 +674,10 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) if (separator==1) Dbprintf("sorry but separator option not yet available"); Dbprintf("Simulating with clk: %d, invert: %d, encoding: %d, separator: %d, n: %d",clk, invert, encoding, separator, n); - //DEBUG - //Dbprintf("First 32:"); - //uint8_t *dest = BigBuf_get_addr(); - //i=0; - //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]); - //i+=16; - //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]); - if (ledcontrol) - LED_A_ON(); - + if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); - - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) LED_A_OFF(); } //carrier can be 2,4 or 8 @@ -722,7 +706,7 @@ static void pskSimBit(uint8_t waveLen, int *n, uint8_t clk, uint8_t *curPhase, b // args clock, carrier, invert, void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) { - int ledcontrol=1; + int ledcontrol = 1; int n=0, i=0; uint8_t clk = arg1 >> 8; uint8_t carrier = arg1 & 0xFF; @@ -736,40 +720,29 @@ void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) } } Dbprintf("Simulating with Carrier: %d, clk: %d, invert: %d, n: %d",carrier, clk, invert, n); - //Dbprintf("DEBUG: First 32:"); - //uint8_t *dest = BigBuf_get_addr(); - //i=0; - //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]); - //i+=16; - //Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]); - if (ledcontrol) - LED_A_ON(); + if (ledcontrol) LED_A_ON(); SimulateTagLowFrequency(n, 0, ledcontrol); - - if (ledcontrol) - LED_A_OFF(); + if (ledcontrol) LED_A_OFF(); } // loop to get raw HID waveform then FSK demodulate the TAG ID from it void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = BigBuf_get_addr(); - //const size_t sizeOfBigBuff = BigBuf_max_traceLen(); size_t size = 0; uint32_t hi2=0, hi=0, lo=0; int idx=0; // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); DoAcquisition_default(-1,true); // FSK demodulator - //size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use size = 50*128*2; //big enough to catch 2 sequences of largest format idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo); @@ -777,12 +750,16 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) // go over previously decoded manchester data and decode into usable tag ID if (hi2 != 0){ //extra large HID tags 88/192 bits Dbprintf("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); + (unsigned int) hi2, + (unsigned int) hi, + (unsigned int) lo, + (unsigned int) (lo>>1) & 0xFFFF + ); }else { //standard HID tags 44/96 bits - //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd uint8_t bitlen = 0; uint32_t fc = 0; uint32_t cardnum = 0; + if (((hi>>5)&1) == 1){//if bit 38 is set then < 37 bit format is used uint32_t lo2=0; lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit @@ -820,11 +797,13 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) fc = ((hi&0xF)<<12)|(lo>>20); } } - //Dbprintf("TAG ID: %x%08x (%d)", - // (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); Dbprintf("TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d", - (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF, - (unsigned int) bitlen, (unsigned int) fc, (unsigned int) cardnum); + (unsigned int) hi, + (unsigned int) lo, + (unsigned int) (lo>>1) & 0xFFFF, + (unsigned int) bitlen, + (unsigned int) fc, + (unsigned int) cardnum); } if (findone){ if (ledcontrol) LED_A_OFF(); @@ -841,6 +820,94 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) if (ledcontrol) LED_A_OFF(); } +// loop to get raw HID waveform then FSK demodulate the TAG ID from it +void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol) +{ + uint8_t *dest = BigBuf_get_addr(); + size_t size; + int idx=0; + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(95, true); + + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { + + WDT_HIT(); + if (ledcontrol) LED_A_ON(); + + DoAcquisition_default(-1,true); + // FSK demodulator + size = 50*128*2; //big enough to catch 2 sequences of largest format + idx = AWIDdemodFSK(dest, &size); + + if (idx>0 && size==96){ + // Index map + // 0 10 20 30 40 50 60 + // | | | | | | | + // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96 + // ----------------------------------------------------------------------------- + // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1 + // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96 + // |---26 bit---| |-----117----||-------------142-------------| + // b = format bit len, o = odd parity of last 3 bits + // f = facility code, c = card number + // w = wiegand parity + // (26 bit format shown) + + //get raw ID before removing parities + uint32_t rawLo = bytebits_to_byte(dest+idx+64,32); + uint32_t rawHi = bytebits_to_byte(dest+idx+32,32); + uint32_t rawHi2 = bytebits_to_byte(dest+idx,32); + + size = removeParity(dest, idx+8, 4, 1, 88); + // ok valid card found! + + // Index map + // 0 10 20 30 40 50 60 + // | | | | | | | + // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456 + // ----------------------------------------------------------------------------- + // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000 + // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + // |26 bit| |-117--| |-----142------| + // b = format bit len, o = odd parity of last 3 bits + // f = facility code, c = card number + // w = wiegand parity + // (26 bit format shown) + + uint32_t fc = 0; + uint32_t cardnum = 0; + uint32_t code1 = 0; + uint32_t code2 = 0; + uint8_t fmtLen = bytebits_to_byte(dest,8); + if (fmtLen==26){ + fc = bytebits_to_byte(dest+9, 8); + cardnum = bytebits_to_byte(dest+17, 16); + code1 = bytebits_to_byte(dest+8,fmtLen); + Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo); + } else { + cardnum = bytebits_to_byte(dest+8+(fmtLen-17), 16); + if (fmtLen>32){ + code1 = bytebits_to_byte(dest+8,fmtLen-32); + code2 = bytebits_to_byte(dest+8+(fmtLen-32),32); + Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo); + } else{ + code1 = bytebits_to_byte(dest+8,fmtLen); + Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo); + } + } + if (findone){ + if (ledcontrol) LED_A_OFF(); + return; + } + // reset + } + idx = 0; + WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); +} + void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = BigBuf_get_addr(); @@ -852,7 +919,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); @@ -913,7 +980,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // Configure to go in 125Khz listen mode LFSetupFPGAForADC(95, true); - while(!BUTTON_PRESS()) { + while(!BUTTON_PRESS() && !usb_poll_validate_length()) { WDT_HIT(); if (ledcontrol) LED_A_ON(); DoAcquisition_default(-1,true); @@ -953,7 +1020,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) code = bytebits_to_byte(dest+idx,32); code2 = bytebits_to_byte(dest+idx+32,32); version = bytebits_to_byte(dest+idx+27,8); //14,4 - facilitycode = bytebits_to_byte(dest+idx+18,8); + facilitycode = bytebits_to_byte(dest+idx+18,8); number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9 crc = bytebits_to_byte(dest+idx+54,8); @@ -968,7 +1035,6 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // if we're only looking for one tag if (findone){ if (ledcontrol) LED_A_OFF(); - //LED_A_OFF(); *high=code; *low=code2; return; @@ -990,14 +1056,14 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) */ /* T55x7 configuration register definitions */ -#define T55x7_POR_DELAY 0x00000001 -#define T55x7_ST_TERMINATOR 0x00000008 -#define T55x7_PWD 0x00000010 +#define T55x7_POR_DELAY 0x00000001 +#define T55x7_ST_TERMINATOR 0x00000008 +#define T55x7_PWD 0x00000010 #define T55x7_MAXBLOCK_SHIFT 5 -#define T55x7_AOR 0x00000200 -#define T55x7_PSKCF_RF_2 0 -#define T55x7_PSKCF_RF_4 0x00000400 -#define T55x7_PSKCF_RF_8 0x00000800 +#define T55x7_AOR 0x00000200 +#define T55x7_PSKCF_RF_2 0 +#define T55x7_PSKCF_RF_4 0x00000400 +#define T55x7_PSKCF_RF_8 0x00000800 #define T55x7_MODULATION_DIRECT 0 #define T55x7_MODULATION_PSK1 0x00001000 #define T55x7_MODULATION_PSK2 0x00002000 @@ -1008,17 +1074,19 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) #define T55x7_MODULATION_FSK2a 0x00007000 #define T55x7_MODULATION_MANCHESTER 0x00008000 #define T55x7_MODULATION_BIPHASE 0x00010000 -#define T55x7_BITRATE_RF_8 0 -#define T55x7_BITRATE_RF_16 0x00040000 -#define T55x7_BITRATE_RF_32 0x00080000 -#define T55x7_BITRATE_RF_40 0x000C0000 -#define T55x7_BITRATE_RF_50 0x00100000 -#define T55x7_BITRATE_RF_64 0x00140000 +#define T55x7_MODULATION_DIPHASE 0x00018000 +//#define T55x7_MODULATION_BIPHASE57 0x00011000 +#define T55x7_BITRATE_RF_8 0 +#define T55x7_BITRATE_RF_16 0x00040000 +#define T55x7_BITRATE_RF_32 0x00080000 +#define T55x7_BITRATE_RF_40 0x000C0000 +#define T55x7_BITRATE_RF_50 0x00100000 +#define T55x7_BITRATE_RF_64 0x00140000 #define T55x7_BITRATE_RF_100 0x00180000 #define T55x7_BITRATE_RF_128 0x001C0000 /* T5555 (Q5) configuration register definitions */ -#define T5555_ST_TERMINATOR 0x00000001 +#define T5555_ST_TERMINATOR 0x00000001 #define T5555_MAXBLOCK_SHIFT 0x00000001 #define T5555_MODULATION_MANCHESTER 0 #define T5555_MODULATION_PSK1 0x00000010 @@ -1028,25 +1096,28 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) #define T5555_MODULATION_FSK2 0x00000050 #define T5555_MODULATION_BIPHASE 0x00000060 #define T5555_MODULATION_DIRECT 0x00000070 -#define T5555_INVERT_OUTPUT 0x00000080 -#define T5555_PSK_RF_2 0 -#define T5555_PSK_RF_4 0x00000100 -#define T5555_PSK_RF_8 0x00000200 -#define T5555_USE_PWD 0x00000400 -#define T5555_USE_AOR 0x00000800 -#define T5555_BITRATE_SHIFT 12 -#define T5555_FAST_WRITE 0x00004000 -#define T5555_PAGE_SELECT 0x00008000 +#define T5555_INVERT_OUTPUT 0x00000080 +#define T5555_PSK_RF_2 0 +#define T5555_PSK_RF_4 0x00000100 +#define T5555_PSK_RF_8 0x00000200 +#define T5555_USE_PWD 0x00000400 +#define T5555_USE_AOR 0x00000800 +#define T5555_BITRATE_SHIFT 12 +#define T5555_FAST_WRITE 0x00004000 +#define T5555_PAGE_SELECT 0x00008000 /* * Relevant times in microsecond * To compensate antenna falling times shorten the write times * and enlarge the gap ones. + * Q5 tags seems to have issues when these values changes. */ -#define START_GAP 50*8 // 10 - 50fc 250 -#define WRITE_GAP 20*8 // 8 - 30fc -#define WRITE_0 24*8 // 16 - 31fc 24fc 192 -#define WRITE_1 54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550 + +#define START_GAP 50*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc) +#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc) +#define WRITE_0 16*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc) +#define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550 +#define READ_GAP 52*8 // VALUES TAKEN FROM EM4x function: SendForward // START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle) @@ -1060,15 +1131,16 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz // Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier) // T0 = TIMER_CLOCK1 / 125000 = 192 -// 1 Cycle = 8 microseconds(us) +// 1 Cycle = 8 microseconds(us) == 1 field clock -#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..) +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 +} // Write one bit to card -void T55xxWriteBit(int bit) -{ - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz +void T55xxWriteBit(int bit) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); if (!bit) SpinDelayUs(WRITE_0); @@ -1079,147 +1151,124 @@ void T55xxWriteBit(int bit) } // Write one card block in page 0, no lock -void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) -{ +void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { + LED_A_ON(); + uint32_t i = 0; // Set up FPGA, 125kHz - // Wait for config.. (192+8190xPOW)x8 == 67ms - LFSetupFPGAForADC(0, true); - - // Now start writting + LFSetupFPGAForADC(95, true); + + // Trigger T55x7 in mode. FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); - // Opcode + // Opcode 10 T55xxWriteBit(1); T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ - // Pwd + // Send Pwd for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Pwd & i); } - // Lock bit + // Send Lock bit T55xxWriteBit(0); - // Data + // Send Data for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Data & i); - // Block + // Send Block number for (i = 0x04; i != 0; i >>= 1) T55xxWriteBit(Block & i); - // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, + // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550, // so wait a little more) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - SpinDelay(20); + TurnReadLFOn(20 * 1000); + + // turn field off FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + cmd_send(CMD_ACK,0,0,0,0,0); + LED_A_OFF(); } -void TurnReadLFOn(){ - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelayUs(8*150); -} - - // Read one card block in page 0 -void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) -{ +void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { + LED_A_ON(); + uint32_t i = 0; - uint8_t *dest = BigBuf_get_addr(); - uint16_t bufferlength = BigBuf_max_traceLen(); - if ( bufferlength > T55xx_SAMPLES_SIZE ) - bufferlength = T55xx_SAMPLES_SIZE; + + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); - // Clear destination buffer before sending the command - memset(dest, 0x80, bufferlength); + //make sure block is at max 7 + Block &= 0x7; // Set up FPGA, 125kHz - // Wait for config.. (192+8190xPOW)x8 == 67ms - LFSetupFPGAForADC(0, true); + LFSetupFPGAForADC(95, true); + + // Trigger T55x7 in mode. + // Trigger T55x7 Direct Access Mode FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); - - // Opcode + + // Opcode 10 T55xxWriteBit(1); T55xxWriteBit(0); //Page 0 + if (PwdMode == 1){ - // Pwd + // Send Pwd for (i = 0x80000000; i != 0; i >>= 1) T55xxWriteBit(Pwd & i); } - // Lock bit + // Send a zero bit separation T55xxWriteBit(0); - // Block + + // Send Block number for (i = 0x04; i != 0; i >>= 1) T55xxWriteBit(Block & i); // Turn field on to read the response - TurnReadLFOn(); - // Now do the acquisition - i = 0; - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - LED_D_OFF(); - if (i >= bufferlength) break; - } - } - + TurnReadLFOn(READ_GAP); + + // Acquisition + doT55x7Acquisition(); + + // turn field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); cmd_send(CMD_ACK,0,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + LED_A_OFF(); } // Read card traceability data (page 1) void T55xxReadTrace(void){ - - uint32_t i = 0; - uint8_t *dest = BigBuf_get_addr(); - uint16_t bufferlength = BigBuf_max_traceLen(); - if ( bufferlength > T55xx_SAMPLES_SIZE ) - bufferlength= T55xx_SAMPLES_SIZE; + LED_A_ON(); - // Clear destination buffer before sending the command - memset(dest, 0x80, bufferlength); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); - LFSetupFPGAForADC(0, true); + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); + + // Trigger T55x7 Direct Access Mode FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); - // Opcode + // Opcode 11 T55xxWriteBit(1); T55xxWriteBit(1); //Page 1 // Turn field on to read the response - TurnReadLFOn(); - - // Now do the acquisition - for(;;) { - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { - AT91C_BASE_SSC->SSC_THR = 0x43; - LED_D_ON(); - } - if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - LED_D_OFF(); + TurnReadLFOn(READ_GAP); - if (i >= bufferlength) break; - } - } + // Acquisition + doT55x7Acquisition(); + // turn field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); cmd_send(CMD_ACK,0,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + LED_A_OFF(); } /*-------------- Cloning routines -----------*/ @@ -1438,8 +1487,11 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) // Clock rate is stored in bits 8-15 of the card value clock = (card & 0xFF00) >> 8; Dbprintf("Clock rate: %d", clock); - switch (clock) - { + switch (clock) { + case 50: + clock = T55x7_BITRATE_RF_50; + case 40: + clock = T55x7_BITRATE_RF_40; case 32: clock = T55x7_BITRATE_RF_32; break; @@ -1478,7 +1530,6 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) // Clone Indala 64-bit tag by UID to T55x7 void CopyIndala64toT55x7(int hi, int lo) { - //Program the 2 data blocks for supplied 64bit UID // and the block 0 for Indala64 format T55xxWriteBlock(hi,1,0,0); @@ -1492,12 +1543,10 @@ void CopyIndala64toT55x7(int hi, int lo) // T5567WriteBlock(0x603E1042,0); DbpString("DONE!"); - } void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7) { - //Program the 7 data blocks for supplied 224bit UID // and the block 0 for Indala224 format T55xxWriteBlock(uid1,1,0,0); @@ -1516,277 +1565,8 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int // T5567WriteBlock(0x603E10E2,0); DbpString("DONE!"); - -} - - -#define abs(x) ( ((x)<0) ? -(x) : (x) ) -#define max(x,y) ( x 18000 ) - GraphTraceLen = 18000; - - - int i, j, lastval, bitidx, half_switch; - int clock = 64; - int tolerance = clock / 8; - int pmc, block_done; - int lc, warnings = 0; - int num_blocks = 0; - int lmin=128, lmax=128; - uint8_t dir; - - LFSetupFPGAForADC(95, true); - DoAcquisition_default(0, true); - - lmin = 64; - lmax = 192; - - i = 2; - - /* Find first local max/min */ - if(dest[1] > dest[0]) { - while(i < GraphTraceLen) { - if( !(dest[i] > dest[i-1]) && dest[i] > lmax) - break; - i++; - } - dir = 0; - } - else { - while(i < GraphTraceLen) { - if( !(dest[i] < dest[i-1]) && dest[i] < lmin) - break; - i++; - } - dir = 1; - } - - lastval = i++; - half_switch = 0; - pmc = 0; - block_done = 0; - - for (bitidx = 0; i < GraphTraceLen; i++) - { - if ( (dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[i] < lmin)) - { - lc = i - lastval; - lastval = i; - - // Switch depending on lc length: - // Tolerance is 1/8 of clock rate (arbitrary) - if (abs(lc-clock/4) < tolerance) { - // 16T0 - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33+16)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else { - pmc = i; - } - } else if (abs(lc-clock/2) < tolerance) { - // 32TO - if((i - pmc) == lc) { /* 16T0 was previous one */ - /* It's a PMC ! */ - i += (128+127+16+32+33)-1; - lastval = i; - pmc = 0; - block_done = 1; - } - else if(half_switch == 1) { - bits[bitidx++] = 0; - half_switch = 0; - } - else - half_switch++; - } else if (abs(lc-clock) < tolerance) { - // 64TO - bits[bitidx++] = 1; - } else { - // Error - warnings++; - if (warnings > 10) - { - Dbprintf("Error: too many detection errors, aborting."); - return 0; - } - } - - if(block_done == 1) { - if(bitidx == 128) { - for(j=0; j<16; j++) { - blocks[num_blocks][j] = 128*bits[j*8+7]+ - 64*bits[j*8+6]+ - 32*bits[j*8+5]+ - 16*bits[j*8+4]+ - 8*bits[j*8+3]+ - 4*bits[j*8+2]+ - 2*bits[j*8+1]+ - bits[j*8]; - - } - num_blocks++; - } - bitidx = 0; - block_done = 0; - half_switch = 0; - } - if(i < GraphTraceLen) - dir =(dest[i-1] > dest[i]) ? 0 : 1; - } - if(bitidx==255) - bitidx=0; - warnings = 0; - if(num_blocks == 4) break; - } - memcpy(outBlocks, blocks, 16*num_blocks); - return num_blocks; } -int IsBlock0PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled - return 1; - if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ? - return 1; - return 0; -} - -int IsBlock1PCF7931(uint8_t *Block) { - // Assume RFU means 0 :) - if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0) - if((Block[14] & 0x7f) <= 9 && Block[15] <= 9) - return 1; - - return 0; -} - -#define ALLOC 16 - -void ReadPCF7931() { - uint8_t Blocks[8][17]; - uint8_t tmpBlocks[4][16]; - int i, j, ind, ind2, n; - int num_blocks = 0; - int max_blocks = 8; - int ident = 0; - int error = 0; - int tries = 0; - - memset(Blocks, 0, 8*17*sizeof(uint8_t)); - - do { - memset(tmpBlocks, 0, 4*16*sizeof(uint8_t)); - n = DemodPCF7931((uint8_t**)tmpBlocks); - if(!n) - error++; - if(error==10 && num_blocks == 0) { - Dbprintf("Error, no tag or bad tag"); - return; - } - else if (tries==20 || error==10) { - Dbprintf("Error reading the tag"); - Dbprintf("Here is the partial content"); - goto end; - } - - for(i=0; i= 0; ind--,ind2--) { - if(ind2 < 0) - ind2 = max_blocks; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) { - if(ind2 > max_blocks) - ind2 = 0; - if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found - // Dbprintf("Tmp %d -> Block %d", ind, ind2); - memcpy(Blocks[ind2], tmpBlocks[ind], 16); - Blocks[ind2][ALLOC] = 1; - num_blocks++; - if(num_blocks == max_blocks) goto end; - } - } - } - } - } - } - } - tries++; - if (BUTTON_PRESS()) return; - } while (num_blocks != max_blocks); - end: - Dbprintf("-----------------------------------------"); - Dbprintf("Memory content:"); - Dbprintf("-----------------------------------------"); - for(i=0; i", i); - } - Dbprintf("-----------------------------------------"); - - return ; -} - - //----------------------------------- // EM4469 / EM4305 routines //----------------------------------- @@ -1795,7 +1575,6 @@ void ReadPCF7931() { #define FWD_CMD_READ 0x9 #define FWD_CMD_DISABLE 0x5 - uint8_t forwardLink_data[64]; //array of forwarded bits uint8_t * forward_ptr; //ptr for forward message preparation uint8_t fwd_bit_sz; //forwardlink bit counter @@ -1805,9 +1584,7 @@ uint8_t * fwd_write_ptr; //forwardlink bit pointer // prepares command bits // see EM4469 spec //==================================================================== -//-------------------------------------------------------------------- uint8_t Prepare_Cmd( uint8_t cmd ) { - //-------------------------------------------------------------------- *forward_ptr++ = 0; //start bit *forward_ptr++ = 0; //second pause for 4050 code @@ -1827,10 +1604,7 @@ uint8_t Prepare_Cmd( uint8_t cmd ) { // prepares address bits // see EM4469 spec //==================================================================== - -//-------------------------------------------------------------------- uint8_t Prepare_Addr( uint8_t addr ) { - //-------------------------------------------------------------------- register uint8_t line_parity; @@ -1851,10 +1625,7 @@ uint8_t Prepare_Addr( uint8_t addr ) { // prepares data bits intreleaved with parity bits // see EM4469 spec //==================================================================== - -//-------------------------------------------------------------------- uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) { - //-------------------------------------------------------------------- register uint8_t line_parity; register uint8_t column_parity; @@ -1898,21 +1669,14 @@ void SendForward(uint8_t fwd_bit_count) { LED_D_ON(); - //Field on - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - + // Set up FPGA, 125kHz + LFSetupFPGAForADC(95, true); + // force 1st mod pulse (start gap must be longer for 4305) fwd_bit_sz--; //prepare next bit modulation fwd_write_ptr++; FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off SpinDelayUs(55*8); //55 cycles off (8us each)for 4305 - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on SpinDelayUs(16*8); //16 cycles on (8us each) @@ -1924,7 +1688,6 @@ void SendForward(uint8_t fwd_bit_count) { //These timings work for 4469/4269/4305 (with the 55*8 above) FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off SpinDelayUs(23*8); //16-4 cycles off (8us each) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on SpinDelayUs(9*8); //16 cycles on (8us each) } @@ -1943,20 +1706,18 @@ void EM4xLogin(uint32_t Password) { //Wait for command to complete SpinDelay(20); - } void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { + uint8_t fwd_bit_count; uint8_t *dest = BigBuf_get_addr(); - uint16_t bufferlength = BigBuf_max_traceLen(); + uint16_t bufsize = BigBuf_max_traceLen(); uint32_t i = 0; - // Clear destination buffer before sending the command 0x80 = average. - memset(dest, 0x80, bufferlength); + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); - uint8_t fwd_bit_count; - //If password mode do login if (PwdMode == 1) EM4xLogin(Pwd); @@ -1980,12 +1741,12 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; ++i; - if (i >= bufferlength) break; + if (i >= bufsize) break; } } - + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off cmd_send(CMD_ACK,0,0,0,0,0); - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off LED_D_OFF(); } @@ -2008,3 +1769,15 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off LED_D_OFF(); } + +void CopyViKingtoT55x7(uint32_t block1, uint32_t block2) { + LED_D_ON(); + T55xxWriteBlock(block1,1,0,0); + T55xxWriteBlock(block2,2,0,0); + T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T55x7_MAXBLOCK_SHIFT,0,0,0); + // T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T5555_MAXBLOCK_SHIFT,0,0,1); + // ICEMAN NOTES: + // Shouldn't this one be: T55x7_MAXBLOCK_SHIFT and 0 in password mode + LED_D_OFF(); +} +