]> cvs.zerfleddert.de Git - proxmark3-svn/blob - armsrc/i2c.c
Change mbedtls initializers to be compatible with older versions of gcc (#732)
[proxmark3-svn] / armsrc / i2c.c
1 //-----------------------------------------------------------------------------
2 // Willok, June 2018
3 // Edits by Iceman, July 2018
4 //
5 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
6 // at your option, any later version. See the LICENSE.txt file for the text of
7 // the license.
8 //-----------------------------------------------------------------------------
9 // The main i2c code, for communications with smart card module
10 //-----------------------------------------------------------------------------
11
12 #include "i2c.h"
13
14 #include <stdint.h>
15 #include <stdbool.h>
16 #include "string.h" //for memset memcmp
17 #include "proxmark3.h"
18 #include "mifareutil.h" // for MF_DBGLEVEL
19 #include "BigBuf.h"
20 #include "apps.h"
21
22 #ifdef WITH_SMARTCARD
23 #include "smartcard.h"
24 #endif
25
26
27 // ¶¨ÒåÁ¬½ÓÒý½Å
28 #define GPIO_RST AT91C_PIO_PA1
29 #define GPIO_SCL AT91C_PIO_PA5
30 #define GPIO_SDA AT91C_PIO_PA7
31
32 #define SCL_H HIGH(GPIO_SCL)
33 #define SCL_L LOW(GPIO_SCL)
34 #define SDA_H HIGH(GPIO_SDA)
35 #define SDA_L LOW(GPIO_SDA)
36
37 #define SCL_read (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SCL)
38 #define SDA_read (AT91C_BASE_PIOA->PIO_PDSR & GPIO_SDA)
39
40 #define I2C_ERROR "I2C_WaitAck Error"
41
42 static volatile unsigned long c;
43
44 // Ö±½ÓʹÓÃÑ­»·À´ÑÓʱ£¬Ò»¸öÑ­»· 6 ÌõÖ¸Á48M£¬ Delay=1 ´ó¸ÅΪ 200kbps
45 // timer.
46 // I2CSpinDelayClk(4) = 12.31us
47 // I2CSpinDelayClk(1) = 3.07us
48 static void __attribute__((optimize("O0"))) I2CSpinDelayClk(uint16_t delay) {
49 for (c = delay * 2; c; c--) {};
50 }
51
52 // ͨѶÑÓ³Ùº¯Êý communication delay function
53 #define I2C_DELAY_1CLK I2CSpinDelayClk(1)
54 #define I2C_DELAY_2CLK I2CSpinDelayClk(2)
55 #define I2C_DELAY_XCLK(x) I2CSpinDelayClk((x))
56
57
58 #define ISO7618_MAX_FRAME 255
59
60 static void I2C_init(void) {
61 // Configure reset pin
62 AT91C_BASE_PIOA->PIO_PPUDR = GPIO_RST; // disable pull up resistor
63 AT91C_BASE_PIOA->PIO_MDDR = GPIO_RST; // push-pull output (multidriver disabled)
64
65 // Configure SCL and SDA pins
66 AT91C_BASE_PIOA->PIO_PPUER |= (GPIO_SCL | GPIO_SDA); // enable pull up resistor
67 AT91C_BASE_PIOA->PIO_MDER |= (GPIO_SCL | GPIO_SDA); // open drain output (multidriver enabled) - requires external pull up resistor
68
69 // set all three outputs to high
70 AT91C_BASE_PIOA->PIO_SODR |= (GPIO_SCL | GPIO_SDA | GPIO_RST);
71
72 // configure all three pins as output, controlled by PIOA
73 AT91C_BASE_PIOA->PIO_OER |= (GPIO_SCL | GPIO_SDA | GPIO_RST);
74 AT91C_BASE_PIOA->PIO_PER |= (GPIO_SCL | GPIO_SDA | GPIO_RST);
75 }
76
77
78 // ÉèÖø´Î»×´Ì¬
79 // set the reset state
80 static void I2C_SetResetStatus(uint8_t LineRST, uint8_t LineSCK, uint8_t LineSDA) {
81 if (LineRST)
82 HIGH(GPIO_RST);
83 else
84 LOW(GPIO_RST);
85
86 if (LineSCK)
87 HIGH(GPIO_SCL);
88 else
89 LOW(GPIO_SCL);
90
91 if (LineSDA)
92 HIGH(GPIO_SDA);
93 else
94 LOW(GPIO_SDA);
95 }
96
97 // ¸´Î»½øÈëÖ÷³ÌÐò
98 // Reset the SIM_Adapter, then enter the main program
99 // Note: the SIM_Adapter will not enter the main program after power up. Please run this function before use SIM_Adapter.
100 static void I2C_Reset_EnterMainProgram(void) {
101 I2C_SetResetStatus(0, 0, 0); // À­µÍ¸´Î»Ïß
102 SpinDelay(30);
103 I2C_SetResetStatus(1, 0, 0); // ½â³ý¸´Î»
104 SpinDelay(30);
105 I2C_SetResetStatus(1, 1, 1); // À­¸ßÊý¾ÝÏß
106 SpinDelay(10);
107 }
108
109 // µÈ´ýʱÖÓ±ä¸ß
110 // Wait for the clock to go High.
111 static bool WaitSCL_H_delay(uint32_t delay) {
112 while (delay--) {
113 if (SCL_read) {
114 return true;
115 }
116 I2C_DELAY_1CLK;
117 }
118 return false;
119 }
120
121 // 15000 * 3.07us = 46050us. 46.05ms
122 static bool WaitSCL_H(void) {
123 return WaitSCL_H_delay(15000);
124 }
125
126 bool WaitSCL_L_delay(uint32_t delay) {
127 while (delay--) {
128 if (!SCL_read) {
129 return true;
130 }
131 I2C_DELAY_1CLK;
132 }
133 return false;
134 }
135
136 bool WaitSCL_L(void) {
137 return WaitSCL_L_delay(15000);
138 }
139
140 static bool I2C_Start(void) {
141
142 I2C_DELAY_XCLK(4);
143 SDA_H; I2C_DELAY_1CLK;
144 SCL_H;
145 if (!WaitSCL_H()) return false;
146
147 I2C_DELAY_2CLK;
148
149 if (!SCL_read) return false;
150 if (!SDA_read) return false;
151
152 SDA_L; I2C_DELAY_2CLK;
153 return true;
154 }
155
156 // send i2c STOP
157 static void I2C_Stop(void) {
158 SCL_L; I2C_DELAY_2CLK;
159 SDA_L; I2C_DELAY_2CLK;
160 SCL_H; I2C_DELAY_2CLK;
161 if (!WaitSCL_H()) return;
162 SDA_H;
163 I2C_DELAY_XCLK(8);
164 }
165
166 static bool I2C_WaitAck(void) {
167 SCL_L; I2C_DELAY_1CLK;
168 SDA_H; I2C_DELAY_1CLK;
169 SCL_H;
170 if (!WaitSCL_H())
171 return false;
172
173 I2C_DELAY_2CLK;
174 I2C_DELAY_2CLK;
175 if (SDA_read) {
176 SCL_L;
177 return false;
178 }
179 SCL_L;
180 return true;
181 }
182
183 static void I2C_SendByte(uint8_t data) {
184 uint8_t bits = 8;
185
186 while (bits--) {
187 SCL_L; I2C_DELAY_1CLK;
188
189 if (data & 0x80)
190 SDA_H;
191 else
192 SDA_L;
193
194 data <<= 1;
195
196 I2C_DELAY_1CLK;
197
198 SCL_H;
199 if (!WaitSCL_H())
200 return;
201
202 I2C_DELAY_2CLK;
203 }
204 SCL_L;
205 }
206
207 bool I2C_is_available(void) {
208 I2C_init();
209 I2C_Reset_EnterMainProgram();
210 if (!I2C_Start()) // some other device is active on the bus
211 return true;
212 I2C_SendByte(I2C_DEVICE_ADDRESS_MAIN & 0xFE);
213 if (!I2C_WaitAck()) { // no response from smartcard reader
214 I2C_Stop();
215 return false;
216 }
217 I2C_Stop();
218 return true;
219 }
220
221 #ifdef WITH_SMARTCARD
222 // ¸´Î»½øÈëÒýµ¼Ä£Ê½
223 // Reset the SIM_Adapter, then enter the bootloader program
224 // Reserve£ºFor firmware update.
225 static void I2C_Reset_EnterBootloader(void) {
226 I2C_SetResetStatus(0, 1, 1); // À­µÍ¸´Î»Ïß
227 SpinDelay(100);
228 I2C_SetResetStatus(1, 1, 1); // ½â³ý¸´Î»
229 SpinDelay(10);
230 }
231
232 // Wait max 300ms or until SCL goes LOW.
233 // Which ever comes first
234 static bool WaitSCL_L_300ms(void) {
235 volatile uint16_t delay = 310;
236 while ( delay-- ) {
237 // exit on SCL LOW
238 if (!SCL_read)
239 return true;
240
241 SpinDelay(1);
242 }
243 return (delay == 0);
244 }
245
246 static bool I2C_WaitForSim() {
247 // variable delay here.
248 if (!WaitSCL_L_300ms())
249 return false;
250
251 // 8051 speaks with smart card.
252 // 1000*50*3.07 = 153.5ms
253 // 1byte transfer == 1ms with max frame being 256bytes
254 if (!WaitSCL_H_delay(10 * 1000 * 50))
255 return false;
256
257 return true;
258 }
259
260 // Send i2c ACK
261 static void I2C_Ack(void) {
262 SCL_L; I2C_DELAY_2CLK;
263 SDA_L; I2C_DELAY_2CLK;
264 SCL_H; I2C_DELAY_2CLK;
265 if (!WaitSCL_H()) return;
266 SCL_L; I2C_DELAY_2CLK;
267 }
268
269 // Send i2c NACK
270 static void I2C_NoAck(void) {
271 SCL_L; I2C_DELAY_2CLK;
272 SDA_H; I2C_DELAY_2CLK;
273 SCL_H; I2C_DELAY_2CLK;
274 if (!WaitSCL_H()) return;
275 SCL_L; I2C_DELAY_2CLK;
276 }
277
278 static int16_t I2C_ReadByte(void) {
279 uint8_t bits = 8, b = 0;
280
281 SDA_H;
282 while (bits--) {
283 b <<= 1;
284 SCL_L;
285 if (!WaitSCL_L()) return -2;
286
287 I2C_DELAY_1CLK;
288
289 SCL_H;
290 if (!WaitSCL_H()) return -1;
291
292 I2C_DELAY_1CLK;
293 if (SDA_read)
294 b |= 0x01;
295 }
296 SCL_L;
297 return b;
298 }
299
300 // Sends one byte ( command to be written, SlaveDevice address)
301 static bool I2C_WriteCmd(uint8_t device_cmd, uint8_t device_address) {
302 bool bBreak = true;
303 do {
304 if (!I2C_Start())
305 return false;
306 //[C0]
307 I2C_SendByte(device_address & 0xFE);
308 if (!I2C_WaitAck())
309 break;
310
311 I2C_SendByte(device_cmd);
312 if (!I2C_WaitAck())
313 break;
314
315 bBreak = false;
316 } while (false);
317
318 I2C_Stop();
319 if (bBreak) {
320 if ( MF_DBGLEVEL > 3 ) DbpString(I2C_ERROR);
321 return false;
322 }
323 return true;
324 }
325
326 // дÈë1×Ö½ÚÊý¾Ý £¨´ýдÈëÊý¾Ý£¬´ýдÈëµØÖ·£¬Æ÷¼þÀàÐÍ£©
327 // Sends 1 byte data (Data to be written, command to be written , SlaveDevice address ).
328 static bool I2C_WriteByte(uint8_t data, uint8_t device_cmd, uint8_t device_address) {
329 bool bBreak = true;
330 do {
331 if (!I2C_Start())
332 return false;
333
334 I2C_SendByte(device_address & 0xFE);
335 if (!I2C_WaitAck())
336 break;
337
338 I2C_SendByte(device_cmd);
339 if (!I2C_WaitAck())
340 break;
341
342 I2C_SendByte(data);
343 if (!I2C_WaitAck())
344 break;
345
346 bBreak = false;
347 } while (false);
348
349 I2C_Stop();
350 if (bBreak) {
351 if ( MF_DBGLEVEL > 3 ) DbpString(I2C_ERROR);
352 return false;
353 }
354 return true;
355 }
356
357 // дÈë1´®Êý¾Ý£¨´ýдÈëÊý×éµØÖ·£¬´ýдÈ볤¶È£¬´ýдÈëµØÖ·£¬Æ÷¼þÀàÐÍ£©
358 //Sends a string of data (Array, length, command to be written , SlaveDevice address ).
359 // len = uint8 (max buffer to write 256bytes)
360 static bool I2C_BufferWrite(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) {
361 bool bBreak = true;
362 do {
363 if (!I2C_Start())
364 return false;
365
366 I2C_SendByte(device_address & 0xFE);
367 if (!I2C_WaitAck())
368 break;
369
370 I2C_SendByte(device_cmd);
371 if (!I2C_WaitAck())
372 break;
373
374 while (len) {
375
376 I2C_SendByte(*data);
377 if (!I2C_WaitAck())
378 break;
379
380 len--;
381 data++;
382 }
383
384 if (len == 0)
385 bBreak = false;
386 } while (false);
387
388 I2C_Stop();
389 if (bBreak) {
390 if ( MF_DBGLEVEL > 3 ) DbpString(I2C_ERROR);
391 return false;
392 }
393 return true;
394 }
395
396 // ¶Á³ö1´®Êý¾Ý£¨´æ·Å¶Á³öÊý¾Ý£¬´ý¶Á³ö³¤¶È£¬´ø¶Á³öµØÖ·£¬Æ÷¼þÀàÐÍ£©
397 // read 1 strings of data (Data array, Readout length, command to be written , SlaveDevice address ).
398 // len = uint8 (max buffer to read 256bytes)
399 static int16_t I2C_BufferRead(uint8_t *data, uint8_t len, uint8_t device_cmd, uint8_t device_address) {
400
401 if ( !data || len == 0 )
402 return 0;
403
404 // extra wait 500us (514us measured)
405 // 200us (xx measured)
406 SpinDelayUs(600);
407 bool bBreak = true;
408 uint16_t readcount = 0;
409
410 do {
411 if (!I2C_Start())
412 return 0;
413
414 // 0xB0 / 0xC0 == i2c write
415 I2C_SendByte(device_address & 0xFE);
416 if (!I2C_WaitAck())
417 break;
418
419 I2C_SendByte(device_cmd);
420 if (!I2C_WaitAck())
421 break;
422
423 // 0xB1 / 0xC1 == i2c read
424 I2C_Start();
425 I2C_SendByte(device_address | 1);
426 if (!I2C_WaitAck())
427 break;
428
429 bBreak = false;
430 } while (false);
431
432 if (bBreak) {
433 I2C_Stop();
434 if ( MF_DBGLEVEL > 3 ) DbpString(I2C_ERROR);
435 return 0;
436 }
437
438 while (len) {
439
440 int16_t tmp = I2C_ReadByte();
441 if ( tmp < 0 )
442 return tmp;
443
444 *data = (uint8_t)tmp & 0xFF;
445
446 len--;
447
448 // ¶ÁÈ¡µÄµÚÒ»¸ö×Ö½ÚΪºóÐø³¤¶È
449 // The first byte in response is the message length
450 if (!readcount && (len > *data)) {
451 len = *data;
452 } else {
453 data++;
454 }
455 readcount++;
456
457 // acknowledgements. After last byte send NACK.
458 if (len == 0)
459 I2C_NoAck();
460 else
461 I2C_Ack();
462 }
463
464 I2C_Stop();
465 // return bytecount - first byte (which is length byte)
466 return --readcount;
467 }
468
469 static int16_t I2C_ReadFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) {
470 //START, 0xB0, 0x00, 0x00, START, 0xB1, xx, yy, zz, ......, STOP
471 bool bBreak = true;
472 uint8_t readcount = 0;
473
474 // sending
475 do {
476 if (!I2C_Start())
477 return 0;
478
479 // 0xB0 / 0xC0 i2c write
480 I2C_SendByte(device_address & 0xFE);
481 if (!I2C_WaitAck())
482 break;
483
484 // msb
485 I2C_SendByte(msb);
486 if (!I2C_WaitAck())
487 break;
488
489 // lsb
490 I2C_SendByte(lsb);
491 if (!I2C_WaitAck())
492 break;
493
494 // 0xB1 / 0xC1 i2c read
495 I2C_Start();
496 I2C_SendByte(device_address | 1);
497 if (!I2C_WaitAck())
498 break;
499
500 bBreak = false;
501 } while (false);
502
503 if (bBreak) {
504 I2C_Stop();
505 if ( MF_DBGLEVEL > 3 ) DbpString(I2C_ERROR);
506 return 0;
507 }
508
509 // reading
510 while (len) {
511
512 int16_t tmp = I2C_ReadByte();
513 if ( tmp < 0 )
514 return tmp;
515
516 *data = (uint8_t)tmp & 0xFF;
517
518 data++;
519 readcount++;
520 len--;
521
522 // acknowledgements. After last byte send NACK.
523 if (len == 0)
524 I2C_NoAck();
525 else
526 I2C_Ack();
527 }
528
529 I2C_Stop();
530 return readcount;
531 }
532
533 static bool I2C_WriteFW(uint8_t *data, uint8_t len, uint8_t msb, uint8_t lsb, uint8_t device_address) {
534 //START, 0xB0, 0x00, 0x00, xx, yy, zz, ......, STOP
535 bool bBreak = true;
536
537 do {
538 if (!I2C_Start())
539 return false;
540
541 // 0xB0 == i2c write
542 I2C_SendByte(device_address & 0xFE);
543 if (!I2C_WaitAck())
544 break;
545
546 // msb
547 I2C_SendByte(msb);
548 if (!I2C_WaitAck())
549 break;
550
551 // lsb
552 I2C_SendByte(lsb);
553 if (!I2C_WaitAck())
554 break;
555
556 while (len) {
557 I2C_SendByte(*data);
558 if (!I2C_WaitAck())
559 break;
560
561 len--;
562 data++;
563 }
564
565 if (len == 0)
566 bBreak = false;
567 } while (false);
568
569 I2C_Stop();
570 if (bBreak) {
571 if ( MF_DBGLEVEL > 3 ) DbpString(I2C_ERROR);
572 return false;
573 }
574 return true;
575 }
576
577 void I2C_print_status(void) {
578 DbpString("Smart card module (ISO 7816)");
579 uint8_t resp[] = {0,0,0,0};
580 I2C_init();
581 I2C_Reset_EnterMainProgram();
582 uint8_t len = I2C_BufferRead(resp, sizeof(resp), I2C_DEVICE_CMD_GETVERSION, I2C_DEVICE_ADDRESS_MAIN);
583 if ( len > 0 )
584 Dbprintf(" version.................v%x.%02x", resp[0], resp[1]);
585 else
586 DbpString(" version.................FAILED");
587 }
588
589 // Will read response from smart card module, retries 3 times to get the data.
590 static bool sc_rx_bytes(uint8_t* dest, uint8_t *destlen) {
591 uint8_t i = 3;
592 int16_t len = 0;
593 while (i--) {
594
595 I2C_WaitForSim();
596
597 len = I2C_BufferRead(dest, *destlen, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN);
598
599 if ( len > 1 ){
600 break;
601 } else if ( len == 1 ) {
602 continue;
603 } else if ( len <= 0 ) {
604 return false;
605 }
606 }
607 // after three
608 if ( len <= 1 )
609 return false;
610
611 *destlen = (uint8_t)len & 0xFF;
612 return true;
613 }
614
615 static bool GetATR(smart_card_atr_t *card_ptr) {
616
617 if ( !card_ptr ) {
618 return false;
619 }
620
621 card_ptr->atr_len = 0;
622 memset(card_ptr->atr, 0, sizeof(card_ptr->atr));
623
624 // Send ATR
625 // start [C0 01] stop start C1 len aa bb cc stop]
626 I2C_WriteCmd(I2C_DEVICE_CMD_GENERATE_ATR, I2C_DEVICE_ADDRESS_MAIN);
627 uint8_t cmd[1] = {1};
628 LogTrace(cmd, 1, 0, 0, NULL, true);
629
630 // wait for sim card to answer.
631 // 1byte = 1ms, max frame 256bytes. Should wait 256ms at least just in case.
632 if (!I2C_WaitForSim())
633 return false;
634
635 // read bytes from module
636 uint8_t len = sizeof(card_ptr->atr);
637 if ( !sc_rx_bytes(card_ptr->atr, &len) )
638 return false;
639
640 uint8_t pos_td = 1;
641 if ( (card_ptr->atr[1] & 0x10) == 0x10) pos_td++;
642 if ( (card_ptr->atr[1] & 0x20) == 0x20) pos_td++;
643 if ( (card_ptr->atr[1] & 0x40) == 0x40) pos_td++;
644
645 // T0 indicate presence T=0 vs T=1. T=1 has checksum TCK
646 if ( (card_ptr->atr[1] & 0x80) == 0x80) {
647
648 pos_td++;
649
650 // 1 == T1 , presence of checksum TCK
651 if ( (card_ptr->atr[pos_td] & 0x01) == 0x01) {
652 uint8_t chksum = 0;
653 // xor property. will be zero when xored with chksum.
654 for (uint8_t i = 1; i < len; ++i)
655 chksum ^= card_ptr->atr[i];
656 if ( chksum ) {
657 if ( MF_DBGLEVEL > 2) DbpString("Wrong ATR checksum");
658 }
659 }
660 }
661
662 // for some reason we only get first byte of atr, if that is so, send dummy command to retrieve the rest of the atr
663 if (len == 1) {
664
665 uint8_t data[1] = {0};
666 I2C_BufferWrite(data, len, I2C_DEVICE_CMD_SEND, I2C_DEVICE_ADDRESS_MAIN);
667
668 if ( !I2C_WaitForSim() )
669 return false;
670
671 uint8_t len2 = I2C_BufferRead(card_ptr->atr + len, sizeof(card_ptr->atr) - len, I2C_DEVICE_CMD_READ, I2C_DEVICE_ADDRESS_MAIN);
672 len = len + len2;
673 }
674
675 card_ptr->atr_len = len;
676 LogTrace(card_ptr->atr, card_ptr->atr_len, 0, 0, NULL, false);
677
678 return true;
679 }
680
681 void SmartCardAtr(void) {
682 smart_card_atr_t card;
683 LED_D_ON();
684 clear_trace();
685 set_tracing(true);
686 I2C_init();
687 I2C_Reset_EnterMainProgram();
688 bool isOK = GetATR( &card );
689 cmd_send(CMD_ACK, isOK, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t));
690 set_tracing(false);
691 LEDsoff();
692 }
693
694 void SmartCardRaw( uint64_t arg0, uint64_t arg1, uint8_t *data ) {
695
696 LED_D_ON();
697
698 uint8_t len = 0;
699 uint8_t *resp = BigBuf_malloc(ISO7618_MAX_FRAME);
700 smartcard_command_t flags = arg0;
701
702 if ((flags & SC_CONNECT))
703 clear_trace();
704
705 set_tracing(true);
706
707 if ((flags & SC_CONNECT)) {
708
709 I2C_init();
710 I2C_Reset_EnterMainProgram();
711
712 if ( !(flags & SC_NO_SELECT) ) {
713 smart_card_atr_t card;
714 bool gotATR = GetATR( &card );
715 //cmd_send(CMD_ACK, gotATR, sizeof(smart_card_atr_t), 0, &card, sizeof(smart_card_atr_t));
716 if ( !gotATR )
717 goto OUT;
718 }
719 }
720
721 if ((flags & SC_RAW)) {
722
723 LogTrace(data, arg1, 0, 0, NULL, true);
724
725 // Send raw bytes
726 // asBytes = A0 A4 00 00 02
727 // arg1 = len 5
728 I2C_BufferWrite(data, arg1, I2C_DEVICE_CMD_SEND, I2C_DEVICE_ADDRESS_MAIN);
729
730 if ( !I2C_WaitForSim() )
731 goto OUT;
732
733 // read bytes from module
734 len = ISO7618_MAX_FRAME;
735 sc_rx_bytes(resp, &len);
736 LogTrace(resp, len, 0, 0, NULL, false);
737 }
738 OUT:
739 cmd_send(CMD_ACK, len, 0, 0, resp, len);
740 set_tracing(false);
741 LEDsoff();
742 }
743
744 void SmartCardUpgrade(uint64_t arg0) {
745
746 LED_C_ON();
747
748 #define I2C_BLOCK_SIZE 128
749 // write. Sector0, with 11,22,33,44
750 // erase is 128bytes, and takes 50ms to execute
751
752 I2C_init();
753 I2C_Reset_EnterBootloader();
754
755 bool isOK = true;
756 int16_t res = 0;
757 uint16_t length = arg0;
758 uint16_t pos = 0;
759 uint8_t *fwdata = BigBuf_get_addr();
760 uint8_t *verfiydata = BigBuf_malloc(I2C_BLOCK_SIZE);
761
762 while (length) {
763
764 uint8_t msb = (pos >> 8) & 0xFF;
765 uint8_t lsb = pos & 0xFF;
766
767 Dbprintf("FW %02X%02X", msb, lsb);
768
769 size_t size = MIN(I2C_BLOCK_SIZE, length);
770
771 // write
772 res = I2C_WriteFW(fwdata+pos, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT);
773 if ( !res ) {
774 DbpString("Writing failed");
775 isOK = false;
776 break;
777 }
778
779 // writing takes time.
780 SpinDelay(50);
781
782 // read
783 res = I2C_ReadFW(verfiydata, size, msb, lsb, I2C_DEVICE_ADDRESS_BOOT);
784 if ( res <= 0) {
785 DbpString("Reading back failed");
786 isOK = false;
787 break;
788 }
789
790 // cmp
791 if ( 0 != memcmp(fwdata+pos, verfiydata, size)) {
792 DbpString("not equal data");
793 isOK = false;
794 break;
795 }
796
797 length -= size;
798 pos += size;
799 }
800 cmd_send(CMD_ACK, isOK, pos, 0, 0, 0);
801 LED_C_OFF();
802 }
803
804 // unfinished (or not needed?)
805 //void SmartCardSetBaud(uint64_t arg0) {
806 //}
807
808 void SmartCardSetClock(uint64_t arg0) {
809 LED_D_ON();
810 set_tracing(true);
811 I2C_init();
812 I2C_Reset_EnterMainProgram();
813
814 // Send SIM CLC
815 // start [C0 05 xx] stop
816 I2C_WriteByte(arg0, I2C_DEVICE_CMD_SIM_CLC, I2C_DEVICE_ADDRESS_MAIN);
817
818 cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
819 set_tracing(false);
820 LEDsoff();
821 }
822
823 #endif
Impressum, Datenschutz