X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/904a96cd80788b29a32c7bbcde07a07d2a6e6511..e09f21fa7b754a2f214efbebc622045138828096:/armsrc/lfops.c diff --git a/armsrc/lfops.c b/armsrc/lfops.c index e34eab35..3684eaaf 100644 --- a/armsrc/lfops.c +++ b/armsrc/lfops.c @@ -394,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"); @@ -406,7 +407,6 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) } WDT_HIT(); } - if (ledcontrol) LED_D_ON(); @@ -417,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(); @@ -435,6 +514,8 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol) } } } + DbpString("Stopped"); + return; } #define DEBUG_FRAME_CONTENTS 1 @@ -442,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; @@ -451,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; @@ -478,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; @@ -488,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 @@ -545,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; i