X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/blobdiff_plain/a631936e84fa35d04bef9c45928ee602a258d6c4..refs/pull/121/head:/armsrc/appmain.c?ds=inline diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 13995f59..bd1075c1 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -18,11 +18,13 @@ #include "util.h" #include "printf.h" #include "string.h" + #include #include "legicrf.h" #include - +#include "lfsampling.h" +#include "BigBuf.h" #ifdef WITH_LCD #include "LCD.h" #endif @@ -41,12 +43,6 @@ int ToSendMax; static int ToSendBit; struct common_area common_area __attribute__((section(".commonarea"))); -void BufferClear(void) -{ - memset(BigBuf,0,sizeof(BigBuf)); - Dbprintf("Buffer cleared (%i bytes)",sizeof(BigBuf)); -} - void ToSendReset(void) { ToSendMax = -1; @@ -140,12 +136,25 @@ static int ReadAdc(int ch) AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST; AT91C_BASE_ADC->ADC_MR = - ADC_MODE_PRESCALE(32) | - ADC_MODE_STARTUP_TIME(16) | - ADC_MODE_SAMPLE_HOLD_TIME(8); + ADC_MODE_PRESCALE(63 /* was 32 */) | // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz + ADC_MODE_STARTUP_TIME(1 /* was 16 */) | // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us + ADC_MODE_SAMPLE_HOLD_TIME(15 /* was 8 */); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us + + // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value. + // Both AMPL_LO and AMPL_HI are very high impedance (10MOhm) outputs, the input capacitance of the ADC is 12pF (typical). This results in a time constant + // of RC = 10MOhm * 12pF = 120us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged. + // + // The maths are: + // If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be + // + // v_cap = v_in * (1 - exp(-RC/SHTIM)) = v_in * (1 - exp(-3)) = v_in * 0,95 (i.e. an error of 5%) + // + // Note: with the "historic" values in the comments above, the error was 34% !!! + AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch); AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; + while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) ; d = AT91C_BASE_ADC->ADC_CDR[ch]; @@ -188,9 +197,7 @@ void MeasureAntennaTuning(void) WDT_HIT(); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); SpinDelay(20); - // 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); + adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); if (i==95) vLf125 = adcval; // voltage at 125Khz if (i==89) vLf134 = adcval; // voltage at 134Khz @@ -210,11 +217,9 @@ void MeasureAntennaTuning(void) FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); SpinDelay(20); - // Vref = 3300mV, and an 10:1 voltage divider on the input - // can measure voltages up to 33000 mV - vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10; + vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; - cmd_send(CMD_MEASURED_ANTENNA_TUNING,vLf125|(vLf134<<16),vHf,peakf|(peakv<<16),LF_Results,256); + cmd_send(CMD_MEASURED_ANTENNA_TUNING, vLf125 | (vLf134<<16), vHf, peakf | (peakv<<16), LF_Results, 256); FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LED_A_OFF(); LED_B_OFF(); @@ -227,25 +232,30 @@ void MeasureAntennaTuningHf(void) DbpString("Measuring HF antenna, press button to exit"); + // Let the FPGA drive the high-frequency antenna around 13.56 MHz. + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); + for (;;) { - // Let the FPGA drive the high-frequency antenna around 13.56 MHz. - FpgaDownloadAndGo(FPGA_BITSTREAM_HF); - FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); SpinDelay(20); - // Vref = 3300mV, and an 10:1 voltage divider on the input - // can measure voltages up to 33000 mV - vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10; + vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; Dbprintf("%d mV",vHf); if (BUTTON_PRESS()) break; } DbpString("cancelled"); + + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); + } void SimulateTagHfListen(void) { - uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET; + // ToDo: historically this used the free buffer, which was 2744 Bytes long. + // There might be a better size to be defined: + #define HF_14B_SNOOP_BUFFER_SIZE 2744 + uint8_t *dest = BigBuf_malloc(HF_14B_SNOOP_BUFFER_SIZE); uint8_t v = 0; int i; int p = 0; @@ -280,7 +290,7 @@ void SimulateTagHfListen(void) p = 0; i++; - if(i >= FREE_BUFFER_SIZE) { + if(i >= HF_14B_SNOOP_BUFFER_SIZE) { break; } } @@ -514,26 +524,32 @@ static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]); void ListenReaderField(int limit) { - int lf_av, lf_av_new, lf_baseline= 0, lf_count= 0, lf_max; - int hf_av, hf_av_new, hf_baseline= 0, hf_count= 0, hf_max; + int lf_av, lf_av_new, lf_baseline= 0, lf_max; + int hf_av, hf_av_new, hf_baseline= 0, hf_max; int mode=1, display_val, display_max, i; -#define LF_ONLY 1 -#define HF_ONLY 2 +#define LF_ONLY 1 +#define HF_ONLY 2 +#define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE + + + // switch off FPGA - we don't want to measure our own signal + FpgaDownloadAndGo(FPGA_BITSTREAM_HF); + FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); LEDsoff(); - lf_av=lf_max=ReadAdc(ADC_CHAN_LF); + lf_av = lf_max = AvgAdc(ADC_CHAN_LF); if(limit != HF_ONLY) { - Dbprintf("LF 125/134 Baseline: %d", lf_av); + Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10); lf_baseline = lf_av; } - hf_av=hf_max=ReadAdc(ADC_CHAN_HF); + hf_av = hf_max = AvgAdc(ADC_CHAN_HF); if (limit != LF_ONLY) { - Dbprintf("HF 13.56 Baseline: %d", hf_av); + Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10); hf_baseline = hf_av; } @@ -556,38 +572,38 @@ void ListenReaderField(int limit) WDT_HIT(); if (limit != HF_ONLY) { - if(mode==1) { - if (abs(lf_av - lf_baseline) > 10) LED_D_ON(); - else LED_D_OFF(); + if(mode == 1) { + if (abs(lf_av - lf_baseline) > REPORT_CHANGE) + LED_D_ON(); + else + LED_D_OFF(); } - ++lf_count; - lf_av_new= ReadAdc(ADC_CHAN_LF); + lf_av_new = AvgAdc(ADC_CHAN_LF); // see if there's a significant change - if(abs(lf_av - lf_av_new) > 10) { - Dbprintf("LF 125/134 Field Change: %x %x %x", lf_av, lf_av_new, lf_count); + if(abs(lf_av - lf_av_new) > REPORT_CHANGE) { + Dbprintf("LF 125/134kHz Field Change: %5dmV", (MAX_ADC_LF_VOLTAGE * lf_av_new) >> 10); lf_av = lf_av_new; if (lf_av > lf_max) lf_max = lf_av; - lf_count= 0; } } if (limit != LF_ONLY) { if (mode == 1){ - if (abs(hf_av - hf_baseline) > 10) LED_B_ON(); - else LED_B_OFF(); + if (abs(hf_av - hf_baseline) > REPORT_CHANGE) + LED_B_ON(); + else + LED_B_OFF(); } - ++hf_count; - hf_av_new= ReadAdc(ADC_CHAN_HF); + hf_av_new = AvgAdc(ADC_CHAN_HF); // see if there's a significant change - if(abs(hf_av - hf_av_new) > 10) { - Dbprintf("HF 13.56 Field Change: %x %x %x", hf_av, hf_av_new, hf_count); + if(abs(hf_av - hf_av_new) > REPORT_CHANGE) { + Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10); hf_av = hf_av_new; if (hf_av > hf_max) hf_max = hf_av; - hf_count= 0; } } @@ -628,16 +644,17 @@ void UsbPacketReceived(uint8_t *packet, int len) switch(c->cmd) { #ifdef WITH_LF + case CMD_SET_LF_SAMPLING_CONFIG: + setSamplingConfig((sample_config *) c->d.asBytes); + break; case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K: - AcquireRawAdcSamples125k(c->arg[0]); - cmd_send(CMD_ACK,0,0,0,0,0); + cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0); break; case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K: ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes); break; case CMD_LF_SNOOP_RAW_ADC_SAMPLES: - SnoopLFRawAdcSamples(c->arg[0], c->arg[1]); - cmd_send(CMD_ACK,0,0,0,0,0); + cmd_send(CMD_ACK,SnoopLF(),0,0,0,0); break; case CMD_HID_DEMOD_FSK: CmdHIDdemodFSK(c->arg[0], 0, 0, 1); @@ -645,6 +662,15 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_HID_SIM_TAG: CmdHIDsimTAG(c->arg[0], c->arg[1], 1); break; + case CMD_FSK_SIM_TAG: + CmdFSKsimTAG(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_ASK_SIM_TAG: + CmdASKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_PSK_SIM_TAG: + CmdPSKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; case CMD_HID_CLONE_TAG: CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]); break; @@ -667,7 +693,9 @@ void UsbPacketReceived(uint8_t *packet, int len) WriteTItag(c->arg[0],c->arg[1],c->arg[2]); break; case CMD_SIMULATE_TAG_125K: + LED_A_ON(); SimulateTagLowFrequency(c->arg[0], c->arg[1], 1); + LED_A_OFF(); break; case CMD_LF_SIMULATE_BIDIR: SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]); @@ -710,7 +738,7 @@ void UsbPacketReceived(uint8_t *packet, int len) ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes); break; #endif - + #ifdef WITH_ISO15693 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693: AcquireRawAdcSamplesIso15693(); @@ -788,40 +816,40 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_EPA_PACE_COLLECT_NONCE: EPA_PACE_Collect_Nonce(c); break; + case CMD_EPA_PACE_REPLAY: + EPA_PACE_Replay(c); + break; case CMD_READER_MIFARE: - ReaderMifare(c->arg[0]); + ReaderMifare(c->arg[0]); break; case CMD_MIFARE_READBL: MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); break; case CMD_MIFAREU_READBL: - MifareUReadBlock(c->arg[0],c->d.asBytes); - break; - case CMD_MIFAREUC_AUTH1: - MifareUC_Auth1(c->arg[0],c->d.asBytes); + MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes); break; - case CMD_MIFAREUC_AUTH2: - MifareUC_Auth2(c->arg[0],c->d.asBytes); + case CMD_MIFAREUC_AUTH: + MifareUC_Auth(c->arg[0],c->d.asBytes); break; case CMD_MIFAREU_READCARD: - MifareUReadCard(c->arg[0],c->arg[1],c->d.asBytes); - break; - case CMD_MIFAREUC_READCARD: - MifareUReadCard(c->arg[0],c->arg[1],c->d.asBytes); - break; + MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); + break; + case CMD_MIFAREUC_SETPWD: + MifareUSetPwd(c->arg[0], c->d.asBytes); + break; case CMD_MIFARE_READSC: MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); break; case CMD_MIFARE_WRITEBL: MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); break; - case CMD_MIFAREU_WRITEBL_COMPAT: - MifareUWriteBlock(c->arg[0], c->d.asBytes); - break; + //case CMD_MIFAREU_WRITEBL_COMPAT: + //MifareUWriteBlockCompat(c->arg[0], c->d.asBytes); + //break; case CMD_MIFAREU_WRITEBL: - MifareUWriteBlock_Special(c->arg[0], c->d.asBytes); - break; + MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes); + break; case CMD_MIFARE_NESTED: MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); break; @@ -881,6 +909,9 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_READER_ICLASS_REPLAY: ReaderIClass_Replay(c->arg[0], c->d.asBytes); break; + case CMD_ICLASS_EML_MEMSET: + emlSet(c->d.asBytes,c->arg[0], c->arg[1]); + break; #endif case CMD_SIMULATE_TAG_HF_LISTEN: @@ -888,7 +919,7 @@ void UsbPacketReceived(uint8_t *packet, int len) break; case CMD_BUFF_CLEAR: - BufferClear(); + BigBuf_Clear(); break; case CMD_MEASURE_ANTENNA_TUNING: @@ -912,17 +943,18 @@ void UsbPacketReceived(uint8_t *packet, int len) case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: LED_B_ON(); + uint8_t *BigBuf = BigBuf_get_addr(); for(size_t i=0; iarg[1]; i += USB_CMD_DATA_SIZE) { size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE); - cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,((byte_t*)BigBuf)+c->arg[0]+i,len); + cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len); } // Trigger a finish downloading signal with an ACK frame - cmd_send(CMD_ACK,0,0,0,0,0); + cmd_send(CMD_ACK,1,0,BigBuf_get_traceLen(),getSamplingConfig(),sizeof(sample_config)); LED_B_OFF(); break; case CMD_DOWNLOADED_SIM_SAMPLES_125K: { - uint8_t *b = (uint8_t *)BigBuf; + uint8_t *b = BigBuf_get_addr(); memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE); cmd_send(CMD_ACK,0,0,0,0,0); break; @@ -993,7 +1025,7 @@ void UsbPacketReceived(uint8_t *packet, int len) void __attribute__((noreturn)) AppMain(void) { SpinDelay(100); - + clear_trace(); if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) { /* Initialize common area */ memset(&common_area, 0, sizeof(common_area));