]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/appmain.c
This version code now reads a TI tag properly.
[proxmark3-svn] / armsrc / appmain.c
index 09f11f03670f2a6308b784580f79d56dc0cfd884..a5c082e59e9325cd0ff138d55454063ce3388128 100644 (file)
@@ -71,7 +71,7 @@ void DbpString(char *str)
        /* this holds up stuff unless we're connected to usb */
 //     if (!usbattached)
 //             return;
-       
+
        UsbCommand c;
        c.cmd = CMD_DEBUG_PRINT_STRING;
        c.ext1 = strlen(str);
@@ -103,10 +103,10 @@ void AcquireRawAdcSamples125k(BOOL at134khz)
 {
        if(at134khz) {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        } else {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        }
 
        // Connect the A/D to the peak-detected low-frequency path.
@@ -157,13 +157,13 @@ void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,BYT
                at134khz= TRUE;
        else
                at134khz= FALSE;
-       
+
        if(at134khz) {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        } else {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        }
 
        // Give it a bit of time for the resonant antenna to settle.
@@ -180,10 +180,10 @@ void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,BYT
                SpinDelayUs(delay_off);
                if(at134khz) {
                        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-                       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
+                       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
                } else {
                        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-                       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
+                       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
                }
                LED_D_ON();
                if(*(command++) == '0')
@@ -196,16 +196,88 @@ void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,BYT
        SpinDelayUs(delay_off);
        if(at134khz) {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        } else {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        }
 
        // now do the read
        DoAcquisition125k(at134khz);
 }
 
+void AcquireTiType(void)
+{
+       int i;
+       int n = 5000;
+
+       // clear buffer
+       memset(BigBuf,0,sizeof(BigBuf));
+
+       // Set up the synchronous serial port
+  PIO_DISABLE = (1<<GPIO_SSC_DIN);
+  PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN);
+
+       // steal this pin from the SSP and use it to control the modulation
+  PIO_ENABLE = (1<<GPIO_SSC_DOUT);
+       PIO_OUTPUT_ENABLE       = (1<<GPIO_SSC_DOUT);
+
+  SSC_CONTROL = SSC_CONTROL_RESET;
+  SSC_CONTROL = SSC_CONTROL_RX_ENABLE | SSC_CONTROL_TX_ENABLE;
+
+  // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long
+  // 48/2 = 24 MHz clock must be divided by 12
+  SSC_CLOCK_DIVISOR = 12;
+
+  SSC_RECEIVE_CLOCK_MODE = SSC_CLOCK_MODE_SELECT(0);
+       SSC_RECEIVE_FRAME_MODE = SSC_FRAME_MODE_BITS_IN_WORD(32) | SSC_FRAME_MODE_MSB_FIRST;
+       SSC_TRANSMIT_CLOCK_MODE = 0;
+       SSC_TRANSMIT_FRAME_MODE = 0;
+
+       LED_D_ON();
+
+       // modulate antenna
+       PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
+
+       // Charge TI tag for 50ms.
+       SpinDelay(50);
+
+       // stop modulating antenna and listen
+       PIO_OUTPUT_DATA_CLEAR = (1<<GPIO_SSC_DOUT);
+
+       LED_D_OFF();
+
+       i = 0;
+       for(;;) {
+                       if(SSC_STATUS & SSC_STATUS_RX_READY) {
+                                       BigBuf[i] = SSC_RECEIVE_HOLDING;        // store 32 bit values in buffer
+                                       i++; if(i >= n) return;
+                       }
+                       WDT_HIT();
+       }
+
+       // return stolen pin ro SSP
+       PIO_DISABLE = (1<<GPIO_SSC_DOUT);
+       PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN) | (1<<GPIO_SSC_DOUT);
+}
+
+void AcquireRawBitsTI(void)
+{
+       LED_D_ON();
+       // TI tags charge at 134.2Khz
+       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
+       // Place FPGA in passthrough mode, in this mode the CROSS_LO line
+       // connects to SSP_DIN and the SSP_DOUT logic level controls
+       // whether we're modulating the antenna (high)
+       // or listening to the antenna (low)
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
+
+       // get TI tag data into the buffer
+       AcquireTiType();
+
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+}
+
 //-----------------------------------------------------------------------------
 // Read an ADC channel and block till it completes, then return the result
 // in ADC units (0 to 1023). Also a routine to average 32 samples and
@@ -240,92 +312,55 @@ static int AvgAdc(int ch)
        return (a + 15) >> 5;
 }
 
