X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/72c5877a74d0859b8da12575470a54a3b0ab8128..1f1f1955dc6521b9934d04677e9a3b5f23fa0e72:/armsrc/lfops.c?ds=inline diff --git a/armsrc/lfops.c b/armsrc/lfops.c index c8924007..75aa1342 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -403,6 +403,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) //wait until SSC_CLK goes HIGH while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { if(BUTTON_PRESS() || (usb_poll_validate_length() )) { + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); DbpString("Stopped"); return; } @@ -420,8 +421,9 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) LED_D_OFF(); //wait until SSC_CLK goes LOW while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { - if(BUTTON_PRESS()) { + if(BUTTON_PRESS() || (usb_poll_validate_length() )) { DbpString("Stopped"); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); return; } WDT_HIT(); @@ -436,6 +438,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) SpinDelayUs(gap); } } + } } @@ -642,6 +645,19 @@ static void biphaseSimBit(uint8_t c, int *n, uint8_t clock, uint8_t *phase) memset(dest+(*n), c ^ *phase, clock); *phase ^= 1; } + *n += clock; +} + +static void stAskSimBit(int *n, uint8_t clock) { + uint8_t *dest = BigBuf_get_addr(); + uint8_t halfClk = clock/2; + //ST = .5 high .5 low 1.5 high .5 low 1 high + memset(dest+(*n), 1, halfClk); + memset(dest+(*n) + halfClk, 0, halfClk); + memset(dest+(*n) + clock, 1, clock + halfClk); + memset(dest+(*n) + clock*2 + halfClk, 0, halfClk); + memset(dest+(*n) + clock*3, 1, clock); + *n += clock*4; } // args clock, ask/man or askraw, invert, transmission separator @@ -659,7 +675,7 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) for (i=0; i<size; i++){ biphaseSimBit(BitStream[i]^invert, &n, clk, &phase); } - if (BitStream[0]==BitStream[size-1]){ //run a second set inverted to keep phase in check + if (phase==1) { //run a second set inverted to keep phase in check for (i=0; i<size; i++){ biphaseSimBit(BitStream[i]^invert, &n, clk, &phase); } @@ -668,14 +684,16 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) for (i=0; i<size; i++){ askSimBit(BitStream[i]^invert, &n, clk, encoding); } - if (encoding==0 && BitStream[0]==BitStream[size-1]){ //run a second set inverted (for biphase phase) + if (encoding==0 && BitStream[0]==BitStream[size-1]){ //run a second set inverted (for ask/raw || biphase phase) for (i=0; i<size; i++){ askSimBit(BitStream[i]^invert^1, &n, clk, encoding); } } } - - if (separator==1) Dbprintf("sorry but separator option not yet available"); + if (separator==1 && encoding == 1) + stAskSimBit(&n, clk); + else 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 @@ -685,7 +703,7 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) //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(); SimulateTagLowFrequency(n, 0, ledcontrol); if (ledcontrol) LED_A_OFF(); @@ -825,13 +843,15 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) if (ledcontrol) LED_A_OFF(); *high = hi; *low = lo; - return; + break; } // reset } hi2 = hi = lo = idx = 0; WDT_HIT(); } + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); DbpString("Stopped"); if (ledcontrol) LED_A_OFF(); } @@ -916,12 +936,13 @@ void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol) } if (findone){ if (ledcontrol) LED_A_OFF(); - return; + break; } // reset idx = 0; WDT_HIT(); } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); DbpString("Stopped"); if (ledcontrol) LED_A_OFF(); } @@ -976,13 +997,14 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol) if (ledcontrol) LED_A_OFF(); *high=lo>>32; *low=lo & 0xFFFFFFFF; - return; + break; } } WDT_HIT(); hi = lo = size = idx = 0; clk = invert = errCnt = 0; } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); DbpString("Stopped"); if (ledcontrol) LED_A_OFF(); } @@ -1041,7 +1063,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) //LED_A_OFF(); *high=code; *low=code2; - return; + break; } code=code2=0; version=facilitycode=0; @@ -1050,6 +1072,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) WDT_HIT(); } + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); DbpString("Stopped"); if (ledcontrol) LED_A_OFF(); } @@ -1335,7 +1358,7 @@ void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7) data[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (7 << T55x7_MAXBLOCK_SHIFT); //TODO add selection of chip for Q5 or T55x7 - // data[0] = (((32-2)/2)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_PSK1 | 7 << T5555_MAXBLOCK_SHIFT; + // data[0] = (((32-2)>>1)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_PSK1 | 7 << T5555_MAXBLOCK_SHIFT; WriteT55xx(data, 0, 8); //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) // T5567WriteBlock(0x603E10E2,0); @@ -1344,7 +1367,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 << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT; + if (Q5) data[0] = ( ((32-2)>>1) << T5555_BITRATE_SHIFT) | 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(); @@ -1548,29 +1571,27 @@ void SendForward(uint8_t fwd_bit_count) { fwd_write_ptr = forwardLink_data; fwd_bit_sz = fwd_bit_count; - LED_D_ON(); - - // Set up FPGA, 125kHz + // Set up FPGA, 125kHz or 95 divisor 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 + WaitUS(55*8); //55 cycles off (8us each)for 4305 //another reader has 37 here... FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(16*8); //16 cycles on (8us each) + WaitUS(18*8); //18 cycles on (8us each) // now start writting while(fwd_bit_sz-- > 0) { //prepare next bit modulation if(((*fwd_write_ptr++) & 1) == 1) - SpinDelayUs(32*8); //32 cycles at 125Khz (8us each) + WaitUS(32*8); //32 cycles at 125Khz (8us each) else { //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) + WaitUS(23*8); //23 cycles off (8us each) FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on - SpinDelayUs(9*8); //16 cycles on (8us each) + WaitUS(18*8); //18 cycles on (8us each) } } } @@ -1592,13 +1613,12 @@ void EM4xLogin(uint32_t Password) { 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(); - uint32_t i = 0; // Clear destination buffer before sending the command BigBuf_Clear_ext(false); + LED_A_ON(); + StartTicks(); //If password mode do login if (PwdMode == 1) EM4xLogin(Pwd); @@ -1606,36 +1626,29 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); fwd_bit_count += Prepare_Addr( Address ); - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - SendForward(fwd_bit_count); - + WaitUS(400); // Now do the acquisition - i = 0; - 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) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; - if (i >= bufferlength) break; - } - } + DoPartialAcquisition(20, true, 6000); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_A_OFF(); cmd_send(CMD_ACK,0,0,0,0,0); - LED_D_OFF(); } -void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - +void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd) { + + bool PwdMode = (flag & 0xF); + uint8_t Address = (flag >> 8) & 0xFF; uint8_t fwd_bit_count; + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); + + LED_A_ON(); + StartTicks(); //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); + if (PwdMode) EM4xLogin(Pwd); forward_ptr = forwardLink_data; fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE ); @@ -1645,7 +1658,72 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode SendForward(fwd_bit_count); //Wait for write to complete - SpinDelay(20); + //SpinDelay(10); + + WaitUS(6500); + //Capture response if one exists + DoPartialAcquisition(20, true, 6000); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + LED_A_OFF(); + cmd_send(CMD_ACK,0,0,0,0,0); +} +/* +Reading a COTAG. + +COTAG needs the reader to send a startsequence and the card has an extreme slow datarate. +because of this, we can "sample" the data signal but we interpreate it to Manchester direct. + +READER START SEQUENCE: +burst 800 us, gap 2.2 msecs +burst 3.6 msecs gap 2.2 msecs +burst 800 us gap 2.2 msecs +pulse 3.6 msecs + +This triggers a COTAG tag to response +*/ +void Cotag(uint32_t arg0) { + +#define OFF { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); WaitUS(2035); } +#define ON(x) { FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); WaitUS((x)); } + + uint8_t rawsignal = arg0 & 0xF; + + LED_A_ON(); + + // Switching to LF image on FPGA. This might empty BigBuff + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + + //clear buffer now so it does not interfere with timing later + BigBuf_Clear_ext(false); + + // Set up FPGA, 132kHz to power up the tag + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 89); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + + // Connect the A/D to the peak-detected low-frequency path. + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + + // Now set up the SSC to get the ADC samples that are now streaming at us. + FpgaSetupSsc(); + + // start clock - 1.5ticks is 1us + StartTicks(); + + //send COTAG start pulse + ON(740) OFF + ON(3330) OFF + ON(740) OFF + ON(1000) + + switch(rawsignal) { + case 0: doCotagAcquisition(50000); break; + case 1: doCotagAcquisitionManchester(); break; + case 2: DoAcquisition_config(TRUE); break; + } + + // Turn the field off + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + cmd_send(CMD_ACK,0,0,0,0,0); + LED_A_OFF(); }