#include #include #include #include #define STATUS_LED 13 #define READER_VCC #define READER_RST 4 #define READER_CLK 3 #define READER_GND #define READER_VPP #define READER_IO 2 #define CARD_VCC 11 #define CARD_RST 7 #define CARD_CLK 9 #define CARD_GND #define CARD_VPP #define CARD_IO 10 #define CARD_PRE 12 SmartCardReader cardReader(CARD_IO, CARD_RST, CARD_VCC, CARD_PRE, CARD_CLK, false); uint8_t readerAtr[MAX_ATR_BYTES]; int readerAtrSize = 0; bool readerReset = false; int baudRate = -1; int etu = -1; #ifndef digitalPinToInterrupt int digitalPinToInterrupt(int pin) { if (pin == 2) { return INT0; } else if (pin == 3) { return INT1; } return -1; } #endif void emulatorComputeEtu() { baudRate = 9600; etu = 1000000 / baudRate; } void emulatorSendAtrByte(char byte) { unsigned long nextBitTime = micros() + (2 * etu); digitalWrite(READER_IO, HIGH); int bitNumber = 0; int parity = 0; while (bitNumber < 11) { if (nextBitTime <= micros()) { if (bitNumber == 0) { digitalWrite(READER_IO, LOW); } else if (bitNumber < 9) { int a = bitRead(byte, bitNumber - 1); parity += a; digitalWrite(READER_IO, a); } else if (bitNumber == 9) { digitalWrite(READER_IO, parity % 2); } else if (bitNumber == 10) { digitalWrite(READER_IO, HIGH); break; } nextBitTime += etu; ++bitNumber; } } } void emulatorSendAtr(const uint8_t* atr, size_t size) { pinMode(READER_IO, OUTPUT); for (int i = 0; i < size; ++i) { emulatorSendAtrByte(atr[i]); delayMicroseconds(4*etu); } } void readerResetAtr() { for (size_t i = 0; i < sizeof(readerAtr); ++i) { readerAtr[i] = 0; } readerAtrSize = 0; } void setup() { Serial.begin(9600); Serial.println("Initializing..."); pinMode(READER_CLK, INPUT); pinMode(READER_RST, INPUT); pinMode(READER_IO, OUTPUT); digitalWrite(READER_IO, HIGH); pinMode(STATUS_LED, OUTPUT); digitalWrite(STATUS_LED, LOW); Serial.println("Initialized"); readerResetAtr(); } void loop() { if (readerAtrSize == 0) { if (cardReader.cardInserted()) { readerAtrSize = cardReader.activate(readerAtr, sizeof(readerAtr)); cardReader.dumpHEX(readerAtr, readerAtrSize); cardReader.deactivate(); digitalWrite(STATUS_LED, HIGH); } } else { if (!cardReader.cardInserted()) { readerResetAtr(); digitalWrite(STATUS_LED, LOW); } else if (digitalRead(READER_RST)) { if (!readerReset) { emulatorComputeEtu(); emulatorSendAtr(readerAtr, readerAtrSize); readerReset = true; } } else { if (readerReset) { readerReset = false; } } } }