-/*
- * Sweeps the useful LF range of the proxmark from
- * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
- * reads the voltage in the antenna: the result is a graph
- * which should clearly show the resonating frequency of your
- * LF antenna ( hopefully around 90 if it is tuned to 125kHz!)
- */
-void SweepLFrange()
+void MeasureAntennaTuning(void)
 {
        BYTE *dest = (BYTE *)BigBuf;
-       char dummy[12];
-       int i, peak= 0, ptr= 0;
-       double freq;
+       int i, ptr = 0, adcval = 0, peak = 0, peakv = 0, peakf = 0;;
+       int vLf125 = 0, vLf134 = 0, vHf = 0;    // in mV
 
-       // clear buffer
+       UsbCommand c;
+
+       DbpString("Measuring antenna characteristics, please wait.");
        memset(BigBuf,0,sizeof(BigBuf));
 
+/*
+ * Sweeps the useful LF range of the proxmark from
+ * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
+ * read the voltage in the antenna, the result left
+ * in the buffer is a graph which should clearly show
+ * the resonating frequency of your LF antenna
+ * ( hopefully around 95 if it is tuned to 125kHz!)
+ */
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
        for (i=255; i>19; i--) {
                FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
                SpinDelay(20);
-               dest[i] = (137500 * AvgAdc(ADC_CHAN_LF)) >> 18;
+               // Vref = 3.3V, and a 10000:240 voltage divider on the input
+               // can measure voltages up to 137500 mV
+               adcval = ((137500 * AvgAdc(ADC_CHAN_LF)) >> 10);
+               if (i==95)      vLf125 = adcval; // voltage at 125Khz
+               if (i==89)      vLf134 = adcval; // voltage at 134Khz
+
+               dest[i] = adcval>>8; // scale int to fit in byte for graphing purposes
                if(dest[i] > peak) {
-                       peak= dest[i];
-                       ptr= i;
-                       }
-       }
-       dummy[11]= '\0';
-       dummy[10]= 'z';
-       dummy[9]= 'H';
-       dummy[8]= 'k';
-       dummy[7]= ' ';
-       freq= 12000000/(ptr + 1);
-       for(i= 6; i > 3 ; --i) {
-               dummy[i]= '0' + ((int) freq) % 10;
-               freq /= 10;
-               }
-       dummy[3]= '.';
-       for(i= 2; i >= 0 ; --i) {
-               dummy[i]= '0' + ((int) freq) % 10;
-               freq /= 10;
+                       peakv = adcval;
+                       peak = dest[i];
+                       peakf = i;
+                       ptr = i;
                }
-       DbpString("Antenna resonates at:");
-       DbpString(dummy);
-}
-
-void MeasureAntennaTuning(void)
-{
-// Impedances are Zc = 1/(j*omega*C), in ohms
-#define LF_TUNING_CAP_Z        1273    //  1 nF @ 125   kHz
-#define HF_TUNING_CAP_Z        235             // 50 pF @ 13.56 MHz
-
-       int vLf125, vLf134, vHf;        // in mV
-
-       UsbCommand c;
-
-       // Let the FPGA drive the low-frequency antenna around 125 kHz.
-       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
-       SpinDelay(20);
-       vLf125 = AvgAdc(ADC_CHAN_LF);
-       // Vref = 3.3V, and a 10000:240 voltage divider on the input
-       // can measure voltages up to 137500 mV
-       vLf125 = (137500 * vLf125) >> 10;
-
-       // Let the FPGA drive the low-frequency antenna around 134 kHz.
-       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
-       SpinDelay(20);
-       vLf134 = AvgAdc(ADC_CHAN_LF);
-       // Vref = 3.3V, and a 10000:240 voltage divider on the input
-       // can measure voltages up to 137500 mV
-       vLf134 = (137500 * vLf134) >> 10;
+       }
 
        // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
        FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
        SpinDelay(20);
-       vHf = AvgAdc(ADC_CHAN_HF);
        // Vref = 3300mV, and an 10:1 voltage divider on the input
        // can measure voltages up to 33000 mV
-       vHf = (33000 * vHf) >> 10;
+       vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
 
        c.cmd = CMD_MEASURED_ANTENNA_TUNING;
        c.ext1 = (vLf125 << 0) | (vLf134 << 16);
        c.ext2 = vHf;
-       c.ext3 = (LF_TUNING_CAP_Z << 0) | (HF_TUNING_CAP_Z << 16);
+       c.ext3 = peakf | (peakv << 16);
        UsbSendPacket((BYTE *)&c, sizeof(c));
 }
 
@@ -361,7 +396,7 @@ void SimulateTagLowFrequency(int period, int ledcontrol)
                        OPEN_COIL();
                else
                        SHORT_COIL();
-               
+
                if (ledcontrol)
                        LED_D_OFF();
 
@@ -476,7 +511,7 @@ static void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
        if (ledcontrol)
                LED_A_ON();
        SimulateTagLowFrequency(n, ledcontrol);
-       
+
        if (ledcontrol)
                LED_A_OFF();
 }
@@ -489,7 +524,7 @@ static void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
        DWORD hi=0, lo=0;
 
        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
 
        // Connect the A/D to the peak-detected low-frequency path.
        SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
