]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/lfops.c
Legic Tag Simulator (#666)
[proxmark3-svn] / armsrc / lfops.c
index 5e9fb193f239bff1df48898c1daecbc7c26d19b6..911ba8da1c62e81d8fc7973928e931bf87cede3e 100644 (file)
@@ -4,7 +4,7 @@
 // the license.
 //-----------------------------------------------------------------------------
 // Miscellaneous routines for low frequency tag operations.
-// Tags supported here so far are Texas Instruments (TI), HID
+// Tags supported here so far are Texas Instruments (TI), HID, EM4x05, EM410x
 // Also routines for raw mode reading/simulating of LF waveform
 //-----------------------------------------------------------------------------
 
  */
 void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command)
 {
-
+       // start timer
        StartTicks();
-       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);
-       //clear read buffer
-       BigBuf_Clear_keep_EM();
+       // use lf config settings
+       sample_config *sc = getSamplingConfig();
 
-       /* Make sure the tag is reset */
+       // Make sure the tag is reset
        FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        WaitMS(2500);
 
-       //power on
-       LFSetupFPGAForADC(sc.divisor, 1);
+       // clear read buffer (after fpga bitstream loaded...)
+       BigBuf_Clear_keep_EM();
+
+       // power on
+       LFSetupFPGAForADC(sc->divisor, 1);
 
        // And a little more time for the tag to fully power up
        WaitMS(2000);
@@ -56,15 +52,21 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
        // now modulate the reader field
 
        if (bitbang) {
-               //HACK it appears my loop and if statements take up about 7 us so adjust waits accordingly...
+               // HACK it appears the loop and if statements take up about 7us so adjust waits accordingly...
                uint8_t hack_cnt = 7;
                if (period_0 < hack_cnt || period_1 < hack_cnt) {
-                       DbpString("Warning periods cannot be less than 7 in bit bang mode");
+                       DbpString("Warning periods cannot be less than 7us in bit bang mode");
                        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                        LED_D_OFF();
                        return;
                }
-               //prime cmd_len to save time comparing strings while modulating
+
+               // hack2 needed---  it appears to take about 8-16us to turn the antenna back on 
+               // leading to ~ 1 to 2 125khz samples extra in every off period 
+               // so we should test for last 0 before next 1 and reduce period_0 by this extra amount...
+               // but is this time different for every antenna or other hw builds???  more testing needed
+
+               // prime cmd_len to save time comparing strings while modulating
                int cmd_len = 0;
                while(command[cmd_len] != '\0' && command[cmd_len] != ' ')
                        cmd_len++;
@@ -72,7 +74,6 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
                int counter = 0;
                bool off = false;
                for (counter = 0; counter < cmd_len; counter++) {
-               //while(*command != '\0' && *command != ' ') {
                        // if cmd = 0 then turn field off
                        if (command[counter] == '0') {
                                // if field already off leave alone (affects timing otherwise)
@@ -81,17 +82,17 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
                                        LED_D_OFF();
                                        off = true;
                                }
-                               // note we appear to take about 6us to switch over (or run the if statements/loop...)
+                               // note we appear to take about 7us to switch over (or run the if statements/loop...)
                                WaitUS(period_0-hack_cnt);
                        // else if cmd = 1 then turn field on
                        } else {
                                // if field already on leave alone (affects timing otherwise)
                                if (off) {
-                                       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);                           
+                                       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
                                        LED_D_ON();
                                        off = false;
                                }
-                               // note we appear to take about 6us to switch over (or run the if statements/loop...)
+                               // note we appear to take about 7us to switch over (or run the if statements/loop...)
                                WaitUS(period_1-hack_cnt);
                        }
                }
@@ -100,7 +101,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
                        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                        LED_D_OFF();
                        WaitUS(delay_off);
-                       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
+                       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor);
                        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
                        LED_D_ON();
                        if(*(command++) == '0') {
@@ -112,14 +113,18 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
                FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
                LED_D_OFF();
                WaitUS(delay_off);
-               FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc.divisor);
+               FpgaSendCommand(FPGA_CMD_SET_DIVISOR, sc->divisor);
        }
 
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
 
        // now do the read
        DoAcquisition_config(false, 0);
-       // note leaves field on...  (for future commands?)
+
+       // Turn off antenna
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       // tell client we are done
+       cmd_send(CMD_ACK,0,0,0,0,0);
 }
 
 /* blank r/w tag data stream
@@ -563,7 +568,7 @@ static void fcAll(uint8_t fc, int *n, uint8_t clock, uint16_t *modCnt)
        uint8_t wavesPerClock = clock/fc;
        uint8_t mod = clock % fc;    //modifier
        uint8_t modAdj = fc/mod;     //how often to apply modifier
-       bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk=TRUE;
+       bool modAdjOk = !(fc % mod); //if (fc % mod==0) modAdjOk=true;
        // loop through clock - step field clock
        for (uint8_t idx=0; idx < wavesPerClock; idx++){
                // put 1/2 FC length 1's and 1/2 0's per field clock wave (to create the wave)
@@ -815,9 +820,9 @@ void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
 
        for (i=0; i<size; i++){
                if (BitStream[i] == curPhase){
-                       pskSimBit(carrier, &n, clk, &curPhase, FALSE);
+                       pskSimBit(carrier, &n, clk, &curPhase, false);
                } else {
-                       pskSimBit(carrier, &n, clk, &curPhase, TRUE);
+                       pskSimBit(carrier, &n, clk, &curPhase, true);
                }
        }
        Dbprintf("Simulating with Carrier: %d, clk: %d, invert: %d, n: %d",carrier, clk, invert, n);
Impressum, Datenschutz