From 050aa18b13084b0d57ffcee352bf7a30b828b8f5 Mon Sep 17 00:00:00 2001 From: pwpiwi Date: Fri, 21 Sep 2018 08:27:35 +0200 Subject: [PATCH] RDV40 compatibility fixes (#678) * detect and use RDV40 higher voltage ADC channel for hw tune, hf tune, hw detectreader * fix mode switching in hw detectreader * detect Smartcard Slot in hw version * i2c changes from https://github.com/RfidResearchGroup/proxmark3 * some formatting in proxmark3.h --- armsrc/Makefile | 7 +- armsrc/appmain.c | 95 ++++++++----- armsrc/apps.h | 5 +- armsrc/i2c.c | 335 +++++++++++++++++++++++++++++--------------- armsrc/i2c.h | 33 +---- armsrc/iso14443a.c | 8 +- armsrc/mifaresim.c | 2 +- include/proxmark3.h | 123 ++++++++-------- 8 files changed, 358 insertions(+), 250 deletions(-) diff --git a/armsrc/Makefile b/armsrc/Makefile index 046ad1bc..d230cda1 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -26,11 +26,8 @@ SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c mifares SRC_ISO14443b = iso14443b.c SRC_CRAPTO1 = crypto1.c des.c SRC_CRC = iso14443crc.c crc.c crc16.c crc32.c parity.c -ifneq (,$(findstring WITH_SMARTCARD,$(APP_CFLAGS))) - SRC_SMARTCARD = i2c.c -else - SRC_SMARTCARD = -endif +SRC_SMARTCARD = i2c.c + #the FPGA bitstream files. Note: order matters! FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit diff --git a/armsrc/appmain.c b/armsrc/appmain.c index e6d40abc..573a3a71 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -28,12 +28,10 @@ #include "BigBuf.h" #include "mifareutil.h" #include "pcf7931.h" +#include "i2c.h" #ifdef WITH_LCD #include "LCD.h" #endif -#ifdef WITH_SMARTCARD - #include "i2c.h" -#endif // Craig Young - 14a stand-alone code @@ -143,7 +141,7 @@ void Dbhexdump(int len, uint8_t *d, bool bAsci) { static int ReadAdc(int ch) { // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value. - // AMPL_HI is are high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant + // AMPL_HI is a high impedance (10MOhm || 1MOhm) output, the input capacitance of the ADC is 12pF (typical). This results in a time constant // of RC = (0.91MOhm) * 12pF = 10.9us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged. // // The maths are: @@ -162,7 +160,7 @@ static int ReadAdc(int ch) while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch))) {}; - return AT91C_BASE_ADC->ADC_CDR[ch]; + return AT91C_BASE_ADC->ADC_CDR[ch] & 0x3ff; } int AvgAdc(int ch) // was static - merlok @@ -177,6 +175,26 @@ int AvgAdc(int ch) // was static - merlok return (a + 15) >> 5; } +static int AvgAdc_Voltage_HF(void) +{ + int AvgAdc_Voltage_Low, AvgAdc_Voltage_High; + + AvgAdc_Voltage_Low= (MAX_ADC_HF_VOLTAGE_LOW * AvgAdc(ADC_CHAN_HF_LOW)) >> 10; + // if voltage range is about to be exceeded, use high voltage ADC channel if available (RDV40 only) + if (AvgAdc_Voltage_Low > MAX_ADC_HF_VOLTAGE_LOW - 300) { + AvgAdc_Voltage_High = (MAX_ADC_HF_VOLTAGE_HIGH * AvgAdc(ADC_CHAN_HF_HIGH)) >> 10; + if (AvgAdc_Voltage_High >= AvgAdc_Voltage_Low) { + return AvgAdc_Voltage_High; + } + } + return AvgAdc_Voltage_Low; +} + +static int AvgAdc_Voltage_LF(void) +{ + return (MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10; +} + void MeasureAntennaTuningLfOnly(int *vLf125, int *vLf134, int *peakf, int *peakv, uint8_t LF_Results[]) { int i, adcval = 0, peak = 0; @@ -198,7 +216,7 @@ void MeasureAntennaTuningLfOnly(int *vLf125, int *vLf134, int *peakf, int *peakv WDT_HIT(); FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i); SpinDelay(20); - adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10); + adcval = AvgAdc_Voltage_LF(); if (i==95) *vLf125 = adcval; // voltage at 125Khz if (i==89) *vLf134 = adcval; // voltage at 134Khz @@ -223,9 +241,8 @@ void MeasureAntennaTuningHfOnly(int *vHf) FpgaDownloadAndGo(FPGA_BITSTREAM_HF); FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); SpinDelay(20); - *vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + *vHf = AvgAdc_Voltage_HF(); LED_A_OFF(); - return; } @@ -267,8 +284,8 @@ void MeasureAntennaTuningHf(void) FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR); for (;;) { - SpinDelay(20); - vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + SpinDelay(500); + vHf = AvgAdc_Voltage_HF(); Dbprintf("%d mV",vHf); if (BUTTON_PRESS()) break; @@ -293,6 +310,7 @@ extern struct version_information version_information; /* bootrom version information is pointed to from _bootphase1_version_pointer */ extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__; + void SendVersion(void) { char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */ @@ -315,11 +333,16 @@ void SendVersion(void) for (int i = 0; i < fpga_bitstream_num; i++) { strncat(VersionString, fpga_version_information[i], sizeof(VersionString) - strlen(VersionString) - 1); - if (i < fpga_bitstream_num - 1) { - strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1); - } + strncat(VersionString, "\n", sizeof(VersionString) - strlen(VersionString) - 1); } - + + // test availability of SmartCard slot + if (I2C_is_available()) { + strncat(VersionString, "SmartCard Slot: available\n", sizeof(VersionString) - strlen(VersionString) - 1); + } else { + strncat(VersionString, "SmartCard Slot: not available\n", sizeof(VersionString) - strlen(VersionString) - 1); + } + // Send Chip ID and used flash memory uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start; uint32_t compressed_data_section_size = common_area.arg1; @@ -828,13 +851,15 @@ 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_max; - int hf_av, hf_av_new, hf_baseline= 0, hf_max; + int lf_av, lf_av_new=0, lf_baseline= 0, lf_max; + int hf_av, hf_av_new=0, hf_baseline= 0, hf_max; int mode=1, display_val, display_max, i; -#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 +#define LF_ONLY 1 +#define HF_ONLY 2 +#define REPORT_CHANGE_PERCENT 5 // report new values only if they have changed at least by REPORT_CHANGE_PERCENT +#define MIN_HF_FIELD 300 // in mode 1 signal HF field greater than MIN_HF_FIELD above baseline +#define MIN_LF_FIELD 1200 // in mode 1 signal LF field greater than MIN_LF_FIELD above baseline // switch off FPGA - we don't want to measure our own signal @@ -843,23 +868,23 @@ void ListenReaderField(int limit) LEDsoff(); - lf_av = lf_max = AvgAdc(ADC_CHAN_LF); + lf_av = lf_max = AvgAdc_Voltage_LF(); if(limit != HF_ONLY) { - Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10); + Dbprintf("LF 125/134kHz Baseline: %dmV", lf_av); lf_baseline = lf_av; } - hf_av = hf_max = AvgAdc(ADC_CHAN_HF); - + hf_av = hf_max = AvgAdc_Voltage_HF(); + if (limit != LF_ONLY) { - Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10); + Dbprintf("HF 13.56MHz Baseline: %dmV", hf_av); hf_baseline = hf_av; } for(;;) { + SpinDelay(500); if (BUTTON_PRESS()) { - SpinDelay(500); switch (mode) { case 1: mode=2; @@ -872,21 +897,22 @@ void ListenReaderField(int limit) return; break; } + while (BUTTON_PRESS()); } WDT_HIT(); if (limit != HF_ONLY) { if(mode == 1) { - if (ABS(lf_av - lf_baseline) > REPORT_CHANGE) + if (lf_av - lf_baseline > MIN_LF_FIELD) LED_D_ON(); else LED_D_OFF(); } - lf_av_new = AvgAdc(ADC_CHAN_LF); + lf_av_new = AvgAdc_Voltage_LF(); // see if there's a significant change - if(ABS(lf_av - lf_av_new) > REPORT_CHANGE) { - Dbprintf("LF 125/134kHz Field Change: %5dmV", (MAX_ADC_LF_VOLTAGE * lf_av_new) >> 10); + if (ABS((lf_av - lf_av_new)*100/(lf_av?lf_av:1)) > REPORT_CHANGE_PERCENT) { + Dbprintf("LF 125/134kHz Field Change: %5dmV", lf_av_new); lf_av = lf_av_new; if (lf_av > lf_max) lf_max = lf_av; @@ -895,16 +921,17 @@ void ListenReaderField(int limit) if (limit != LF_ONLY) { if (mode == 1){ - if (ABS(hf_av - hf_baseline) > REPORT_CHANGE) + if (hf_av - hf_baseline > MIN_HF_FIELD) LED_B_ON(); else LED_B_OFF(); } - hf_av_new = AvgAdc(ADC_CHAN_HF); + hf_av_new = AvgAdc_Voltage_HF(); + // see if there's a significant change - if(ABS(hf_av - hf_av_new) > REPORT_CHANGE) { - Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10); + if (ABS((hf_av - hf_av_new)*100/(hf_av?hf_av:1)) > REPORT_CHANGE_PERCENT) { + Dbprintf("HF 13.56MHz Field Change: %5dmV", hf_av_new); hf_av = hf_av_new; if (hf_av > hf_max) hf_max = hf_av; @@ -1436,7 +1463,7 @@ void __attribute__((noreturn)) AppMain(void) LED_A_OFF(); // Init USB device - usb_enable(); + usb_enable(); // The FPGA gets its clock from us from PCK0 output, so set that up. AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0; diff --git a/armsrc/apps.h b/armsrc/apps.h index 5b981f4f..6f728c61 100644 --- a/armsrc/apps.h +++ b/armsrc/apps.h @@ -42,9 +42,10 @@ void Dbprintf(const char *fmt, ...); void Dbhexdump(int len, uint8_t *d, bool bAsci); // ADC Vref = 3300mV, and an (10M+1M):1M voltage divider on the HF input can measure voltages up to 36300 mV -#define MAX_ADC_HF_VOLTAGE 36300 +#define MAX_ADC_HF_VOLTAGE_LOW 36300 // ADC Vref = 3300mV, and an (10000k+240k):240k voltage divider on the LF input can measure voltages up to 140800 mV -#define MAX_ADC_LF_VOLTAGE 140800 +#define MAX_ADC_HF_VOLTAGE_HIGH 140800 +#define MAX_ADC_LF_VOLTAGE 140800 int AvgAdc(int ch); void ToSendStuffBit(int b); diff --git a/armsrc/i2c.c b/armsrc/i2c.c index 721b4b2e..7efb1fd3 100644 --- a/armsrc/i2c.c +++ b/armsrc/i2c.c @@ -8,9 +8,21 @@ //----------------------------------------------------------------------------- // The main i2c code, for communications with smart card module //----------------------------------------------------------------------------- + #include "i2c.h" -#include "mifareutil.h" //for mf_dbglevel + +#include +#include #include "string.h" //for memset memcmp +#include "proxmark3.h" +#include "mifareutil.h" // for MF_DBGLEVEL +#include "BigBuf.h" +#include "apps.h" + +#ifdef WITH_SMARTCARD +#include "smartcard.h" +#endif + // ¶¨ÒåÁ¬½ÓÒý½Å #define GPIO_RST AT91C_PIO_PA1 @@ -27,13 +39,13 @@ #define I2C_ERROR "I2C_WaitAck Error" -volatile unsigned long c; +static volatile unsigned long c; // Ö±½ÓʹÓÃÑ­»·À´ÑÓʱ£¬Ò»¸öÑ­»· 6 ÌõÖ¸Á48M£¬ Delay=1 ´ó¸ÅΪ 200kbps // timer. // I2CSpinDelayClk(4) = 12.31us // I2CSpinDelayClk(1) = 3.07us -void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { +static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { for (c = delay * 2; c; c--) {}; } @@ -45,23 +57,19 @@ void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) { #define ISO7618_MAX_FRAME 255 -void I2C_init(void) { - // ÅäÖø´Î»Òý½Å£¬¹Ø±ÕÉÏÀ­£¬ÍÆÍìÊä³ö£¬Ä¬ÈÏ¸ß - // Configure reset pin, close up pull up, push-pull output, default high - AT91C_BASE_PIOA->PIO_PPUDR = GPIO_RST; - AT91C_BASE_PIOA->PIO_MDDR = GPIO_RST; +static void I2C_init(void) { + // Configure reset pin + AT91C_BASE_PIOA->PIO_PPUDR = GPIO_RST; // disable pull up resistor + AT91C_BASE_PIOA->PIO_MDDR = GPIO_RST; // push-pull output (multidriver disabled) - // ÅäÖà I2C Òý½Å£¬¿ªÆôÉÏÀ­£¬¿ªÂ©Êä³ö - // Configure I2C pin, open up, open leakage - AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_SCL | GPIO_SDA); // ´ò¿ªÉÏÀ­ Open up the pull up - AT91C_BASE_PIOA->PIO_MDER |= (GPIO_SCL | GPIO_SDA); + // Configure SCL and SDA pins + AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_SCL | GPIO_SDA); // enable pull up resistor + AT91C_BASE_PIOA->PIO_MDER |= (GPIO_SCL | GPIO_SDA); // open drain output (multidriver enabled) - requires external pull up resistor - // ĬÈÏÈý¸ùÏßÈ«²¿À­¸ß - // default three lines all pull up + // set all three outputs to high AT91C_BASE_PIOA->PIO_SODR |= (GPIO_SCL | GPIO_SDA | GPIO_RST); - // ÔÊÐíÊä³ö - // allow output + // configure all three pins as output, controlled by PIOA AT91C_BASE_PIOA->PIO_OER |= (GPIO_SCL | GPIO_SDA | GPIO_RST); AT91C_BASE_PIOA->PIO_PER |= (GPIO_SCL | GPIO_SDA | GPIO_RST); } @@ -69,7 +77,7 @@ void I2C_init(void) { // ÉèÖø´Î»×´Ì¬ // set the reset state -void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA) { +static void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA) { if (LineRST) HIGH(GPIO_RST); else @@ -89,7 +97,7 @@ void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA) { // ¸´Î»½øÈëÖ÷³ÌÐò // Reset the SIM_Adapter, then enter the main program // Note: the SIM_Adapter will not enter the main program after power up. Please run this function before use SIM_Adapter. -void I2C_Reset_EnterMainProgram(void) { +static void I2C_Reset_EnterMainProgram(void) { I2C_SetResetStatus(0, 0, 0); // À­µÍ¸´Î»Ïß SpinDelay(30); I2C_SetResetStatus(1, 0, 0); // ½â³ý¸´Î» @@ -98,19 +106,9 @@ void I2C_Reset_EnterMainProgram(void) { SpinDelay(10); } -// ¸´Î»½øÈëÒýµ¼Ä£Ê½ -// Reset the SIM_Adapter, then enter the bootloader program -// Reserve£ºFor firmware update. -void I2C_Reset_EnterBootloader(void) { - I2C_SetResetStatus(0, 1, 1); // À­µÍ¸´Î»Ïß - SpinDelay(100); - I2C_SetResetStatus(1, 1, 1); // ½â³ý¸´Î» - SpinDelay(10); -} - // µÈ´ýʱÖÓ±ä¸ß // Wait for the clock to go High. -bool WaitSCL_H_delay(uint32_t delay) { +static bool WaitSCL_H_delay(uint32_t delay) { while (delay--) { if (SCL_read) { return true; @@ -120,26 +118,26 @@ bool WaitSCL_H_delay(uint32_t delay) { return false; } -// 5000 * 3.07us = 15350us. 15.35ms -bool WaitSCL_H(void) { - return WaitSCL_H_delay(5000); +// 15000 * 3.07us = 46050us. 46.05ms +static bool WaitSCL_H(void) { + return WaitSCL_H_delay(15000); } -// Wait max 300ms or until SCL goes LOW. -// Which ever comes first -bool WaitSCL_L_300ms(void) { - volatile uint16_t delay = 300; - while ( delay-- ) { - // exit on SCL LOW - if (!SCL_read) +bool WaitSCL_L_delay(uint32_t delay) { + while (delay--) { + if (!SCL_read) { return true; - - SpinDelay(1); + } + I2C_DELAY_1CLK; } - return (delay == 0); + return false; } -bool I2C_Start(void) { +bool WaitSCL_L(void) { + return WaitSCL_L_delay(15000); +} + +static bool I2C_Start(void) { I2C_DELAY_XCLK(4); SDA_H; I2C_DELAY_1CLK; @@ -155,22 +153,8 @@ bool I2C_Start(void) { return true; } -bool I2C_WaitForSim() { - // variable delay here. - if (!WaitSCL_L_300ms()) - return false; - - // 8051 speaks with smart card. - // 1000*50*3.07 = 153.5ms - // 1byte transfer == 1ms - if (!WaitSCL_H_delay(2000*50) ) - return false; - - return true; -} - // send i2c STOP -void I2C_Stop(void) { +static void I2C_Stop(void) { SCL_L; I2C_DELAY_2CLK; SDA_L; I2C_DELAY_2CLK; SCL_H; I2C_DELAY_2CLK; @@ -179,29 +163,14 @@ void I2C_Stop(void) { I2C_DELAY_XCLK(8); } -// Send i2c ACK -void I2C_Ack(void) { - SCL_L; I2C_DELAY_2CLK; - SDA_L; I2C_DELAY_2CLK; - SCL_H; I2C_DELAY_2CLK; - SCL_L; I2C_DELAY_2CLK; -} - -// Send i2c NACK -void I2C_NoAck(void) { - SCL_L; I2C_DELAY_2CLK; - SDA_H; I2C_DELAY_2CLK; - SCL_H; I2C_DELAY_2CLK; - SCL_L; I2C_DELAY_2CLK; -} - -bool I2C_WaitAck(void) { +static bool I2C_WaitAck(void) { SCL_L; I2C_DELAY_1CLK; SDA_H; I2C_DELAY_1CLK; SCL_H; if (!WaitSCL_H()) return false; + I2C_DELAY_2CLK; I2C_DELAY_2CLK; if (SDA_read) { SCL_L; @@ -211,10 +180,10 @@ bool I2C_WaitAck(void) { return true; } -void I2C_SendByte(uint8_t data) { - uint8_t i = 8; +static void I2C_SendByte(uint8_t data) { + uint8_t bits = 8; - while (i--) { + while (bits--) { SCL_L; I2C_DELAY_1CLK; if (data & 0x80) @@ -223,6 +192,7 @@ void I2C_SendByte(uint8_t data) { SDA_L; data <<= 1; + I2C_DELAY_1CLK; SCL_H; @@ -234,18 +204,92 @@ void I2C_SendByte(uint8_t data) { SCL_L; } -uint8_t I2C_ReadByte(void) { - uint8_t i = 8, b = 0; +bool I2C_is_available(void) { + I2C_init(); + I2C_Reset_EnterMainProgram(); + if (!I2C_Start()) // some other device is active on the bus + return true; + I2C_SendByte(I2C_DEVICE_ADDRESS_MAIN & 0xFE); + if (!I2C_WaitAck()) { // no response from smartcard reader + I2C_Stop(); + return false; + } + I2C_Stop(); + return true; +} + +#ifdef WITH_SMARTCARD +// ¸´Î»½øÈëÒýµ¼Ä£Ê½ +// Reset the SIM_Adapter, then enter the bootloader program +// Reserve£ºFor firmware update. +static void I2C_Reset_EnterBootloader(void) { + I2C_SetResetStatus(0, 1, 1); // À­µÍ¸´Î»Ïß + SpinDelay(100); + I2C_SetResetStatus(1, 1, 1); // ½â³ý¸´Î» + SpinDelay(10); +} + +// Wait max 300ms or until SCL goes LOW. +// Which ever comes first +static bool WaitSCL_L_300ms(void) { + volatile uint16_t delay = 310; + while ( delay-- ) { + // exit on SCL LOW + if (!SCL_read) + return true; + + SpinDelay(1); + } + return (delay == 0); +} + +static bool I2C_WaitForSim() { + // variable delay here. + if (!WaitSCL_L_300ms()) + return false; + + // 8051 speaks with smart card. + // 1000*50*3.07 = 153.5ms + // 1byte transfer == 1ms with max frame being 256bytes + if (!WaitSCL_H_delay(10 * 1000 * 50)) + return false; + + return true; +} + +// Send i2c ACK +static void I2C_Ack(void) { + SCL_L; I2C_DELAY_2CLK; + SDA_L; I2C_DELAY_2CLK; + SCL_H; I2C_DELAY_2CLK; + if (!WaitSCL_H()) return; + SCL_L; I2C_DELAY_2CLK; +} + +// Send i2c NACK +static void I2C_NoAck(void) { + SCL_L; I2C_DELAY_2CLK; + SDA_H; I2C_DELAY_2CLK; + SCL_H; I2C_DELAY_2CLK; + if (!WaitSCL_H()) return; + SCL_L; I2C_DELAY_2CLK; +} + +static int16_t I2C_ReadByte(void) { + uint8_t bits = 8, b = 0; SDA_H; - while (i--) { + while (bits--) { b <<= 1; - SCL_L; I2C_DELAY_2CLK; + SCL_L; + if (!WaitSCL_L()) return -2; + + I2C_DELAY_1CLK; + SCL_H; - if (!WaitSCL_H()) - return 0; + if (!WaitSCL_H()) return -1; - I2C_DELAY_2CLK; + I2C_DELAY_1CLK; if (SDA_read) b |= 0x01; } @@ -254,7 +298,7 @@ uint8_t I2C_ReadByte(void) { } // Sends one byte ( command to be written, SlaveDevice address) -bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address) { +static bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address) { bool bBreak = true; do { if (!I2C_Start()) @@ -281,7 +325,7 @@ bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address) { // дÈë1×Ö½ÚÊý¾Ý £¨´ýдÈëÊý¾Ý£¬´ýдÈëµØÖ·£¬Æ÷¼þÀàÐÍ£© // Sends 1 byte data (Data to be written, command to be written , SlaveDevice address ). -bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address) { +static bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address) { bool bBreak = true; do { if (!I2C_Start()) @@ -313,7 +357,7 @@ bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address) { // дÈë1´®Êý¾Ý£¨´ýдÈëÊý×éµØÖ·£¬´ýдÈ볤¶È£¬´ýдÈëµØÖ·£¬Æ÷¼þÀàÐÍ£© //Sends a string of data (Array, length, command to be written , SlaveDevice address ). // len = uint8 (max buffer to write 256bytes) -bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) { +static bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) { bool bBreak = true; do { if (!I2C_Start()) @@ -352,16 +396,16 @@ bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t dev // ¶Á³ö1´®Êý¾Ý£¨´æ·Å¶Á³öÊý¾Ý£¬´ý¶Á³ö³¤¶È£¬´ø¶Á³öµØÖ·£¬Æ÷¼þÀàÐÍ£© // read 1 strings of data (Data array, Readout length, command to be written , SlaveDevice address ). // len = uint8 (max buffer to read 256bytes) -uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) { +static int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) { if ( !data || len == 0 ) return 0; // extra wait 500us (514us measured) // 200us (xx measured) - SpinDelayUs(200); + SpinDelayUs(600); bool bBreak = true; - uint8_t readcount = 0; + uint16_t readcount = 0; do { if (!I2C_Start()) @@ -391,11 +435,14 @@ uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d return 0; } - // reading while (len) { - *data = I2C_ReadByte(); - + int16_t tmp = I2C_ReadByte(); + if ( tmp < 0 ) + return tmp; + + *data = (uint8_t)tmp & 0xFF; + len--; // ¶ÁÈ¡µÄµÚÒ»¸ö×Ö½ÚΪºóÐø³¤¶È @@ -416,10 +463,10 @@ uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t d I2C_Stop(); // return bytecount - first byte (which is length byte) - return (readcount) ? --readcount : 0; + return --readcount; } -uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) { +static int16_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) { //START, 0xB0, 0x00, 0x00, START, 0xB1, xx, yy, zz, ......, STOP bool bBreak = true; uint8_t readcount = 0; @@ -461,8 +508,13 @@ uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t // reading while (len) { - *data = I2C_ReadByte(); - + + int16_t tmp = I2C_ReadByte(); + if ( tmp < 0 ) + return tmp; + + *data = (uint8_t)tmp & 0xFF; + data++; readcount++; len--; @@ -478,7 +530,7 @@ uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t return readcount; } -bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) { +static bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) { //START, 0xB0, 0x00, 0x00, xx, yy, zz, ......, STOP bool bBreak = true; @@ -534,30 +586,79 @@ void I2C_print_status(void) { DbpString(" version.................FAILED"); } -bool GetATR(smart_card_atr_t *card_ptr) { +// Will read response from smart card module, retries 3 times to get the data. +static bool sc_rx_bytes(uint8_t* dest, uint8_t *destlen) { + uint8_t i = 3; + int16_t len = 0; + while (i--) { + + I2C_WaitForSim(); + + len = I2C_BufferRead(dest, *destlen, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); + + if ( len > 1 ){ + break; + } else if ( len == 1 ) { + continue; + } else if ( len <= 0 ) { + return false; + } + } + // after three + if ( len <= 1 ) + return false; + + *destlen = (uint8_t)len & 0xFF; + return true; +} + +static bool GetATR(smart_card_atr_t *card_ptr) { - // clear - if ( card_ptr ) { - card_ptr->atr_len = 0; - memset(card_ptr->atr, 0, sizeof(card_ptr->atr)); + if ( !card_ptr ) { + return false; } + card_ptr->atr_len = 0; + memset(card_ptr->atr, 0, sizeof(card_ptr->atr)); + // Send ATR // start [C0 01] stop start C1 len aa bb cc stop] I2C_WriteCmd(I2C_DEVICE_CMD_GENERATE_ATR, I2C_DEVICE_ADDRESS_MAIN); uint8_t cmd[1] = {1}; LogTrace(cmd, 1, 0, 0, NULL, true); - //wait for sim card to answer. + // wait for sim card to answer. + // 1byte = 1ms, max frame 256bytes. Should wait 256ms at least just in case. if (!I2C_WaitForSim()) return false; - // read answer - uint8_t len = I2C_BufferRead(card_ptr->atr, sizeof(card_ptr->atr), I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); - - if ( len == 0 ) + // read bytes from module + uint8_t len = sizeof(card_ptr->atr); + if ( !sc_rx_bytes(card_ptr->atr, &len) ) return false; + uint8_t pos_td = 1; + if ( (card_ptr->atr[1] & 0x10) == 0x10) pos_td++; + if ( (card_ptr->atr[1] & 0x20) == 0x20) pos_td++; + if ( (card_ptr->atr[1] & 0x40) == 0x40) pos_td++; + + // T0 indicate presence T=0 vs T=1. T=1 has checksum TCK + if ( (card_ptr->atr[1] & 0x80) == 0x80) { + + pos_td++; + + // 1 == T1 , presence of checksum TCK + if ( (card_ptr->atr[pos_td] & 0x01) == 0x01) { + uint8_t chksum = 0; + // xor property. will be zero when xored with chksum. + for (uint8_t i = 1; i < len; ++i) + chksum ^= card_ptr->atr[i]; + if ( chksum ) { + if ( MF_DBGLEVEL > 2) DbpString("Wrong ATR checksum"); + } + } + } + // for some reason we only get first byte of atr, if that is so, send dummy command to retrieve the rest of the atr if (len == 1) { @@ -571,10 +672,8 @@ bool GetATR(smart_card_atr_t *card_ptr) { len = len + len2; } - if ( card_ptr ) { - card_ptr->atr_len = len; - LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false); - } + card_ptr->atr_len = len; + LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false); return true; } @@ -631,7 +730,9 @@ void SmartCardRaw( uint64_t arg0, uint64_t arg1, uint8_t *data ) { if ( !I2C_WaitForSim() ) goto OUT; - len = I2C_BufferRead(resp, ISO7618_MAX_FRAME, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN); + // read bytes from module + len = ISO7618_MAX_FRAME; + sc_rx_bytes(resp, &len); LogTrace(resp, len, 0, 0, NULL, false); } OUT: @@ -652,7 +753,7 @@ void SmartCardUpgrade(uint64_t arg0) { I2C_Reset_EnterBootloader(); bool isOK = true; - uint8_t res = 0; + int16_t res = 0; uint16_t length = arg0; uint16_t pos = 0; uint8_t *fwdata = BigBuf_get_addr(); @@ -680,7 +781,7 @@ void SmartCardUpgrade(uint64_t arg0) { // read res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT); - if ( res == 0) { + if ( res <= 0) { DbpString("Reading back failed"); isOK = false; break; @@ -718,3 +819,5 @@ void SmartCardSetClock(uint64_t arg0) { set_tracing(false); LEDsoff(); } + +#endif \ No newline at end of file diff --git a/armsrc/i2c.h b/armsrc/i2c.h index 4c5c5228..a10ac74f 100644 --- a/armsrc/i2c.h +++ b/armsrc/i2c.h @@ -11,12 +11,8 @@ #ifndef __I2C_H #define __I2C_H -#include -#include "proxmark3.h" -#include "apps.h" -#include "util.h" -#include "BigBuf.h" -#include "smartcard.h" +#include +#include #define I2C_DEVICE_ADDRESS_BOOT 0xB0 #define I2C_DEVICE_ADDRESS_MAIN 0xC0 @@ -28,31 +24,14 @@ #define I2C_DEVICE_CMD_SIM_CLC 0x05 #define I2C_DEVICE_CMD_GETVERSION 0x06 +bool I2C_is_available(void); -void I2C_init(void); -void I2C_Reset(void); -void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA); - -void I2C_Reset_EnterMainProgram(void); -void I2C_Reset_EnterBootloader(void); - -bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address); - -bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address); -bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address); -uint8_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address); - -// for firmware -uint8_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address); -bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address); - -bool GetATR(smart_card_atr_t *card_ptr); - -// generic functions +#ifdef WITH_SMARTCARD void SmartCardAtr(void); void SmartCardRaw(uint64_t arg0, uint64_t arg1, uint8_t *data); void SmartCardUpgrade(uint64_t arg0); -//void SmartCardSetBaud(uint64_t arg0); void SmartCardSetClock(uint64_t arg0); void I2C_print_status(void); #endif + +#endif // __I2C_H diff --git a/armsrc/iso14443a.c b/armsrc/iso14443a.c index 0cacaed9..059db71e 100644 --- a/armsrc/iso14443a.c +++ b/armsrc/iso14443a.c @@ -1405,7 +1405,7 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) ADC_MODE_PRESCALE(63) | ADC_MODE_STARTUP_TIME(1) | ADC_MODE_SAMPLE_HOLD_TIME(15); - AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF); + AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ADC_CHAN_HF_LOW); // start ADC AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; @@ -1432,12 +1432,12 @@ int EmGetCmd(uint8_t *received, uint16_t *len, uint8_t *parity) if (BUTTON_PRESS()) return 1; // test if the field exists - if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF)) { + if (AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ADC_CHAN_HF_LOW)) { analogCnt++; - analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF]; + analogAVG += AT91C_BASE_ADC->ADC_CDR[ADC_CHAN_HF_LOW]; AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START; if (analogCnt >= 32) { - if ((MAX_ADC_HF_VOLTAGE * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { + if ((MAX_ADC_HF_VOLTAGE_LOW * (analogAVG / analogCnt) >> 10) < MF_MINFIELDV) { vtime = GetTickCount(); if (!timer) timer = vtime; // 50ms no field --> card to idle state diff --git a/armsrc/mifaresim.c b/armsrc/mifaresim.c index 1fdf99d6..c9264836 100644 --- a/armsrc/mifaresim.c +++ b/armsrc/mifaresim.c @@ -347,7 +347,7 @@ void Mifare1ksim(uint8_t flags, uint8_t exitAfterNReads, uint8_t arg2, uint8_t * // find reader field if (cardSTATE == MFEMUL_NOFIELD) { - int vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10; + int vHf = (MAX_ADC_HF_VOLTAGE_LOW * AvgAdc(ADC_CHAN_HF_LOW)) >> 10; if (vHf > MF_MINFIELDV) { LED_A_ON(); cardSTATE_TO_IDLE(); diff --git a/include/proxmark3.h b/include/proxmark3.h index 6fb6624f..fec7415a 100644 --- a/include/proxmark3.h +++ b/include/proxmark3.h @@ -16,70 +16,71 @@ #include "config_gpio.h" #include "usb_cmd.h" -#define WDT_HIT() AT91C_BASE_WDTC->WDTC_WDCR = 0xa5000001 - -#define PWM_CH_MODE_PRESCALER(x) ((x)<<0) -#define PWM_CHANNEL(x) (1<<(x)) - -#define ADC_CHAN_LF 4 -#define ADC_CHAN_HF 5 -#define ADC_MODE_PRESCALE(x) ((x)<<8) -#define ADC_MODE_STARTUP_TIME(x) ((x)<<16) -#define ADC_MODE_SAMPLE_HOLD_TIME(x) ((x)<<24) -#define ADC_CHANNEL(x) (1<<(x)) -#define ADC_END_OF_CONVERSION(x) (1<<(x)) - -#define SSC_CLOCK_MODE_START(x) ((x)<<8) -#define SSC_FRAME_MODE_WORDS_PER_TRANSFER(x) ((x)<<8) -#define SSC_CLOCK_MODE_SELECT(x) ((x)<<0) -#define SSC_FRAME_MODE_BITS_IN_WORD(x) (((x)-1)<<0) - -#define MC_FLASH_COMMAND_KEY ((0x5a)<<24) -#define MC_FLASH_MODE_FLASH_WAIT_STATES(x) ((x)<<8) -#define MC_FLASH_MODE_MASTER_CLK_IN_MHZ(x) (((x)+((x)/2))<<16) -#define MC_FLASH_COMMAND_PAGEN(x) ((x)<<8) - -#define RST_CONTROL_KEY (0xa5<<24) - -#define PMC_MAIN_OSC_STARTUP_DELAY(x) ((x)<<8) -#define PMC_PLL_DIVISOR(x) (x) -#define PMC_PLL_MULTIPLIER(x) (((x)-1)<<16) -#define PMC_PLL_COUNT_BEFORE_LOCK(x) ((x)<<8) -#define PMC_PLL_FREQUENCY_RANGE(x) ((x)<<14) -#define PMC_PLL_USB_DIVISOR(x) ((x)<<28) - -#define UDP_INTERRUPT_ENDPOINT(x) (1<<(x)) -#define UDP_CSR_BYTES_RECEIVED(x) (((x) >> 16) & 0x7ff) +#define WDT_HIT() AT91C_BASE_WDTC->WDTC_WDCR = 0xa5000001 + +#define PWM_CH_MODE_PRESCALER(x) ((x)<<0) +#define PWM_CHANNEL(x) (1<<(x)) + +#define ADC_CHAN_LF 4 +#define ADC_CHAN_HF_LOW 5 +#define ADC_CHAN_HF_HIGH 7 +#define ADC_MODE_PRESCALE(x) ((x)<<8) +#define ADC_MODE_STARTUP_TIME(x) ((x)<<16) +#define ADC_MODE_SAMPLE_HOLD_TIME(x) ((x)<<24) +#define ADC_CHANNEL(x) (1<<(x)) +#define ADC_END_OF_CONVERSION(x) (1<<(x)) + +#define SSC_CLOCK_MODE_START(x) ((x)<<8) +#define SSC_FRAME_MODE_WORDS_PER_TRANSFER(x) ((x)<<8) +#define SSC_CLOCK_MODE_SELECT(x) ((x)<<0) +#define SSC_FRAME_MODE_BITS_IN_WORD(x) (((x)-1)<<0) + +#define MC_FLASH_COMMAND_KEY ((0x5a)<<24) +#define MC_FLASH_MODE_FLASH_WAIT_STATES(x) ((x)<<8) +#define MC_FLASH_MODE_MASTER_CLK_IN_MHZ(x) (((x)+((x)/2))<<16) +#define MC_FLASH_COMMAND_PAGEN(x) ((x)<<8) + +#define RST_CONTROL_KEY (0xa5<<24) + +#define PMC_MAIN_OSC_STARTUP_DELAY(x) ((x)<<8) +#define PMC_PLL_DIVISOR(x) (x) +#define PMC_PLL_MULTIPLIER(x) (((x)-1)<<16) +#define PMC_PLL_COUNT_BEFORE_LOCK(x) ((x)<<8) +#define PMC_PLL_FREQUENCY_RANGE(x) ((x)<<14) +#define PMC_PLL_USB_DIVISOR(x) ((x)<<28) + +#define UDP_INTERRUPT_ENDPOINT(x) (1<<(x)) +#define UDP_CSR_BYTES_RECEIVED(x) (((x) >> 16) & 0x7ff) //************************************************************** -#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x) -#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x) -#define GETBIT(x) (AT91C_BASE_PIOA->PIO_ODSR & (x)) ? 1:0 -#define SETBIT(x, y) (y) ? (HIGH(x)):(LOW(x)) -#define INVBIT(x) SETBIT((x), !(GETBIT(x))) +#define LOW(x) AT91C_BASE_PIOA->PIO_CODR = (x) +#define HIGH(x) AT91C_BASE_PIOA->PIO_SODR = (x) +#define GETBIT(x) (AT91C_BASE_PIOA->PIO_ODSR & (x)) ? 1:0 +#define SETBIT(x, y) (y) ? (HIGH(x)):(LOW(x)) +#define INVBIT(x) SETBIT((x), !(GETBIT(x))) -#define SPI_FPGA_MODE 0 -#define SPI_LCD_MODE 1 +#define SPI_FPGA_MODE 0 +#define SPI_LCD_MODE 1 //#define PACKED __attribute__((__packed__)) -#define LED_A_ON() HIGH(GPIO_LED_A) -#define LED_A_OFF() LOW(GPIO_LED_A) -#define LED_A_INV() INVBIT(GPIO_LED_A) -#define LED_B_ON() HIGH(GPIO_LED_B) -#define LED_B_OFF() LOW(GPIO_LED_B) -#define LED_B_INV() INVBIT(GPIO_LED_B) -#define LED_C_ON() HIGH(GPIO_LED_C) -#define LED_C_OFF() LOW(GPIO_LED_C) -#define LED_C_INV() INVBIT(GPIO_LED_C) -#define LED_D_ON() HIGH(GPIO_LED_D) -#define LED_D_OFF() LOW(GPIO_LED_D) -#define LED_D_INV() INVBIT(GPIO_LED_D) -#define RELAY_ON() HIGH(GPIO_RELAY) -#define RELAY_OFF() LOW(GPIO_RELAY) -#define BUTTON_PRESS() !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON) - -#define VERSION_INFORMATION_MAGIC 0x56334d50 +#define LED_A_ON() HIGH(GPIO_LED_A) +#define LED_A_OFF() LOW(GPIO_LED_A) +#define LED_A_INV() INVBIT(GPIO_LED_A) +#define LED_B_ON() HIGH(GPIO_LED_B) +#define LED_B_OFF() LOW(GPIO_LED_B) +#define LED_B_INV() INVBIT(GPIO_LED_B) +#define LED_C_ON() HIGH(GPIO_LED_C) +#define LED_C_OFF() LOW(GPIO_LED_C) +#define LED_C_INV() INVBIT(GPIO_LED_C) +#define LED_D_ON() HIGH(GPIO_LED_D) +#define LED_D_OFF() LOW(GPIO_LED_D) +#define LED_D_INV() INVBIT(GPIO_LED_D) +#define RELAY_ON() HIGH(GPIO_RELAY) +#define RELAY_OFF() LOW(GPIO_RELAY) +#define BUTTON_PRESS() !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON) + +#define VERSION_INFORMATION_MAGIC 0x56334d50 struct version_information { int magic; /* Magic sequence to identify this as a correct version information structure. Must be VERSION_INFORMATION_MAGIC */ char versionversion; /* Must be 1 */ @@ -89,9 +90,9 @@ struct version_information { char buildtime[30]; /* string with the build time */ } __attribute__((packed)); -#define COMMON_AREA_MAGIC 0x43334d50 -#define COMMON_AREA_COMMAND_NONE 0 -#define COMMON_AREA_COMMAND_ENTER_FLASH_MODE 1 +#define COMMON_AREA_MAGIC 0x43334d50 +#define COMMON_AREA_COMMAND_NONE 0 +#define COMMON_AREA_COMMAND_ENTER_FLASH_MODE 1 struct common_area { int magic; /* Magic sequence, to distinguish against random uninitialized memory */ char version; /* Must be 1 */ -- 2.39.5