X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/cf608ac8f37549561f9bdee1dd655a69b65882a8..2ae8a312e058f71d0f02be4f2f9cc6f284ebbf34:/armsrc/lfops.c diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 76c4b44e..025314a0 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -8,15 +8,18 @@ // Also routines for raw mode reading/simulating of LF waveform //----------------------------------------------------------------------------- -#include "proxmark3.h" +#include "../include/proxmark3.h" #include "apps.h" #include "util.h" -#include "hitag2.h" -#include "crc16.h" +#include "../include/hitag2.h" +#include "../common/crc16.h" #include "string.h" +#include "crapto1.h" +#include "mifareutil.h" -void AcquireRawAdcSamples125k(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) @@ -24,29 +27,38 @@ void AcquireRawAdcSamples125k(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); - + SpinDelay(150); + // Now set up the SSC to get the ADC samples that are now streaming at us. FpgaSetupSsc(); +} - // Now call the acquisition routine +void AcquireRawAdcSamples125k(int divisor) +{ + LFSetupFPGAForADC(divisor, true); DoAcquisition125k(); } +void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) +{ + LFSetupFPGAForADC(divisor, false); + DoAcquisition125k_threshold(trigger_threshold); +} + // split into two routines so we can avoid timing issues after sending commands // -void DoAcquisition125k(void) +void DoAcquisition125k_internal(int trigger_threshold, bool silent) { - uint8_t *dest = (uint8_t *)BigBuf; - int n = sizeof(BigBuf); + uint8_t *dest = mifare_get_bigbufptr(); + int n = 24000; int i; - memset(dest, 0, n); + memset(dest, 0x00, n); i = 0; for(;;) { if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) { @@ -55,38 +67,46 @@ void DoAcquisition125k(void) } 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; } } - Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...", + 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_threshold(int trigger_threshold) { + DoAcquisition125k_internal(trigger_threshold, true); +} +void DoAcquisition125k() { + DoAcquisition125k_internal(-1, true); +} + void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - int at134khz; /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelay(2500); + int divisor_used = 95; // 125 KHz // see if 'h' was specified - if (command[strlen((char *) command) - 1] == 'h') - at134khz = TRUE; - else - at134khz = FALSE; - if (at134khz) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + if (command[strlen((char *) command) - 1] == 'h') + divisor_used = 88; // 134.8 KHz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + 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); + + // And a little more time for the tag to fully power up SpinDelay(2000); @@ -98,12 +118,9 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); SpinDelayUs(delay_off); - if (at134khz) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - 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); @@ -113,15 +130,12 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); SpinDelayUs(delay_off); - if (at134khz) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); - 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 @@ -158,6 +172,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 @@ -365,6 +380,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); @@ -434,12 +450,17 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) void SimulateTagLowFrequency(int period, int gap, int ledcontrol) { int i; - uint8_t *tab = (uint8_t *)BigBuf; + uint8_t *buff = (uint8_t *)BigBuf; + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); - - AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK; - + SetAdcMuxFor(GPIO_MUXSEL_LOPKD); + + // Give it a bit of time for the resonant antenna to settle. + SpinDelay(150); + + 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; @@ -459,7 +480,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) if (ledcontrol) LED_D_ON(); - if(tab[i]) + if(buff[i]) OPEN_COIL(); else SHORT_COIL(); @@ -594,414 +615,208 @@ 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; - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + // 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 + dest[0] = (dest[0] < threshold_value) ? 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 + dest[idx] = (dest[idx] < threshold_value) ? 0 : 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; - } - } + dest[numBits] = (idx-last_transition < 9) ? 1 : 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; + + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(0, true); + + while(!BUTTON_PRESS()) { + WDT_HIT(); + if (ledcontrol) LED_A_ON(); + + DoAcquisition125k_internal(-1,true); + size = sizeof(BigBuf); + + // FSK demodulator + size = fsk_demod(dest, size); // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns - lastval=dest[0]; - idx=0; - i=0; - n=0; - for( idx=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 (found) { - if (dest[idx] && (!dest[idx+1]) ) { + 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 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; + else // 0 1 + lo=(lo<<1)| + 1; + numshifts ++; + idx += 2; } - 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(idx + sizeof(frame_marker_mask) < size) + { + 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; - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + 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); + // Configure to go in 125Khz listen mode + LFSetupFPGAForADC(0, true); - // 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(); - 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(-1,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>= 1) - T55xxWriteBit(Pwd & i); - } + if (PwdMode == 1){ + // Pwd + for (i = 0x80000000; i != 0; i >>= 1) + T55xxWriteBit(Pwd & i); + } // Lock bit T55xxWriteBit(0); @@ -1180,7 +971,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); } @@ -1188,26 +979,17 @@ void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMod // Read one card block in page 0 void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) { - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; - - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // 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(); - - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); - - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); - - // Now start writting + uint8_t *dest = mifare_get_bigbufptr(); + uint16_t bufferlength = T55xx_SAMPLES_SIZE; + uint32_t i = 0; + + // Clear destination buffer before sending the command 0x80 = average. + memset(dest, 0x80, bufferlength); + + // Set up FPGA, 125kHz + // Wait for config.. (192+8190xPOW)x8 == 67ms + LFSetupFPGAForADC(0, true); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); @@ -1225,53 +1007,40 @@ void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode) for (i = 0x04; i != 0; i >>= 1) T55xxWriteBit(Block & i); - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + // 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; - // 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 (i >= m) break; + ++i; + LED_D_OFF(); + if (i > bufferlength) 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(); - DbpString("DONE!"); } // Read card traceability data (page 1) void T55xxReadTrace(void){ - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; - - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // 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(); - - LED_D_ON(); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + uint8_t *dest = mifare_get_bigbufptr(); + uint16_t bufferlength = T55xx_SAMPLES_SIZE; + int i=0; + + // Clear destination buffer before sending the command 0x80 = average + memset(dest, 0x80, bufferlength); - // Give it a bit of time for the resonant antenna to settle. - // And for the tag to fully power up - SpinDelay(150); + LFSetupFPGAForADC(0, true); - // Now start writting FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); SpinDelayUs(START_GAP); @@ -1279,26 +1048,35 @@ void T55xxReadTrace(void){ T55xxWriteBit(1); T55xxWriteBit(1); //Page 1 - // Turn field on to read the response - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER); + // 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++; - if (i >= m) break; + ++i; + LED_D_OFF(); + + if (i >= bufferlength) 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(); - DbpString("DONE!"); +} + +void TurnReadLFOn(){ + 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. + //SpinDelay(30); + SpinDelayUs(8*150); } /*-------------- Cloning routines -----------*/ @@ -1414,7 +1192,7 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) } // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long) - T55xxWriteBlock(T55x7_BITRATE_RF_50 | + T55xxWriteBlock(T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2a | last_block << T55x7_MAXBLOCK_SHIFT, 0,0,0); @@ -1557,7 +1335,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); @@ -1568,15 +1345,13 @@ void CopyIndala64toT55x7(int hi, int lo) 2 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0); //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data) -// T5567WriteBlock(0x603E1042,0); + // 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); @@ -1592,10 +1367,9 @@ void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int 7 << T55x7_MAXBLOCK_SHIFT, 0,0,0); //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data) -// T5567WriteBlock(0x603E10E2,0); + // T5567WriteBlock(0x603E10E2,0); DbpString("DONE!"); - } @@ -1742,7 +1516,6 @@ int IsBlock1PCF7931(uint8_t *Block) { return 0; } - #define ALLOC 16 void ReadPCF7931() { @@ -1970,8 +1743,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 @@ -1983,7 +1757,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 @@ -1995,12 +1769,13 @@ 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) } } } + void EM4xLogin(uint32_t Password) { uint8_t fwd_bit_count; @@ -2018,41 +1793,48 @@ void EM4xLogin(uint32_t Password) { void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) { - uint8_t fwd_bit_count; - uint8_t *dest = (uint8_t *)BigBuf; - int m=0, i=0; + uint8_t *dest = mifare_get_bigbufptr(); + uint16_t bufferlength = 12000; + uint32_t i = 0; + + // Clear destination buffer before sending the command 0x80 = average. + memset(dest, 0x80, bufferlength); + + uint8_t fwd_bit_count; - //If password mode do login - if (PwdMode == 1) EM4xLogin(Pwd); + //If password mode do login + if (PwdMode == 1) EM4xLogin(Pwd); - forward_ptr = forwardLink_data; - fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); - fwd_bit_count += Prepare_Addr( Address ); + forward_ptr = forwardLink_data; + fwd_bit_count = Prepare_Cmd( FWD_CMD_READ ); + fwd_bit_count += Prepare_Addr( Address ); - m = sizeof(BigBuf); - // Clear destination buffer before sending the command - memset(dest, 128, m); - // 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(); + // 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); + SendForward(fwd_bit_count); - // 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 >= m) break; - } - } - FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off - LED_D_OFF(); + // // 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; + } + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR; + ++i; + if (i >= bufferlength) break; + } + } + + cmd_send(CMD_ACK,0,0,0,0,0); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off + LED_D_OFF(); } void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {