X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/e770c6482407fb67c37973cc3e95409cd5c6d952..e09f21fa7b754a2f214efbebc622045138828096:/armsrc/lfops.c diff --git a/armsrc/lfops.c b/armsrc/lfops.c index 67652986..3684eaaf 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -15,130 +15,44 @@ #include "crc16.h" #include "string.h" #include "lfdemod.h" +#include "lfsampling.h" /** -* Does the sample acquisition. If threshold is specified, the actual sampling -* is not commenced until the threshold has been reached. -* @param trigger_threshold - the threshold -* @param silent - is true, now outputs are made. If false, dbprints the status -*/ -void DoAcquisition125k_internal(int trigger_threshold,bool silent) -{ - uint8_t *dest = BigBuf_get_addr(); - int n = BigBuf_max_traceLen(); - 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]); - - } -} -/** -* Perform sample aquisition. -*/ -void DoAcquisition125k(int trigger_threshold) -{ - DoAcquisition125k_internal(trigger_threshold, false); -} - -/** -* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream -* if not already loaded, sets divisor and starts up the antenna. -* @param divisor : 1, 88> 255 or negative ==> 134.8 KHz -* 0 or 95 ==> 125 KHz -* -**/ -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) - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz - else - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor); - - 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(); -} -/** -* Initializes the FPGA, and acquires the samples. -**/ -void AcquireRawAdcSamples125k(int divisor) -{ - LFSetupFPGAForADC(divisor, true); - // Now call the acquisition routine - DoAcquisition125k_internal(-1,false); -} -/** -* Initializes the FPGA for snoop-mode, and acquires the samples. -**/ - -void SnoopLFRawAdcSamples(int divisor, int trigger_threshold) -{ - LFSetupFPGAForADC(divisor, false); - DoAcquisition125k(trigger_threshold); -} - + * Function to do a modulation and then get samples. + * @param delay_off + * @param period_0 + * @param period_1 + * @param command + */ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command) { - /* 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') divisor_used = 88; // 134.8 KHz + sample_config sc = { 0,0,1, divisor_used, 0}; + setSamplingConfig(&sc); - 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); + /* Make sure the tag is reset */ + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + SpinDelay(2500); - // And a little more time for the tag to fully power up - SpinDelay(2000); + LFSetupFPGAForADC(sc.divisor, 1); - // Now set up the SSC to get the ADC samples that are now streaming at us. - FpgaSetupSsc(); + // And a little more time for the tag to fully power up + SpinDelay(2000); // now modulate the reader field while(*command != '\0' && *command != ' ') { FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); LED_D_ON(); @@ -150,14 +64,16 @@ void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_D_OFF(); SpinDelayUs(delay_off); - FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor_used); + FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor); FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD); // now do the read - DoAcquisition125k(-1); + DoAcquisition_config(false); } + + /* blank r/w tag data stream ...0000000000000000 01111111 1010101010101010101010101010101010101010101010101010101010101010 @@ -478,11 +394,12 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT; AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK; -#define SHORT_COIL() LOW(GPIO_SSC_DOUT) -#define OPEN_COIL() HIGH(GPIO_SSC_DOUT) + #define SHORT_COIL() LOW(GPIO_SSC_DOUT) + #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) i = 0; for(;;) { + //wait until SSC_CLK goes HIGH while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { if(BUTTON_PRESS()) { DbpString("Stopped"); @@ -490,7 +407,6 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) } WDT_HIT(); } - if (ledcontrol) LED_D_ON(); @@ -501,17 +417,96 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) if (ledcontrol) LED_D_OFF(); - + //wait until SSC_CLK goes LOW while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { if(BUTTON_PRESS()) { DbpString("Stopped"); return; } WDT_HIT(); + } + + i++; + if(i == period) { + + i = 0; + if (gap) { + SHORT_COIL(); + SpinDelayUs(gap); + } } + } +} + +//Testing to fix timing issues by marshmellow (MM) +void SimulateTagLowFrequencyMM(int period, int gap, int ledcontrol) +{ + int i; + uint8_t *tab = BigBuf_get_addr(); + FpgaDownloadAndGo(FPGA_BITSTREAM_LF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT); + + 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; + + #define SHORT_COIL() LOW(GPIO_SSC_DOUT) + #define OPEN_COIL() HIGH(GPIO_SSC_DOUT) + + i = 0; + while(!BUTTON_PRESS()) { + + WDT_HIT(); + //wait until reader carrier is HIGH + while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) { + WDT_HIT(); + } + if (i>0){ + if (tab[i]!=tab[i-1]){ + // transition + if (ledcontrol) + LED_D_ON(); + + // modulate coil + if(tab[i]) + OPEN_COIL(); + else + SHORT_COIL(); + + if (ledcontrol) + LED_D_OFF(); + + } else { //no transition + //NOTE: it appears the COIL transition messes with the detection of the carrier, so if a transition happened + // skip test for readers Carrier = LOW, otherwise we get a bit behind + + //wait until reader carrier is LOW + while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) { + WDT_HIT(); + } + } + } else { + // transition + if (ledcontrol) + LED_D_ON(); + + // modulate coil + if(tab[i]) + OPEN_COIL(); + else + SHORT_COIL(); + + if (ledcontrol) + LED_D_OFF(); + } + WDT_HIT(); + + i++; - if(i == period) { + if(i == period) { + // end of data stream, gap then repeat i = 0; if (gap) { SHORT_COIL(); @@ -519,6 +514,8 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) } } } + DbpString("Stopped"); + return; } #define DEBUG_FRAME_CONTENTS 1 @@ -526,8 +523,9 @@ void SimulateTagLowFrequencyBidir(int divisor, int t0) { } -// compose fc/8 fc/10 waveform -static void fc(int c, int *n) { +// compose fc/8 fc/10 waveform (FSK2) +static void fc(int c, int *n) +{ uint8_t *dest = BigBuf_get_addr(); int idx; @@ -535,20 +533,21 @@ static void fc(int c, int *n) { if(c==0) { dest[((*n)++)]=1; dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; + dest[((*n)++)]=1; + dest[((*n)++)]=1; dest[((*n)++)]=0; dest[((*n)++)]=0; dest[((*n)++)]=0; dest[((*n)++)]=0; } + // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples if(c==8) { for (idx=0; idx<6; idx++) { dest[((*n)++)]=1; dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; + dest[((*n)++)]=1; + dest[((*n)++)]=1; dest[((*n)++)]=0; dest[((*n)++)]=0; dest[((*n)++)]=0; @@ -562,8 +561,8 @@ static void fc(int c, int *n) { dest[((*n)++)]=1; dest[((*n)++)]=1; dest[((*n)++)]=1; - dest[((*n)++)]=0; - dest[((*n)++)]=0; + dest[((*n)++)]=1; + dest[((*n)++)]=1; dest[((*n)++)]=0; dest[((*n)++)]=0; dest[((*n)++)]=0; @@ -572,6 +571,55 @@ static void fc(int c, int *n) { } } } +// compose fc/X fc/Y waveform (FSKx) +static void fcAll(uint8_t c, int *n, uint8_t clock, uint16_t *modCnt) +{ + uint8_t *dest = BigBuf_get_addr(); + uint8_t idx; + uint8_t fcCnt; + // c = count of field clock for this bit + uint8_t mod = clock % c; + uint8_t modAdj = c/mod; + bool modAdjOk=FALSE; + if (c % mod==0) modAdjOk=TRUE; + // loop through clock - step field clock + for (idx=0; idx < (uint8_t) clock/c; idx++){ + // loop through field clock length - put 1/2 FC length 1's and 1/2 0's per field clock wave (to create the wave) + for (fcCnt=0; fcCnt < c; fcCnt++){ //fudge slow transition from low to high - shorten wave by 1 + if (fcCnt < c/2+1){ + dest[((*n)++)]=0; + } else { + //fudge low to high transition + //if (idx==clock/c && dest[*n-1]==1 && mod>0) dest[((*n++))]=0; + //if (c==8 && fcCnt==5) continue; + dest[((*n)++)]=1; + } + } + } + if (mod>0) (*modCnt)++; + if ((mod>0) && modAdjOk){ //fsk2 + if ((*modCnt % modAdj) == 0){ //if 4th 8 length wave in a rf/50 add extra 8 length wave + for (fcCnt=0; fcCnt < c; fcCnt++){ //fudge slow transition from low to high - shorten wave by 1 + if (fcCnt < c/2+1){ + dest[((*n)++)]=0; + } else { + //if (c==8 && fcCnt==5) continue; + dest[((*n)++)]=1; + } + } + } + } + //Dbprintf("mod: %d, modAdj %d, modc %d",mod, modAdj, c % mod); + if (mod>0 && !modAdjOk){ //fsk1 + for (idx=0; idx < mod; idx++){ + if (idx < mod/2) { + dest[((*n)++)]=0; + } else { + dest[((*n)++)]=1; + } + } + } +} // prepare a waveform pattern in the buffer based on the ID given then // simulate a HID tag until the button is pressed @@ -629,6 +677,210 @@ void CmdHIDsimTAG(int hi, int lo, int ledcontrol) LED_A_OFF(); } +// prepare a waveform pattern in the buffer based on the ID given then +// simulate a FSK tag until the button is pressed +// arg1 contains fcHigh and fcLow, arg2 contains invert and clock +void CmdFSKsimTAG(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream) +{ + int ledcontrol=1; + int n=0, i=0; + uint8_t fcHigh = arg1 >> 8; + uint8_t fcLow = arg1 & 0xFF; + uint16_t modCnt = 0; + //spacer bit + uint8_t clk = arg2 & 0xFF; + uint8_t invert = (arg2 >> 8) & 1; + //fcAll(0, &n, clk); + + WDT_HIT(); + for (i=0; i> 8) & 0xFF; + uint8_t manchester = arg1 & 1; + uint8_t separator = arg2 & 1; + uint8_t invert = (arg2 >> 8) & 1; + WDT_HIT(); + for (i=0; i> 8; + uint8_t carrier = arg1 & 0xFF; + uint8_t invert = arg2 & 0xFF; + //uint8_t phase = carrier/2; //extra phase changing bits = 1/2 a carrier wave to change the phase + //uint8_t invert = (arg2 >> 8) & 1; + uint8_t curPhase = 0; + WDT_HIT(); + for (i=0; i0){ @@ -1394,7 +1646,9 @@ int DemodPCF7931(uint8_t **outBlocks) { int lmin=128, lmax=128; uint8_t dir; - AcquireRawAdcSamples125k(0); + LFSetupFPGAForADC(95, true); + DoAcquisition_default(0, 0); + lmin = 64; lmax = 192; @@ -1621,7 +1875,7 @@ void ReadPCF7931() { tries++; if (BUTTON_PRESS()) return; } while (num_blocks != max_blocks); -end: + end: Dbprintf("-----------------------------------------"); Dbprintf("Memory content:"); Dbprintf("-----------------------------------------");