X-Git-Url: http://cvs.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/3ad48540d4d77f50cc62d16acb78f17019ef431d..f97d4e2378e04397b3c884d10acb79725dee4e06:/armsrc/lfops.c diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 6b131c26..d29ec375 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -15,6 +15,43 @@ #include "crc16.h" #include "string.h" +// split into two routines so we can avoid timing issues after sending commands // +void DoAcquisition125k_internal(int trigger_threshold,bool silent) +{ + uint8_t *dest = (uint8_t *)BigBuf; + int n = sizeof(BigBuf); + int i; + + memset(dest, 0, n); + 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; + LED_D_OFF(); + if (trigger_threshold != -1 && dest[i] < trigger_threshold) + continue; + else + trigger_threshold = -1; + if (++i >= n) break; + } + } + 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(int trigger_threshold) +{ + DoAcquisition125k_internal(trigger_threshold, false); +} + +//void SetupToAcquireRawAdcSamples(int divisor) void LFSetupFPGAForADC(int divisor, bool lf_field) { FpgaDownloadAndGo(FPGA_BITSTREAM_LF); @@ -38,41 +75,16 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) void AcquireRawAdcSamples125k(int divisor) { LFSetupFPGAForADC(divisor, true); - DoAcquisition125k(-1); + // Now call the acquisition routine + DoAcquisition125k_internal(-1,false); } - void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) { LFSetupFPGAForADC(divisor, false); - DoAcquisition125k(trigger_threshold); + DoAcquisition125k(trigger_threshold, false); } -// split into two routines so we can avoid timing issues after sending commands // -void DoAcquisition125k(int trigger_threshold) -{ - uint8_t *dest = (uint8_t *)BigBuf; - int n = sizeof(BigBuf); - int i; - memset(dest, 0, n); - 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; - LED_D_OFF(); - if (trigger_threshold != -1 && dest[i] < trigger_threshold) - continue; - else - trigger_threshold = -1; - if (++i >= n) break; - } - } - 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 ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) @@ -609,416 +621,212 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol) LED_A_OFF(); } - -// loop to capture raw HID waveform then FSK demodulate the TAG ID from it -void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) +size_t fsk_demod(uint8_t * dest, size_t size) { - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, n=0, i=0, idx=0, found=0, lastval=0; - uint32_t hi2=0, hi=0, lo=0; + uint32_t last_transition = 0; + uint32_t idx = 1; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + // 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; - // Connect the A/D to the peak-detected low-frequency path. - SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + // sync to first lo-hi transition, and threshold - // Give it a bit of time for the resonant antenna to settle. - SpinDelay(50); + //Need to threshold first sample + if(dest[0] < threshold_value) dest[0] = 0; + else dest[0] = 1; - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + 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; - for(;;) { - WDT_HIT(); - if (ledcontrol) - LED_A_ON(); - if(BUTTON_PRESS()) { - DbpString("Stopped"); - if (ledcontrol) - LED_A_OFF(); - return; - } + // Check for 0->1 transition + if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition - i = 0; - m = sizeof(BigBuf); - memset(dest,128,m); - 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 >= m) { - break; - } + if (idx-last_transition < 9) { + dest[numBits]=1; + } else { + dest[numBits]=0; } + last_transition = idx; + numBits++; } + } + return numBits; //Actually, it returns the number of bytes, but each byte represents a bit: 1 or 0 +} - // FSK demodulator - // sync to first lo-hi transition - for( idx=1; idx0 crossing + if ( dest[idx-1] ) { + n=(n+1) / h2l_crossing_value; + } else {// 0->1 crossing + n=(n+1) / l2h_crossing_value; } + if (n == 0) n = 1; + + if(n < maxConsequtiveBits) + { + memset(dest+numBits, dest[idx-1] , n); + numBits += n; + } + n=0; + lastval=dest[idx]; + }//end for + + return numBits; + +} +// loop to capture raw HID waveform then FSK demodulate the TAG ID from it +void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol) +{ + uint8_t *dest = (uint8_t *)BigBuf; + + size_t size=0,idx=0; //, found=0; + uint32_t hi2=0, hi=0, lo=0; + + + while(!BUTTON_PRESS()) { + + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(0, true) + WDT_HIT(); + if (ledcontrol) LED_A_ON(); - // 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( i=0; idx0 : fc/8 in sets of 6 + // 0->1 : fc/10 in sets of 5 + size = aggregate_bits(dest,size, 6,5,5); + WDT_HIT(); // 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 - for( idx=0; idx>1) & 0xFFFF); - } - else { - 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; + if ( memcmp(dest+idx, frame_marker_mask, sizeof(frame_marker_mask)) == 0) + { // frame marker found + idx+=sizeof(frame_marker_mask); + + 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; + numshifts ++; + idx += 2; } - } - if (found) { - if (dest[idx] && (!dest[idx+1]) ) { - hi2=(hi2<<1)|(hi>>31); - hi=(hi<<1)|(lo>>31); - lo=(lo<<1)|0; - } else if ( (!dest[idx]) && dest[idx+1]) { - hi2=(hi2<<1)|(hi>>31); - hi=(hi<<1)|(lo>>31); - lo=(lo<<1)|1; - } else { - found=0; - hi2=0; - hi=0; - lo=0; - } - idx++; - } - if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) ) - { - found=1; - idx+=6; - if (found && (hi|lo)) { - if (hi2 != 0){ - Dbprintf("TAG ID: %x%08x%08x (%d)", - (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); - } - else { - 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; + //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); + } + else { + Dbprintf("TAG ID: %x%08x (%d)", + (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); } - 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) +{ + uint32_t num = 0; + for(int i = 0 ; i < numbits ; i++) + { + num = (num << 1) | (*src); + src++; + } + return num; +} + + void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol) { uint8_t *dest = (uint8_t *)BigBuf; - int m=0, n=0, i=0, idx=0, lastval=0; - int found=0; - uint32_t code=0, code2=0; - //uint32_t hi2=0, hi=0, lo=0; - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); + size_t size=0, idx=0; + uint32_t code=0, code2=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); + while(!BUTTON_PRESS()) { - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(0, true); - for(;;) { WDT_HIT(); - if (ledcontrol) - LED_A_ON(); - if(BUTTON_PRESS()) { - DbpString("Stopped"); - if (ledcontrol) - LED_A_OFF(); - return; - } + if (ledcontrol) LED_A_ON(); - i = 0; - m = sizeof(BigBuf); - memset(dest,128,m); - 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 >= m) { - break; - } - } - } + DoAcquisition125k_internal(true); + size = sizeof(BigBuf); // FSK demodulator - - // sync to first lo-hi transition - for( idx=1; idx0 : fc/8 in sets of 7 + // 0->1 : fc/10 in sets of 6 + size = aggregate_bits(dest, size, 7,6,13); + WDT_HIT(); - for( idx=0; idx