@@ -735,6 +770,10 @@ void UsbPacketReceived(BYTE *packet, int len)
                        ModThenAcquireRawAdcSamples125k(c->ext1,c->ext2,c->ext3,c->d.asBytes);
                        break;
 
+               case CMD_ACQUIRE_RAW_BITS_TI_TYPE:
+                       AcquireRawBitsTI();
+                       break;
+
                case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
                        AcquireRawAdcSamplesIso15693();
                        break;
@@ -836,10 +875,6 @@ void UsbPacketReceived(BYTE *packet, int len)
                case CMD_READ_MEM:
                        ReadMem(c->ext1);
                        break;
-               case CMD_SWEEP_LF:
-                       SweepLFrange();
-                       break;
-
                case CMD_SET_LF_DIVISOR:
                        FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->ext1);
                        break;
@@ -871,7 +906,7 @@ void ReadMem(int addr)
 {
        const DWORD *data = ((DWORD *)addr);
        int i;
-       
+
        DbpString("Reading memory at address");
        DbpIntegers(0, 0, addr);
        for (i = 0; i < 8; i+= 2)
@@ -883,10 +918,10 @@ void AppMain(void)
        memset(BigBuf,0,sizeof(BigBuf));
        SpinDelay(100);
 
-    LED_D_OFF();
-    LED_C_OFF();
-    LED_B_OFF();
-    LED_A_OFF();
+       LED_D_OFF();
+       LED_C_OFF();
+       LED_B_OFF();
+       LED_A_OFF();
 
        UsbStart();
 
@@ -912,14 +947,14 @@ void AppMain(void)
        LCDInit();
 
        // test text on different colored backgrounds
-    LCDString(" The quick brown fox  ",        &FONT6x8,1,1+8*0,WHITE  ,BLACK );
-    LCDString("  jumped over the     ",        &FONT6x8,1,1+8*1,BLACK  ,WHITE );
-    LCDString("     lazy dog.        ",        &FONT6x8,1,1+8*2,YELLOW ,RED   );
-    LCDString(" AaBbCcDdEeFfGgHhIiJj ",        &FONT6x8,1,1+8*3,RED    ,GREEN );
-    LCDString(" KkLlMmNnOoPpQqRrSsTt ",        &FONT6x8,1,1+8*4,MAGENTA,BLUE  );
-    LCDString("UuVvWwXxYyZz0123456789",        &FONT6x8,1,1+8*5,BLUE   ,YELLOW);
-    LCDString("`-=[]_;',./~!@#$%^&*()",        &FONT6x8,1,1+8*6,BLACK  ,CYAN  );
-    LCDString("     _+{}|:\\\"<>?     ",&FONT6x8,1,1+8*7,BLUE  ,MAGENTA);
+       LCDString(" The quick brown fox  ",     &FONT6x8,1,1+8*0,WHITE  ,BLACK );
+       LCDString("  jumped over the     ",     &FONT6x8,1,1+8*1,BLACK  ,WHITE );
+       LCDString("     lazy dog.        ",     &FONT6x8,1,1+8*2,YELLOW ,RED   );
+       LCDString(" AaBbCcDdEeFfGgHhIiJj ",     &FONT6x8,1,1+8*3,RED    ,GREEN );
+       LCDString(" KkLlMmNnOoPpQqRrSsTt ",     &FONT6x8,1,1+8*4,MAGENTA,BLUE  );
+       LCDString("UuVvWwXxYyZz0123456789",     &FONT6x8,1,1+8*5,BLUE   ,YELLOW);
+       LCDString("`-=[]_;',./~!@#$%^&*()",     &FONT6x8,1,1+8*6,BLACK  ,CYAN  );
+       LCDString("     _+{}|:\\\"<>?     ",&FONT6x8,1,1+8*7,BLUE  ,MAGENTA);
 
        // color bands
        LCDFill(0, 1+8* 8, 132, 8, BLACK);
@@ -952,7 +987,7 @@ void SamyRun()
 #define OPTS 2
 
        int high[OPTS], low[OPTS];
-       
+
        // Oooh pretty -- notify user we're in elite samy mode now
        LED(LED_RED,    200);
        LED(LED_ORANGE, 200);
@@ -963,47 +998,52 @@ void SamyRun()
        LED(LED_GREEN,  200);
        LED(LED_ORANGE, 200);
        LED(LED_RED,    200);
-       
+
        int selected = 0;
        int playing = 0;
-       
+
        // Turn on selected LED
        LED(selected + 1, 0);
-       
+
        for (;;)
        {
                usbattached = UsbPoll(FALSE);
                WDT_HIT();
-               
+
                // Was our button held down or pressed?
                int button_pressed = BUTTON_HELD(1000);
                SpinDelay(300);
-               
+
                // Button was held for a second, begin recording
                if (button_pressed > 0)
                {
                        LEDsoff();
                        LED(selected + 1, 0);
                        LED(LED_RED2, 0);
-                                               
+
                        // record
                        DbpString("Starting recording");
-                       
+
+                       // wait for button to be released
+                       while(BUTTON_PRESS())
+                               WDT_HIT();
+
                        /* need this delay to prevent catching some weird data */
                        SpinDelay(500);
+
                        CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
                        DbpString("Recorded");
                        DbpIntegers(selected, high[selected], low[selected]);
-                       
+
                        LEDsoff();
                        LED(selected + 1, 0);
                        // Finished recording
-                       
+
                        // If we were previously playing, set playing off
                        // so next button push begins playing what we recorded
                        playing = 0;
                }
-               
+
                // Change where to record (or begin playing)
                else if (button_pressed)
                {
@@ -1011,34 +1051,46 @@ void SamyRun()
                        if (playing)
                                selected = (selected + 1) % OPTS;
                        playing = !playing;
-                       
+
                        LEDsoff();
                        LED(selected + 1, 0);
-                       
+
                        // Begin transmitting
                        if (playing)
                        {
                                LED(LED_GREEN, 0);
                                DbpString("Playing");
+                               // wait for button to be released
+                               while(BUTTON_PRESS())
+                                       WDT_HIT();
                                DbpIntegers(selected, high[selected], low[selected]);
                                CmdHIDsimTAG(high[selected], low[selected], 0);
                                DbpString("Done playing");
-                               
+                               if (BUTTON_HELD(1000) > 0)
+                                       {
+                                       DbpString("Exiting");
+                                       LEDsoff();
+                                       return;
+                                       }
+
                                /* We pressed a button so ignore it here with a delay */
                                SpinDelay(300);
-                               
+
                                // when done, we're done playing, move to next option
                                selected = (selected + 1) % OPTS;
                                playing = !playing;
                                LEDsoff();
                                LED(selected + 1, 0);
                        }
+                       else
+                               while(BUTTON_PRESS())
+                                       WDT_HIT();
                }
        }
 }
 
 
