X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/69d88ec4639d7bec0d3b226c2f4d2186703e9055..f97d4e2378e04397b3c884d10acb79725dee4e06:/armsrc/lfops.c diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 072961a2..d29ec375 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -16,7 +16,7 @@ #include "string.h" // split into two routines so we can avoid timing issues after sending commands // -void DoAcquisition125k_internal(bool silent) +void DoAcquisition125k_internal(int trigger_threshold,bool silent) { uint8_t *dest = (uint8_t *)BigBuf; int n = sizeof(BigBuf); @@ -31,25 +31,30 @@ void DoAcquisition125k_internal(bool silent) } if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - i++; LED_D_OFF(); - if (i >= n) break; + if (trigger_threshold != -1 && dest[i] < trigger_threshold) + continue; + else + trigger_threshold = -1; + if (++i >= n) break; } } - if( ! silent) + if(!silent) { Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]); + } } - -void DoAcquisition125k(void) +void DoAcquisition125k(int trigger_threshold) { - DoAcquisition125k_internal(false); + DoAcquisition125k_internal(trigger_threshold, false); } -void SetupToAcquireRawAdcSamples(int divisor) +//void SetupToAcquireRawAdcSamples(int divisor) +void LFSetupFPGAForADC(int divisor, bool lf_field) { + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); if ( (divisor == 1) || (divisor < 0) || (divisor > 255) ) FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz else if (divisor == 0) @@ -57,23 +62,29 @@ void SetupToAcquireRawAdcSamples(int divisor) else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0)); // Connect the A/D to the peak-detected low-frequency path. SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Give it a bit of time for the resonant antenna to settle. SpinDelay(50); - // Now set up the SSC to get the ADC samples that are now streaming at us. FpgaSetupSsc(); } void AcquireRawAdcSamples125k(int divisor) { - SetupToAcquireRawAdcSamples(divisor); + LFSetupFPGAForADC(divisor, true); // Now call the acquisition routine - DoAcquisition125k_internal(false); + DoAcquisition125k_internal(-1,false); +} +void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) +{ + LFSetupFPGAForADC(divisor, false); + DoAcquisition125k(trigger_threshold, false); +} + + } void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) @@ -81,6 +92,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, int at134khz; /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(2500); @@ -95,7 +107,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // Give it a bit of time for the resonant antenna to settle. SpinDelay(50); @@ -115,7 +127,7 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); if(*(command++) == '0') SpinDelayUs(period_0); @@ -130,10 +142,10 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, else FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // now do the read - DoAcquisition125k(); + DoAcquisition125k(-1); } /* blank r/w tag data stream @@ -170,6 +182,7 @@ void ReadTItag(void) uint32_t threshold = (sampleslo - sampleshi + 1)>>1; // TI tags charge at 134.2Khz + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz // Place FPGA in passthrough mode, in this mode the CROSS_LO line @@ -377,6 +390,7 @@ void AcquireTiType(void) // if not provided a valid crc will be computed from the data and written. void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) { + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); if(crc == 0) { crc = update_crc16(crc, (idlo)&0xff); crc = update_crc16(crc, (idlo>>8)&0xff); @@ -448,6 +462,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) int i; uint8_t *tab = (uint8_t *)BigBuf; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; @@ -605,68 +620,27 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol) if (ledcontrol) LED_A_OFF(); } -void setup_for_125khz() -{ - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); - - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); - - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); - -} -void get_samples(int ledcontrol, uint8_t* dest, int size) +size_t fsk_demod(uint8_t * dest, size_t size) { - int i = 0; - - memset(dest,128,size); - for(;;) { - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) { - AT91C_BASE_SSC->SSC_THR = 0x43; - if (ledcontrol) LED_D_ON(); - } - if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) { - dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; - // we don't care about actual value, only if it's more or less than a - // threshold essentially we capture zero crossings for later analysis - if(dest[i] < 127) dest[i] = 0; else dest[i] = 1; - i++; - if (ledcontrol) LED_D_OFF(); - if(i >= size) { - break; - } - } - } -} - -uint8_t fsk_demod(uint8_t * dest, int size) -{ - uint8_t last_transition = 0; - uint8_t idx = 1; + uint32_t last_transition = 0; + uint32_t idx = 1; // we don't care about actual value, only if it's more or less than a // threshold essentially we capture zero crossings for later analysis uint8_t threshold_value = 127; - WDT_HIT(); - // sync to first lo-hi transition, and threshold //Need to threshold first sample if(dest[0] < threshold_value) dest[0] = 0; else dest[0] = 1; - uint8_t numBits = 0; + size_t numBits = 0; // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8) // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10 for(idx = 1; idx < size; idx++) { - // threshold current value if (dest[idx] < threshold_value) dest[idx] = 0; else dest[idx] = 1; @@ -686,12 +660,13 @@ uint8_t fsk_demod(uint8_t * dest, int size) return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 } -uint8_t aggregate_bits(uint8_t *dest,uint8_t size, uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, uint8_t maxConsequtiveBits ) + +size_t aggregate_bits(uint8_t *dest,size_t size, uint8_t h2l_crossing_value,uint8_t l2h_crossing_value, uint8_t maxConsequtiveBits ) { uint8_t lastval=dest[0]; - uint8_t idx=0; - uint8_t numBits=0; - uint8_t n=1, i=0; + uint32_t idx=0; + size_t numBits=0; + uint32_t n=1; for( idx=1; idx < size; idx++) { @@ -700,14 +675,16 @@ uint8_t aggregate_bits(uint8_t *dest,uint8_t size, uint8_t h2l_crossing_value,ui continue; } //if lastval was 1, we have a 1->0 crossing - if ( lastval ) { - n=(n+1)/7; + if ( dest[idx-1] ) { + n=(n+1) / h2l_crossing_value; } else {// 0->1 crossing - n=(n+1)/6; + n=(n+1) / l2h_crossing_value; } - if(n < 13) + if (n == 0) n = 1; + + if(n < maxConsequtiveBits) { - memset(dest+i, lastval ^ 1, n); + memset(dest+numBits, dest[idx-1] , n); numBits += n; } n=0; @@ -722,34 +699,26 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = (uint8_t *)BigBuf; - int size=0, idx=0, found=0; + size_t size=0,idx=0; //, found=0; uint32_t hi2=0, hi=0, lo=0; - // Configure to go in 125Khz listen mode - SetupToAcquireRawAdcSamples(0); - for(;;) { - WDT_HIT(); - if (ledcontrol) - LED_A_ON(); - if(BUTTON_PRESS()) { - DbpString("Stopped"); - if (ledcontrol) - LED_A_OFF(); - return; - } + while(!BUTTON_PRESS()) { + + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(0, true) + WDT_HIT(); + if (ledcontrol) LED_A_ON(); DoAcquisition125k_internal(true); size = sizeof(BigBuf); // FSK demodulator size = fsk_demod(dest, size); - WDT_HIT(); // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns - // 1->0 : fc/8 in sets of 6 // 0->1 : fc/10 in sets of 5 size = aggregate_bits(dest,size, 6,5,5); @@ -759,36 +728,32 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) // final loop, go over previously decoded manchester data and decode into usable tag ID // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0 uint8_t frame_marker_mask[] = {1,1,1,0,0,0}; + int numshifts = 0; + idx = 0; + while( idx + sizeof(frame_marker_mask) < size) { + // search for a start of frame marker + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=sizeof(frame_marker_mask); - for( idx=0; idx < size-sizeof(frame_marker_mask); idx++) { - - if (found) { - if(dest[idx] == dest[idx+1]) - {// 1 1 or 00 - found=0; - hi2=0; - hi=0; - lo=0; - }else - { - //Shift in a bit. Start by shifting high registers + while(dest[idx] != dest[idx+1] && idx < size-2) + { // Keep going until next frame marker (or error) + // Shift in a bit. Start by shifting high registers hi2 = (hi2<<1)|(hi>>31); hi = (hi<<1)|(lo>>31); //Then, shift in a 0 or one into low if (dest[idx] && !dest[idx+1]) // 1 0 lo=(lo<<1)|0; else // 0 1 - lo=(lo<<1)|1; + lo=(lo<<1)| + 1; + numshifts ++; + idx += 2; } - idx++; - } - - // search for a start of frame marker - if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) - { // Found start of frame marker - found=1; - idx+=sizeof(frame_marker_mask); - if (found && (hi2|hi|lo)) { + //Dbprintf("Num shifts: %d ", numshifts); + // Hopefully, we read a tag and hit upon the next frame marker + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { if (hi2 != 0){ Dbprintf("TAG ID: %x%08x%08x (%d)", (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); @@ -797,22 +762,21 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) Dbprintf("TAG ID: %x%08x (%d)", (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); } - /* if we're only looking for one tag */ - if (findone) - { - *high = hi; - *low = lo; - return; - } - hi2=0; - hi=0; - lo=0; - found=0; } + + // reset + hi2 = hi = lo = 0; + numshifts = 0; + }else + { + idx++; } } WDT_HIT(); + } + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } uint32_t bytebits_to_byte(uint8_t* src, int numbits) @@ -830,22 +794,18 @@ uint32_t bytebits_to_byte(uint8_t* src, int numbits) void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = (uint8_t *)BigBuf; - int size=0, idx=0; + + size_t size=0, idx=0; uint32_t code=0, code2=0; - //uint32_t hi2=0, hi=0, lo=0; - setup_for_125khz(); - for(;;) { + while(!BUTTON_PRESS()) { + + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(0, true); + WDT_HIT(); - if (ledcontrol) - LED_A_ON(); - if(BUTTON_PRESS()) { - DbpString("Stopped"); - if (ledcontrol) - LED_A_OFF(); - return; - } + if (ledcontrol) LED_A_ON(); DoAcquisition125k_internal(true); size = sizeof(BigBuf); @@ -853,6 +813,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // FSK demodulator size = fsk_demod(dest, size); WDT_HIT(); + // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns // 1->0 : fc/8 in sets of 7 // 0->1 : fc/10 in sets of 6 @@ -860,6 +821,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) WDT_HIT(); + //Handle the data uint8_t mask[] = {0,0,0,0,0,0,0,0,0,1}; for( idx=0; idx < size - 64; idx++) { @@ -890,8 +852,10 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) return; } } + WDT_HIT(); } - WDT_HIT(); + DbpString("Stopped"); + if (ledcontrol) LED_A_OFF(); } /*------------------------------ @@ -961,8 +925,9 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) // Write one bit to card void T55xxWriteBit(int bit) { + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); if (bit == 0) SpinDelayUs(WRITE_0); else @@ -976,8 +941,9 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod { unsigned int i; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + 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 @@ -1009,7 +975,7 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod // Now 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_READER); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); SpinDelay(20); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); } @@ -1020,6 +986,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) uint8_t *dest = (uint8_t *)BigBuf; int m=0, i=0; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); m = sizeof(BigBuf); // Clear destination buffer before sending the command memset(dest, 128, m); @@ -1030,7 +997,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) LED_D_ON(); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + 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 @@ -1056,7 +1023,7 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) // Turn field on to read the response FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // Now do the acquisition i = 0; @@ -1084,6 +1051,7 @@ void T55xxReadTrace(void){ uint8_t *dest = (uint8_t *)BigBuf; int m=0, i=0; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); m = sizeof(BigBuf); // Clear destination buffer before sending the command memset(dest, 128, m); @@ -1094,7 +1062,7 @@ void T55xxReadTrace(void){ LED_D_ON(); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + 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 @@ -1110,7 +1078,7 @@ void T55xxReadTrace(void){ // Turn field on to read the response FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // Now do the acquisition i = 0; @@ -1799,8 +1767,9 @@ 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_READER); + 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 @@ -1812,7 +1781,7 @@ void SendForward(uint8_t fwd_bit_count) { 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_READER);//field on + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on SpinDelayUs(16*8); //16 cycles on (8us each) // now start writting @@ -1824,7 +1793,7 @@ void SendForward(uint8_t fwd_bit_count) { 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_READER);//field on + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on SpinDelayUs(9*8); //16 cycles on (8us each) } }