* 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
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
#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
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:
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
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;
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
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;
}
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;
/* 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 */
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;
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
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;
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;
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;
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;
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);
//-----------------------------------------------------------------------------
// The main i2c code, for communications with smart card module
//-----------------------------------------------------------------------------
+
#include "i2c.h"
-#include "mifareutil.h" //for mf_dbglevel
+
+#include <stdint.h>
+#include <stdbool.h>
#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
#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--) {};
}
#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);
}
// ÉèÖø´Î»×´Ì¬
// 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
// ¸´Î»½øÈëÖ÷³ÌÐò
// 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); // ½â³ý¸´Î»
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;
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;
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;
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;
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)
SDA_L;
data <<= 1;
+
I2C_DELAY_1CLK;
SCL_H;
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;
}
}
// 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())
// дÈë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())
// дÈë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())
// ¶Á³ö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())
return 0;
}
- // reading
while (len) {
- *data = I2C_ReadByte();
-
+ int16_t tmp = I2C_ReadByte();
+ if ( tmp < 0 )
+ return tmp;
+
+ *data = (uint8_t)tmp & 0xFF;
+
len--;
// ¶ÁÈ¡µÄµÚÒ»¸ö×Ö½ÚΪºóÐø³¤¶È
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;
// reading
while (len) {
- *data = I2C_ReadByte();
-
+
+ int16_t tmp = I2C_ReadByte();
+ if ( tmp < 0 )
+ return tmp;
+
+ *data = (uint8_t)tmp & 0xFF;
+
data++;
readcount++;
len--;
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;
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) {
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;
}
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:
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();
// 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;
set_tracing(false);
LEDsoff();
}
+
+#endif
\ No newline at end of file
#ifndef __I2C_H
#define __I2C_H
-#include <stddef.h>
-#include "proxmark3.h"
-#include "apps.h"
-#include "util.h"
-#include "BigBuf.h"
-#include "smartcard.h"
+#include <stdint.h>
+#include <stdbool.h>
#define I2C_DEVICE_ADDRESS_BOOT 0xB0
#define I2C_DEVICE_ADDRESS_MAIN 0xC0
#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
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;
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
// 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();
#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 */
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 */