-// listen for external reader 
+// listen for external reader
 void ListenReaderField(int limit)
 {
        int lf_av, lf_av_new, lf_baseline= 0, lf_count= 0;
@@ -1054,7 +1106,7 @@ void ListenReaderField(int limit)
 
        lf_av= ReadAdc(ADC_CHAN_LF);
 
-       if(limit != HF_ONLY) 
+       if(limit != HF_ONLY)
                {
                DbpString("LF 125/134 Baseline:");
                DbpIntegers(lf_av,0,0);
@@ -1064,16 +1116,16 @@ void ListenReaderField(int limit)
        hf_av= ReadAdc(ADC_CHAN_HF);
 
 
-       if (limit != LF_ONLY) 
+       if (limit != LF_ONLY)
                {
                DbpString("HF 13.56 Baseline:");
                DbpIntegers(hf_av,0,0);
                hf_baseline= hf_av;
                }
 
-       for(;;) 
+       for(;;)
                {
-               if(BUTTON_PRESS()) 
+               if(BUTTON_PRESS())
                        {
                        DbpString("Stopped");
                        LED_B_OFF();
@@ -1083,7 +1135,7 @@ void ListenReaderField(int limit)
                WDT_HIT();
 
 
-               if (limit != HF_ONLY) 
+               if (limit != HF_ONLY)
                        {
                        if (abs(lf_av - lf_baseline) > 10)
                                LED_D_ON();
@@ -1092,7 +1144,7 @@ void ListenReaderField(int limit)
                        ++lf_count;
                        lf_av_new= ReadAdc(ADC_CHAN_LF);
                        // see if there's a significant change
-                       if(abs(lf_av - lf_av_new) > 10) 
+                       if(abs(lf_av - lf_av_new) > 10)
                                {
                                DbpString("LF 125/134 Field Change:");
                                DbpIntegers(lf_av,lf_av_new,lf_count);
@@ -1101,7 +1153,7 @@ void ListenReaderField(int limit)
                                }
                        }
 
-               if (limit != LF_ONLY) 
+               if (limit != LF_ONLY)
                        {
                        if (abs(hf_av - hf_baseline) > 10)
                                LED_B_ON();
@@ -1110,7 +1162,7 @@ void ListenReaderField(int limit)
                        ++hf_count;
                        hf_av_new= ReadAdc(ADC_CHAN_HF);
                        // see if there's a significant change
-                       if(abs(hf_av - hf_av_new) > 10) 
+                       if(abs(hf_av - hf_av_new) > 10)
                                {
                                DbpString("HF 13.56 Field Change:");
                                DbpIntegers(hf_av,hf_av_new,hf_count);
Impressum, Datenschutz