232 lines
5.4 KiB
Arduino
232 lines
5.4 KiB
Arduino
|
|
||
|
#define RST 8
|
||
|
#define CLK 9
|
||
|
#define DATA 10
|
||
|
|
||
|
#define PSC1 0xff
|
||
|
#define PSC2 0xff
|
||
|
|
||
|
uint8_t card_data[] = {
|
||
|
|
||
|
0xff, 0xf7, 0x5c, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x47, 0x38,
|
||
|
0x78, 0x28, 0x07, 0x8c, 0xc1, 0x03, 0xfe, 0xff,
|
||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||
|
0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||
|
0x00, 0x00, 0x00, 0x00,
|
||
|
|
||
|
};
|
||
|
|
||
|
void setup()
|
||
|
{
|
||
|
digitalWrite(RST, LOW);
|
||
|
pinMode(RST, OUTPUT);
|
||
|
digitalWrite(CLK, LOW);
|
||
|
pinMode(CLK, OUTPUT);
|
||
|
pinMode(DATA, INPUT_PULLUP);
|
||
|
digitalWrite(DATA, HIGH);
|
||
|
|
||
|
Serial.begin(9600);
|
||
|
while (!Serial) {
|
||
|
; // wait for serial port to connect. Needed for Leonardo only
|
||
|
}
|
||
|
Serial.readStringUntil('\m');
|
||
|
}
|
||
|
|
||
|
void loop()
|
||
|
{
|
||
|
again:
|
||
|
Serial.println("Press 'a' for ATR, 'r' to read card, 'w' to program card, 'u' to unlock card");
|
||
|
Serial.println("-> You must read card ('r') before you are able to write to card.");
|
||
|
while (42) {
|
||
|
if (Serial.available() == 0)
|
||
|
continue;
|
||
|
char inChar = Serial.read();
|
||
|
if (inChar == 'a') {
|
||
|
Serial.println("ATR...");
|
||
|
card_atr(52);
|
||
|
goto again;
|
||
|
} else if (inChar == 'r') {
|
||
|
Serial.println("reading...");
|
||
|
card_read(52, 0);
|
||
|
goto again;
|
||
|
} else if (inChar == 'w') {
|
||
|
Serial.println("writing...");
|
||
|
card_write(card_data, sizeof(card_data), 0);
|
||
|
goto again;
|
||
|
} else if (inChar == 'u') {
|
||
|
Serial.println("unlocking...");
|
||
|
card_unlock(PSC1, PSC2);
|
||
|
goto again;
|
||
|
} else {
|
||
|
goto again;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void card_atr(int num)
|
||
|
{
|
||
|
uint8_t data[num];
|
||
|
|
||
|
digitalWrite(RST, HIGH);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(CLK, HIGH);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(CLK, LOW);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(RST, LOW);
|
||
|
delayMicroseconds(100);
|
||
|
card_read_bytes(data, num);
|
||
|
}
|
||
|
|
||
|
void card_read(int num, int address)
|
||
|
{
|
||
|
uint8_t data[num];
|
||
|
|
||
|
card_command(((address >> 2) & 0xc0) | 0x0e, address & 0xff, 0);
|
||
|
digitalWrite(CLK, HIGH);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(CLK, LOW);
|
||
|
delayMicroseconds(100);
|
||
|
card_read_bytes(data, num);
|
||
|
}
|
||
|
|
||
|
void card_write(uint8_t *data, int num, int address)
|
||
|
{
|
||
|
int i, cnt;
|
||
|
|
||
|
for (i = 0; i < num; i++) {
|
||
|
card_command(((address >> 2) & 0xc0) | 0x33, address & 0xff, *data);
|
||
|
cnt = card_erase_and_write();
|
||
|
if (cnt <= 2) {
|
||
|
Serial.println("write failed!");
|
||
|
// break;
|
||
|
}
|
||
|
address++;
|
||
|
data++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void card_unlock(uint8_t psc1, uint8_t psc2)
|
||
|
{
|
||
|
int i;
|
||
|
uint8_t data[3];
|
||
|
|
||
|
// read error counter
|
||
|
card_command(0xce, 253, 0);
|
||
|
digitalWrite(CLK, HIGH);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(CLK, LOW);
|
||
|
delayMicroseconds(100);
|
||
|
Serial.println("3 bytes: error counter mask, first PSC code, second psc code");
|
||
|
card_read_bytes(data, 3);
|
||
|
// check bit to erase
|
||
|
for (i = 0; i < 8; i++) {
|
||
|
if ((data[0] & (1 << i)))
|
||
|
break;
|
||
|
}
|
||
|
if (i == 8) {
|
||
|
Serial.println("SORRY NO MORE BITS TO ERASE TO UNLOCK, YOUR CARD IS BRICKED!");
|
||
|
return;
|
||
|
}
|
||
|
data[0] = data[0] - (1 << i);
|
||
|
// ease bit to unlock
|
||
|
card_command(0xf2, 253, data[0]);
|
||
|
card_erase_and_write();
|
||
|
// unlock
|
||
|
Serial.println("unlock bit has been erased, sending PSC code");
|
||
|
card_command(0xcd, 254, psc1);
|
||
|
card_erase_and_write();
|
||
|
card_command(0xcd, 255, psc2);
|
||
|
card_erase_and_write();
|
||
|
// read error counter mask
|
||
|
card_command(0xce, 253, 0);
|
||
|
digitalWrite(CLK, HIGH);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(CLK, LOW);
|
||
|
delayMicroseconds(100);
|
||
|
Serial.println("checking error counter mask, one bit shall be erased...");
|
||
|
card_read_bytes(data, 1);
|
||
|
// reset unlock mask
|
||
|
Serial.println("PSC code has been sent, resetting error counter mask");
|
||
|
card_command(0xf3, 253, 0xff);
|
||
|
card_erase_and_write();
|
||
|
// read error counter mask
|
||
|
card_command(0xce, 253, 0);
|
||
|
digitalWrite(CLK, HIGH);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(CLK, LOW);
|
||
|
delayMicroseconds(100);
|
||
|
Serial.println("reading: error counter mask, all bits should be reset");
|
||
|
card_read_bytes(data, 1);
|
||
|
}
|
||
|
|
||
|
void card_command(uint8_t c1, uint8_t c2, uint8_t c3)
|
||
|
{
|
||
|
int i, j;
|
||
|
uint8_t c[3];
|
||
|
|
||
|
c[0] = c1;
|
||
|
c[1] = c2;
|
||
|
c[2] = c3;
|
||
|
Serial.println("card command:");
|
||
|
Serial.println(c1);
|
||
|
Serial.println(c2);
|
||
|
Serial.println(c3);
|
||
|
|
||
|
digitalWrite(RST, HIGH);
|
||
|
delayMicroseconds(100);
|
||
|
pinMode(DATA, OUTPUT);
|
||
|
for (i = 0; i < 3; i++) {
|
||
|
for (j = 0; j < 8; j++) {
|
||
|
digitalWrite(DATA, ((c[i] >> j) & 1) ? HIGH : LOW);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(CLK, HIGH);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(CLK, LOW);
|
||
|
delayMicroseconds(100);
|
||
|
}
|
||
|
}
|
||
|
pinMode(DATA, INPUT_PULLUP);
|
||
|
digitalWrite(DATA, HIGH);
|
||
|
digitalWrite(RST, LOW);
|
||
|
delayMicroseconds(100);
|
||
|
}
|
||
|
|
||
|
void card_read_bytes(uint8_t *data, int num) {
|
||
|
int i, j;
|
||
|
|
||
|
for (i = 0; i < num; i++) {
|
||
|
for (j = 0; j < 8; j++) {
|
||
|
data[i] = (data[i] >> 1) | ((digitalRead(DATA) != LOW) ? 128 : 0);
|
||
|
Serial.print((digitalRead(DATA) != LOW) ? '1' : '0');
|
||
|
digitalWrite(CLK, HIGH);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(CLK, LOW);
|
||
|
delayMicroseconds(100);
|
||
|
}
|
||
|
Serial.print(" 0x");
|
||
|
Serial.println(data[i], HEX);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int card_erase_and_write(void)
|
||
|
{
|
||
|
int i;
|
||
|
|
||
|
for (i = 0; i < 203; i++) {
|
||
|
digitalWrite(CLK, HIGH);
|
||
|
delayMicroseconds(100);
|
||
|
digitalWrite(CLK, LOW);
|
||
|
delayMicroseconds(100);
|
||
|
if (0) if (digitalRead(DATA) == LOW) {
|
||
|
Serial.print(" -> write pulses:");
|
||
|
Serial.println(i);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
return i;
|
||
|
}
|
||
|
|