X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/39611e3d68fd067229797b9e18be57f3bbc9f3b2..2938b3cb12060875655ba9afbd98a69b7eea6d43:/armsrc/lfops.c?ds=inline diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 610781d2..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); } } + } } @@ -645,6 +648,18 @@ static void biphaseSimBit(uint8_t c, int *n, uint8_t clock, uint8_t *phase) *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 void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) { @@ -669,14 +684,16 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) for (i=0; i>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(); } @@ -1042,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; @@ -1051,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(); } @@ -1336,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)<>1)<>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(); @@ -1549,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) } } } @@ -1593,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); @@ -1607,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 ); @@ -1646,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(); }