]> git.zerfleddert.de Git - proxmark3-svn/blob - armsrc/appmain.c
7aa353b2404a7401f57d1b216ee9f256e760ee34
[proxmark3-svn] / armsrc / appmain.c
1 //-----------------------------------------------------------------------------
2 // Jonathan Westhues, Mar 2006
3 // Edits by Gerhard de Koning Gans, Sep 2007 (##)
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 application code. This is the first thing called after start.c
10 // executes.
11 //-----------------------------------------------------------------------------
12
13 #include "usb_cdc.h"
14 #include "cmd.h"
15
16 #include "proxmark3.h"
17 #include "apps.h"
18 #include "util.h"
19 #include "printf.h"
20 #include "string.h"
21
22 #include <stdarg.h>
23
24 #include "legicrf.h"
25 #include <hitag2.h>
26 #include "lfsampling.h"
27 #include "BigBuf.h"
28 #ifdef WITH_LCD
29 #include "LCD.h"
30 #endif
31
32 // Craig Young - 14a stand-alone code
33 #ifdef WITH_ISO14443a_StandAlone
34 #include "iso14443a.h"
35 #endif
36
37 #define abs(x) ( ((x)<0) ? -(x) : (x) )
38
39 //=============================================================================
40 // A buffer where we can queue things up to be sent through the FPGA, for
41 // any purpose (fake tag, as reader, whatever). We go MSB first, since that
42 // is the order in which they go out on the wire.
43 //=============================================================================
44
45 #define TOSEND_BUFFER_SIZE (9*MAX_FRAME_SIZE + 1 + 1 + 2) // 8 data bits and 1 parity bit per payload byte, 1 correction bit, 1 SOC bit, 2 EOC bits
46 uint8_t ToSend[TOSEND_BUFFER_SIZE];
47 int ToSendMax;
48 static int ToSendBit;
49 struct common_area common_area __attribute__((section(".commonarea")));
50
51 void ToSendReset(void)
52 {
53 ToSendMax = -1;
54 ToSendBit = 8;
55 }
56
57 void ToSendStuffBit(int b)
58 {
59 if(ToSendBit >= 8) {
60 ToSendMax++;
61 ToSend[ToSendMax] = 0;
62 ToSendBit = 0;
63 }
64
65 if(b) {
66 ToSend[ToSendMax] |= (1 << (7 - ToSendBit));
67 }
68
69 ToSendBit++;
70
71 if(ToSendMax >= sizeof(ToSend)) {
72 ToSendBit = 0;
73 DbpString("ToSendStuffBit overflowed!");
74 }
75 }
76
77 //=============================================================================
78 // Debug print functions, to go out over USB, to the usual PC-side client.
79 //=============================================================================
80
81 void DbpString(char *str)
82 {
83 byte_t len = strlen(str);
84 cmd_send(CMD_DEBUG_PRINT_STRING,len,0,0,(byte_t*)str,len);
85 }
86
87 #if 0
88 void DbpIntegers(int x1, int x2, int x3)
89 {
90 cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0);
91 }
92 #endif
93
94 void Dbprintf(const char *fmt, ...) {
95 // should probably limit size here; oh well, let's just use a big buffer
96 char output_string[128];
97 va_list ap;
98
99 va_start(ap, fmt);
100 kvsprintf(fmt, output_string, 10, ap);
101 va_end(ap);
102
103 DbpString(output_string);
104 }
105
106 // prints HEX & ASCII
107 void Dbhexdump(int len, uint8_t *d, bool bAsci) {
108 int l=0,i;
109 char ascii[9];
110
111 while (len>0) {
112 if (len>8) l=8;
113 else l=len;
114
115 memcpy(ascii,d,l);
116 ascii[l]=0;
117
118 // filter safe ascii
119 for (i=0;i<l;i++)
120 if (ascii[i]<32 || ascii[i]>126) ascii[i]='.';
121
122 if (bAsci) {
123 Dbprintf("%-8s %*D",ascii,l,d," ");
124 } else {
125 Dbprintf("%*D",l,d," ");
126 }
127
128 len-=8;
129 d+=8;
130 }
131 }
132
133 //-----------------------------------------------------------------------------
134 // Read an ADC channel and block till it completes, then return the result
135 // in ADC units (0 to 1023). Also a routine to average 32 samples and
136 // return that.
137 //-----------------------------------------------------------------------------
138 static int ReadAdc(int ch)
139 {
140 uint32_t d;
141
142 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
143 AT91C_BASE_ADC->ADC_MR =
144 ADC_MODE_PRESCALE(63 /* was 32 */) | // ADC_CLK = MCK / ((63+1) * 2) = 48MHz / 128 = 375kHz
145 ADC_MODE_STARTUP_TIME(1 /* was 16 */) | // Startup Time = (1+1) * 8 / ADC_CLK = 16 / 375kHz = 42,7us Note: must be > 20us
146 ADC_MODE_SAMPLE_HOLD_TIME(15 /* was 8 */); // Sample & Hold Time SHTIM = 15 / ADC_CLK = 15 / 375kHz = 40us
147
148 // Note: ADC_MODE_PRESCALE and ADC_MODE_SAMPLE_HOLD_TIME are set to the maximum allowed value.
149 // Both AMPL_LO and AMPL_HI are very high impedance (10MOhm) outputs, the input capacitance of the ADC is 12pF (typical). This results in a time constant
150 // of RC = 10MOhm * 12pF = 120us. Even after the maximum configurable sample&hold time of 40us the input capacitor will not be fully charged.
151 //
152 // The maths are:
153 // If there is a voltage v_in at the input, the voltage v_cap at the capacitor (this is what we are measuring) will be
154 //
155 // v_cap = v_in * (1 - exp(-RC/SHTIM)) = v_in * (1 - exp(-3)) = v_in * 0,95 (i.e. an error of 5%)
156 //
157 // Note: with the "historic" values in the comments above, the error was 34% !!!
158
159 AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch);
160
161 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
162
163 while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch)))
164 ;
165 d = AT91C_BASE_ADC->ADC_CDR[ch];
166
167 return d;
168 }
169
170 int AvgAdc(int ch) // was static - merlok
171 {
172 int i;
173 int a = 0;
174
175 for(i = 0; i < 32; i++) {
176 a += ReadAdc(ch);
177 }
178
179 return (a + 15) >> 5;
180 }
181
182 void MeasureAntennaTuning(void)
183 {
184 uint8_t LF_Results[256];
185 int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0
186 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
187
188 LED_B_ON();
189
190 /*
191 * Sweeps the useful LF range of the proxmark from
192 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
193 * read the voltage in the antenna, the result left
194 * in the buffer is a graph which should clearly show
195 * the resonating frequency of your LF antenna
196 * ( hopefully around 95 if it is tuned to 125kHz!)
197 */
198
199 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
200 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
201 for (i=255; i>=19; i--) {
202 WDT_HIT();
203 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
204 SpinDelay(20);
205 adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
206 if (i==95) vLf125 = adcval; // voltage at 125Khz
207 if (i==89) vLf134 = adcval; // voltage at 134Khz
208
209 LF_Results[i] = adcval>>8; // scale int to fit in byte for graphing purposes
210 if(LF_Results[i] > peak) {
211 peakv = adcval;
212 peak = LF_Results[i];
213 peakf = i;
214 //ptr = i;
215 }
216 }
217
218 for (i=18; i >= 0; i--) LF_Results[i] = 0;
219
220 LED_A_ON();
221 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
222 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
223 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
224 SpinDelay(20);
225 vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
226
227 cmd_send(CMD_MEASURED_ANTENNA_TUNING, vLf125 | (vLf134<<16), vHf, peakf | (peakv<<16), LF_Results, 256);
228 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
229 LED_A_OFF();
230 LED_B_OFF();
231 return;
232 }
233
234 void MeasureAntennaTuningHf(void)
235 {
236 int vHf = 0; // in mV
237
238 DbpString("Measuring HF antenna, press button to exit");
239
240 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
241 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
242 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
243
244 for (;;) {
245 SpinDelay(20);
246 vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
247
248 Dbprintf("%d mV",vHf);
249 if (BUTTON_PRESS()) break;
250 }
251 DbpString("cancelled");
252
253 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
254
255 }
256
257
258 void ReadMem(int addr)
259 {
260 const uint8_t *data = ((uint8_t *)addr);
261
262 Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x",
263 addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
264 }
265
266 /* osimage version information is linked in */
267 extern struct version_information version_information;
268 /* bootrom version information is pointed to from _bootphase1_version_pointer */
269 extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__;
270 void SendVersion(void)
271 {
272 char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
273 char VersionString[USB_CMD_DATA_SIZE] = { '\0' };
274
275 /* Try to find the bootrom version information. Expect to find a pointer at
276 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
277 * pointer, then use it.
278 */
279 char *bootrom_version = *(char**)&_bootphase1_version_pointer;
280 if( bootrom_version < &_flash_start || bootrom_version >= &_flash_end ) {
281 strcat(VersionString, "bootrom version information appears invalid\n");
282 } else {
283 FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);
284 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
285 }
286
287 FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
288 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
289
290 FpgaGatherVersion(FPGA_BITSTREAM_LF, temp, sizeof(temp));
291 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
292 FpgaGatherVersion(FPGA_BITSTREAM_HF, temp, sizeof(temp));
293 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
294
295 // Send Chip ID and used flash memory
296 uint32_t text_and_rodata_section_size = (uint32_t)&__data_src_start__ - (uint32_t)&_flash_start;
297 uint32_t compressed_data_section_size = common_area.arg1;
298 cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString));
299 }
300
301 #if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF)
302
303 #define OPTS 2
304
305 void StandAloneMode()
306 {
307 DbpString("Stand-alone mode! No PC necessary.");
308 // Oooh pretty -- notify user we're in elite samy mode now
309 LED(LED_RED, 200);
310 LED(LED_ORANGE, 200);
311 LED(LED_GREEN, 200);
312 LED(LED_ORANGE, 200);
313 LED(LED_RED, 200);
314 LED(LED_ORANGE, 200);
315 LED(LED_GREEN, 200);
316 LED(LED_ORANGE, 200);
317 LED(LED_RED, 200);
318
319 }
320
321 #endif
322
323
324
325 #ifdef WITH_ISO14443a_StandAlone
326 void StandAloneMode14a()
327 {
328 StandAloneMode();
329 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
330
331 int selected = 0;
332 int playing = 0;
333 int cardRead[OPTS] = {0};
334 uint8_t readUID[10] = {0};
335 uint32_t uid_1st[OPTS]={0};
336 uint32_t uid_2nd[OPTS]={0};
337
338 LED(selected + 1, 0);
339
340 for (;;)
341 {
342 usb_poll();
343 WDT_HIT();
344
345 // Was our button held down or pressed?
346 int button_pressed = BUTTON_HELD(1000);
347 SpinDelay(300);
348
349 // Button was held for a second, begin recording
350 if (button_pressed > 0 && cardRead[selected] == 0)
351 {
352 LEDsoff();
353 LED(selected + 1, 0);
354 LED(LED_RED2, 0);
355
356 // record
357 Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected);
358
359 // wait for button to be released
360 while(BUTTON_PRESS())
361 WDT_HIT();
362 /* need this delay to prevent catching some weird data */
363 SpinDelay(500);
364 /* Code for reading from 14a tag */
365 uint8_t uid[10] ={0};
366 uint32_t cuid;
367 iso14443a_setup(FPGA_HF_ISO14443A_READER_MOD);
368
369 for ( ; ; )
370 {
371 WDT_HIT();
372 if (!iso14443a_select_card(uid, NULL, &cuid))
373 continue;
374 else
375 {
376 Dbprintf("Read UID:"); Dbhexdump(10,uid,0);
377 memcpy(readUID,uid,10*sizeof(uint8_t));
378 uint8_t *dst = (uint8_t *)&uid_1st[selected];
379 // Set UID byte order
380 for (int i=0; i<4; i++)
381 dst[i] = uid[3-i];
382 dst = (uint8_t *)&uid_2nd[selected];
383 for (int i=0; i<4; i++)
384 dst[i] = uid[7-i];
385 break;
386 }
387 }
388 LEDsoff();
389 LED(LED_GREEN, 200);
390 LED(LED_ORANGE, 200);
391 LED(LED_GREEN, 200);
392 LED(LED_ORANGE, 200);
393
394 LEDsoff();
395 LED(selected + 1, 0);
396 // Finished recording
397
398 // If we were previously playing, set playing off
399 // so next button push begins playing what we recorded
400 playing = 0;
401
402 cardRead[selected] = 1;
403
404 }
405 /* MF UID clone */
406 else if (button_pressed > 0 && cardRead[selected] == 1)
407 {
408 LEDsoff();
409 LED(selected + 1, 0);
410 LED(LED_ORANGE, 250);
411
412
413 // record
414 Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
415
416 // wait for button to be released
417 while(BUTTON_PRESS())
418 {
419 // Delay cloning until card is in place
420 WDT_HIT();
421 }
422 Dbprintf("Starting clone. [Bank: %u]", selected);
423 // need this delay to prevent catching some weird data
424 SpinDelay(500);
425 // Begin clone function here:
426 /* Example from client/mifarehost.c for commanding a block write for "magic Chinese" cards:
427 UsbCommand c = {CMD_MIFARE_CSETBLOCK, {wantWipe, params & (0xFE | (uid == NULL ? 0:1)), blockNo}};
428 memcpy(c.d.asBytes, data, 16);
429 SendCommand(&c);
430
431 Block read is similar:
432 UsbCommand c = {CMD_MIFARE_CGETBLOCK, {params, 0, blockNo}};
433 We need to imitate that call with blockNo 0 to set a uid.
434
435 The get and set commands are handled in this file:
436 // Work with "magic Chinese" card
437 case CMD_MIFARE_CSETBLOCK:
438 MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
439 break;
440 case CMD_MIFARE_CGETBLOCK:
441 MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
442 //
443 break;
444
445 mfCSetUID provides example logic for UID set workflow:
446 -Read block0 from card in field with MifareCGetBlock()
447 -Configure new values without replacing reserved bytes
448 memcpy(block0, uid, 4); // Copy UID bytes from byte array
449 // Mifare UID BCC
450 block0[4] = block0[0]^block0[1]^block0[2]^block0[3]; // BCC on byte 5
451 Bytes 5-7 are reserved SAK and ATQA for mifare classic
452 -Use mfCSetBlock(0, block0, oldUID, wantWipe, CSETBLOCK_SINGLE_OPER) to write it
453 */
454 uint8_t oldBlock0[16] = {0}, newBlock0[16] = {0}, testBlock0[16] = {0};
455 // arg0 = Flags == CSETBLOCK_SINGLE_OPER=0x1F, arg1=returnSlot, arg2=blockNo
456 MifareCGetBlock(0x1F, 1, 0, oldBlock0);
457 Dbprintf("UID from target tag: %02X%02X%02X%02X", oldBlock0[0],oldBlock0[1],oldBlock0[2],oldBlock0[3]);
458 memcpy(newBlock0,oldBlock0,16);
459 // Copy uid_1st for bank (2nd is for longer UIDs not supported if classic)
460
461 newBlock0[0] = uid_1st[selected]>>24;
462 newBlock0[1] = 0xFF & (uid_1st[selected]>>16);
463 newBlock0[2] = 0xFF & (uid_1st[selected]>>8);
464 newBlock0[3] = 0xFF & (uid_1st[selected]);
465 newBlock0[4] = newBlock0[0]^newBlock0[1]^newBlock0[2]^newBlock0[3];
466 // arg0 = needWipe, arg1 = workFlags, arg2 = blockNo, datain
467 MifareCSetBlock(0, 0xFF,0, newBlock0);
468 MifareCGetBlock(0x1F, 1, 0, testBlock0);
469 if (memcmp(testBlock0,newBlock0,16)==0)
470 {
471 DbpString("Cloned successfull!");
472 cardRead[selected] = 0; // Only if the card was cloned successfully should we clear it
473 }
474 LEDsoff();
475 LED(selected + 1, 0);
476 // Finished recording
477
478 // If we were previously playing, set playing off
479 // so next button push begins playing what we recorded
480 playing = 0;
481
482 }
483 // Change where to record (or begin playing)
484 else if (button_pressed && cardRead[selected])
485 {
486 // Next option if we were previously playing
487 if (playing)
488 selected = (selected + 1) % OPTS;
489 playing = !playing;
490
491 LEDsoff();
492 LED(selected + 1, 0);
493
494 // Begin transmitting
495 if (playing)
496 {
497 LED(LED_GREEN, 0);
498 DbpString("Playing");
499 while (!BUTTON_HELD(500)) { // Loop simulating tag until the button is held a half-sec
500 Dbprintf("Simulating ISO14443a tag with uid[0]: %08x, uid[1]: %08x [Bank: %u]", uid_1st[selected],uid_2nd[selected],selected);
501 SimulateIso14443aTag(1,uid_1st[selected],uid_2nd[selected],NULL);
502 }
503 //cardRead[selected] = 1;
504 Dbprintf("Done playing [Bank: %u]",selected);
505
506 /* We pressed a button so ignore it here with a delay */
507 SpinDelay(300);
508
509 // when done, we're done playing, move to next option
510 selected = (selected + 1) % OPTS;
511 playing = !playing;
512 LEDsoff();
513 LED(selected + 1, 0);
514 }
515 else
516 while(BUTTON_PRESS())
517 WDT_HIT();
518 }
519 }
520 }
521 #elif WITH_LF
522 // samy's sniff and repeat routine
523 void SamyRun()
524 {
525 StandAloneMode();
526 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
527
528 int high[OPTS], low[OPTS];
529 int selected = 0;
530 int playing = 0;
531 int cardRead = 0;
532
533 // Turn on selected LED
534 LED(selected + 1, 0);
535
536 for (;;)
537 {
538 usb_poll();
539 WDT_HIT();
540
541 // Was our button held down or pressed?
542 int button_pressed = BUTTON_HELD(1000);
543 SpinDelay(300);
544
545 // Button was held for a second, begin recording
546 if (button_pressed > 0 && cardRead == 0)
547 {
548 LEDsoff();
549 LED(selected + 1, 0);
550 LED(LED_RED2, 0);
551
552 // record
553 DbpString("Starting recording");
554
555 // wait for button to be released
556 while(BUTTON_PRESS())
557 WDT_HIT();
558
559 /* need this delay to prevent catching some weird data */
560 SpinDelay(500);
561
562 CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
563 Dbprintf("Recorded %x %x %x", selected, high[selected], low[selected]);
564
565 LEDsoff();
566 LED(selected + 1, 0);
567 // Finished recording
568
569 // If we were previously playing, set playing off
570 // so next button push begins playing what we recorded
571 playing = 0;
572
573 cardRead = 1;
574
575 }
576
577 else if (button_pressed > 0 && cardRead == 1)
578 {
579 LEDsoff();
580 LED(selected + 1, 0);
581 LED(LED_ORANGE, 0);
582
583 // record
584 Dbprintf("Cloning %x %x %x", selected, high[selected], low[selected]);
585
586 // wait for button to be released
587 while(BUTTON_PRESS())
588 WDT_HIT();
589
590 /* need this delay to prevent catching some weird data */
591 SpinDelay(500);
592
593 CopyHIDtoT55x7(high[selected], low[selected], 0, 0);
594 Dbprintf("Cloned %x %x %x", selected, high[selected], low[selected]);
595
596 LEDsoff();
597 LED(selected + 1, 0);
598 // Finished recording
599
600 // If we were previously playing, set playing off
601 // so next button push begins playing what we recorded
602 playing = 0;
603
604 cardRead = 0;
605
606 }
607
608 // Change where to record (or begin playing)
609 else if (button_pressed)
610 {
611 // Next option if we were previously playing
612 if (playing)
613 selected = (selected + 1) % OPTS;
614 playing = !playing;
615
616 LEDsoff();
617 LED(selected + 1, 0);
618
619 // Begin transmitting
620 if (playing)
621 {
622 LED(LED_GREEN, 0);
623 DbpString("Playing");
624 // wait for button to be released
625 while(BUTTON_PRESS())
626 WDT_HIT();
627 Dbprintf("%x %x %x", selected, high[selected], low[selected]);
628 CmdHIDsimTAG(high[selected], low[selected], 0);
629 DbpString("Done playing");
630 if (BUTTON_HELD(1000) > 0)
631 {
632 DbpString("Exiting");
633 LEDsoff();
634 return;
635 }
636
637 /* We pressed a button so ignore it here with a delay */
638 SpinDelay(300);
639
640 // when done, we're done playing, move to next option
641 selected = (selected + 1) % OPTS;
642 playing = !playing;
643 LEDsoff();
644 LED(selected + 1, 0);
645 }
646 else
647 while(BUTTON_PRESS())
648 WDT_HIT();
649 }
650 }
651 }
652
653 #endif
654 /*
655 OBJECTIVE
656 Listen and detect an external reader. Determine the best location
657 for the antenna.
658
659 INSTRUCTIONS:
660 Inside the ListenReaderField() function, there is two mode.
661 By default, when you call the function, you will enter mode 1.
662 If you press the PM3 button one time, you will enter mode 2.
663 If you press the PM3 button a second time, you will exit the function.
664
665 DESCRIPTION OF MODE 1:
666 This mode just listens for an external reader field and lights up green
667 for HF and/or red for LF. This is the original mode of the detectreader
668 function.
669
670 DESCRIPTION OF MODE 2:
671 This mode will visually represent, using the LEDs, the actual strength of the
672 current compared to the maximum current detected. Basically, once you know
673 what kind of external reader is present, it will help you spot the best location to place
674 your antenna. You will probably not get some good results if there is a LF and a HF reader
675 at the same place! :-)
676
677 LIGHT SCHEME USED:
678 */
679 static const char LIGHT_SCHEME[] = {
680 0x0, /* ---- | No field detected */
681 0x1, /* X--- | 14% of maximum current detected */
682 0x2, /* -X-- | 29% of maximum current detected */
683 0x4, /* --X- | 43% of maximum current detected */
684 0x8, /* ---X | 57% of maximum current detected */
685 0xC, /* --XX | 71% of maximum current detected */
686 0xE, /* -XXX | 86% of maximum current detected */
687 0xF, /* XXXX | 100% of maximum current detected */
688 };
689 static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]);
690
691 void ListenReaderField(int limit)
692 {
693 int lf_av, lf_av_new, lf_baseline= 0, lf_max;
694 int hf_av, hf_av_new, hf_baseline= 0, hf_max;
695 int mode=1, display_val, display_max, i;
696
697 #define LF_ONLY 1
698 #define HF_ONLY 2
699 #define REPORT_CHANGE 10 // report new values only if they have changed at least by REPORT_CHANGE
700
701
702 // switch off FPGA - we don't want to measure our own signal
703 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
704 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
705
706 LEDsoff();
707
708 lf_av = lf_max = AvgAdc(ADC_CHAN_LF);
709
710 if(limit != HF_ONLY) {
711 Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10);
712 lf_baseline = lf_av;
713 }
714
715 hf_av = hf_max = AvgAdc(ADC_CHAN_HF);
716
717 if (limit != LF_ONLY) {
718 Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10);
719 hf_baseline = hf_av;
720 }
721
722 for(;;) {
723 if (BUTTON_PRESS()) {
724 SpinDelay(500);
725 switch (mode) {
726 case 1:
727 mode=2;
728 DbpString("Signal Strength Mode");
729 break;
730 case 2:
731 default:
732 DbpString("Stopped");
733 LEDsoff();
734 return;
735 break;
736 }
737 }
738 WDT_HIT();
739
740 if (limit != HF_ONLY) {
741 if(mode == 1) {
742 if (abs(lf_av - lf_baseline) > REPORT_CHANGE)
743 LED_D_ON();
744 else
745 LED_D_OFF();
746 }
747
748 lf_av_new = AvgAdc(ADC_CHAN_LF);
749 // see if there's a significant change
750 if(abs(lf_av - lf_av_new) > REPORT_CHANGE) {
751 Dbprintf("LF 125/134kHz Field Change: %5dmV", (MAX_ADC_LF_VOLTAGE * lf_av_new) >> 10);
752 lf_av = lf_av_new;
753 if (lf_av > lf_max)
754 lf_max = lf_av;
755 }
756 }
757
758 if (limit != LF_ONLY) {
759 if (mode == 1){
760 if (abs(hf_av - hf_baseline) > REPORT_CHANGE)
761 LED_B_ON();
762 else
763 LED_B_OFF();
764 }
765
766 hf_av_new = AvgAdc(ADC_CHAN_HF);
767 // see if there's a significant change
768 if(abs(hf_av - hf_av_new) > REPORT_CHANGE) {
769 Dbprintf("HF 13.56MHz Field Change: %5dmV", (MAX_ADC_HF_VOLTAGE * hf_av_new) >> 10);
770 hf_av = hf_av_new;
771 if (hf_av > hf_max)
772 hf_max = hf_av;
773 }
774 }
775
776 if(mode == 2) {
777 if (limit == LF_ONLY) {
778 display_val = lf_av;
779 display_max = lf_max;
780 } else if (limit == HF_ONLY) {
781 display_val = hf_av;
782 display_max = hf_max;
783 } else { /* Pick one at random */
784 if( (hf_max - hf_baseline) > (lf_max - lf_baseline) ) {
785 display_val = hf_av;
786 display_max = hf_max;
787 } else {
788 display_val = lf_av;
789 display_max = lf_max;
790 }
791 }
792 for (i=0; i<LIGHT_LEN; i++) {
793 if (display_val >= ((display_max/LIGHT_LEN)*i) && display_val <= ((display_max/LIGHT_LEN)*(i+1))) {
794 if (LIGHT_SCHEME[i] & 0x1) LED_C_ON(); else LED_C_OFF();
795 if (LIGHT_SCHEME[i] & 0x2) LED_A_ON(); else LED_A_OFF();
796 if (LIGHT_SCHEME[i] & 0x4) LED_B_ON(); else LED_B_OFF();
797 if (LIGHT_SCHEME[i] & 0x8) LED_D_ON(); else LED_D_OFF();
798 break;
799 }
800 }
801 }
802 }
803 }
804
805 void UsbPacketReceived(uint8_t *packet, int len)
806 {
807 UsbCommand *c = (UsbCommand *)packet;
808
809 // Dbprintf("received %d bytes, with command: 0x%04x and args: %d %d %d",len,c->cmd,c->arg[0],c->arg[1],c->arg[2]);
810
811 switch(c->cmd) {
812 #ifdef WITH_LF
813 case CMD_SET_LF_SAMPLING_CONFIG:
814 setSamplingConfig((sample_config *) c->d.asBytes);
815 break;
816 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
817 cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0);
818 break;
819 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
820 ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
821 break;
822 case CMD_LF_SNOOP_RAW_ADC_SAMPLES:
823 cmd_send(CMD_ACK,SnoopLF(),0,0,0,0);
824 break;
825 case CMD_HID_DEMOD_FSK:
826 CmdHIDdemodFSK(c->arg[0], 0, 0, 1);
827 break;
828 case CMD_HID_SIM_TAG:
829 CmdHIDsimTAG(c->arg[0], c->arg[1], 1);
830 break;
831 case CMD_FSK_SIM_TAG:
832 CmdFSKsimTAG(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
833 break;
834 case CMD_ASK_SIM_TAG:
835 CmdASKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
836 break;
837 case CMD_PSK_SIM_TAG:
838 CmdPSKsimTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
839 break;
840 case CMD_HID_CLONE_TAG:
841 CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
842 break;
843 case CMD_IO_DEMOD_FSK:
844 CmdIOdemodFSK(c->arg[0], 0, 0, 1);
845 break;
846 case CMD_IO_CLONE_TAG:
847 CopyIOtoT55x7(c->arg[0], c->arg[1], c->d.asBytes[0]);
848 break;
849 case CMD_EM410X_DEMOD:
850 CmdEM410xdemod(c->arg[0], 0, 0, 1);
851 break;
852 case CMD_EM410X_WRITE_TAG:
853 WriteEM410x(c->arg[0], c->arg[1], c->arg[2]);
854 break;
855 case CMD_READ_TI_TYPE:
856 ReadTItag();
857 break;
858 case CMD_WRITE_TI_TYPE:
859 WriteTItag(c->arg[0],c->arg[1],c->arg[2]);
860 break;
861 case CMD_SIMULATE_TAG_125K:
862 LED_A_ON();
863 SimulateTagLowFrequency(c->arg[0], c->arg[1], 1);
864 LED_A_OFF();
865 break;
866 case CMD_LF_SIMULATE_BIDIR:
867 SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]);
868 break;
869 case CMD_INDALA_CLONE_TAG:
870 CopyIndala64toT55x7(c->arg[0], c->arg[1]);
871 break;
872 case CMD_INDALA_CLONE_TAG_L:
873 CopyIndala224toT55x7(c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6]);
874 break;
875 case CMD_T55XX_READ_BLOCK:
876 T55xxReadBlock(c->arg[1], c->arg[2],c->d.asBytes[0]);
877 break;
878 case CMD_T55XX_WRITE_BLOCK:
879 T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
880 cmd_send(CMD_ACK,0,0,0,0,0);
881 break;
882 case CMD_T55XX_READ_TRACE:
883 T55xxReadTrace();
884 break;
885 case CMD_PCF7931_READ:
886 ReadPCF7931();
887 cmd_send(CMD_ACK,0,0,0,0,0);
888 break;
889 case CMD_EM4X_READ_WORD:
890 EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
891 break;
892 case CMD_EM4X_WRITE_WORD:
893 EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
894 break;
895 case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
896 CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
897 break;
898 #endif
899
900 #ifdef WITH_HITAG
901 case CMD_SNOOP_HITAG: // Eavesdrop Hitag tag, args = type
902 SnoopHitag(c->arg[0]);
903 break;
904 case CMD_SIMULATE_HITAG: // Simulate Hitag tag, args = memory content
905 SimulateHitagTag((bool)c->arg[0],(byte_t*)c->d.asBytes);
906 break;
907 case CMD_READER_HITAG: // Reader for Hitag tags, args = type and function
908 ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
909 break;
910 #endif
911
912 #ifdef WITH_ISO15693
913 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
914 AcquireRawAdcSamplesIso15693();
915 break;
916 case CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693:
917 RecordRawAdcSamplesIso15693();
918 break;
919
920 case CMD_ISO_15693_COMMAND:
921 DirectTag15693Command(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
922 break;
923
924 case CMD_ISO_15693_FIND_AFI:
925 BruteforceIso15693Afi(c->arg[0]);
926 break;
927
928 case CMD_ISO_15693_DEBUG:
929 SetDebugIso15693(c->arg[0]);
930 break;
931
932 case CMD_READER_ISO_15693:
933 ReaderIso15693(c->arg[0]);
934 break;
935 case CMD_SIMTAG_ISO_15693:
936 SimTagIso15693(c->arg[0], c->d.asBytes);
937 break;
938 #endif
939
940 #ifdef WITH_LEGICRF
941 case CMD_SIMULATE_TAG_LEGIC_RF:
942 LegicRfSimulate(c->arg[0], c->arg[1], c->arg[2]);
943 break;
944
945 case CMD_WRITER_LEGIC_RF:
946 LegicRfWriter(c->arg[1], c->arg[0]);
947 break;
948
949 case CMD_READER_LEGIC_RF:
950 LegicRfReader(c->arg[0], c->arg[1]);
951 break;
952 #endif
953
954 #ifdef WITH_ISO14443b
955 case CMD_READ_SRI512_TAG:
956 ReadSTMemoryIso14443b(0x0F);
957 break;
958 case CMD_READ_SRIX4K_TAG:
959 ReadSTMemoryIso14443b(0x7F);
960 break;
961 case CMD_SNOOP_ISO_14443B:
962 SnoopIso14443b();
963 break;
964 case CMD_SIMULATE_TAG_ISO_14443B:
965 SimulateIso14443bTag();
966 break;
967 case CMD_ISO_14443B_COMMAND:
968 SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
969 break;
970 #endif
971
972 #ifdef WITH_ISO14443a
973 case CMD_SNOOP_ISO_14443a:
974 SnoopIso14443a(c->arg[0]);
975 break;
976 case CMD_READER_ISO_14443a:
977 ReaderIso14443a(c);
978 break;
979 case CMD_SIMULATE_TAG_ISO_14443a:
980 SimulateIso14443aTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); // ## Simulate iso14443a tag - pass tag type & UID
981 break;
982
983 case CMD_EPA_PACE_COLLECT_NONCE:
984 EPA_PACE_Collect_Nonce(c);
985 break;
986 case CMD_EPA_PACE_REPLAY:
987 EPA_PACE_Replay(c);
988 break;
989
990 case CMD_READER_MIFARE:
991 ReaderMifare(c->arg[0]);
992 break;
993 case CMD_MIFARE_READBL:
994 MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
995 break;
996 case CMD_MIFAREU_READBL:
997 MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes);
998 break;
999 case CMD_MIFAREUC_AUTH:
1000 MifareUC_Auth(c->arg[0],c->d.asBytes);
1001 break;
1002 case CMD_MIFAREU_READCARD:
1003 MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1004 break;
1005 case CMD_MIFAREUC_SETPWD:
1006 MifareUSetPwd(c->arg[0], c->d.asBytes);
1007 break;
1008 case CMD_MIFARE_READSC:
1009 MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1010 break;
1011 case CMD_MIFARE_WRITEBL:
1012 MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1013 break;
1014 //case CMD_MIFAREU_WRITEBL_COMPAT:
1015 //MifareUWriteBlockCompat(c->arg[0], c->d.asBytes);
1016 //break;
1017 case CMD_MIFAREU_WRITEBL:
1018 MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
1019 break;
1020 case CMD_MIFARE_NESTED:
1021 MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1022 break;
1023 case CMD_MIFARE_CHKKEYS:
1024 MifareChkKeys(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1025 break;
1026 case CMD_SIMULATE_MIFARE_CARD:
1027 Mifare1ksim(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1028 break;
1029
1030 // emulator
1031 case CMD_MIFARE_SET_DBGMODE:
1032 MifareSetDbgLvl(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1033 break;
1034 case CMD_MIFARE_EML_MEMCLR:
1035 MifareEMemClr(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1036 break;
1037 case CMD_MIFARE_EML_MEMSET:
1038 MifareEMemSet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1039 break;
1040 case CMD_MIFARE_EML_MEMGET:
1041 MifareEMemGet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1042 break;
1043 case CMD_MIFARE_EML_CARDLOAD:
1044 MifareECardLoad(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1045 break;
1046
1047 // Work with "magic Chinese" card
1048 case CMD_MIFARE_CSETBLOCK:
1049 MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1050 break;
1051 case CMD_MIFARE_CGETBLOCK:
1052 MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1053 break;
1054 case CMD_MIFARE_CIDENT:
1055 MifareCIdent();
1056 break;
1057
1058 // mifare sniffer
1059 case CMD_MIFARE_SNIFFER:
1060 SniffMifare(c->arg[0]);
1061 break;
1062
1063 #endif
1064
1065 #ifdef WITH_ICLASS
1066 // Makes use of ISO14443a FPGA Firmware
1067 case CMD_SNOOP_ICLASS:
1068 SnoopIClass();
1069 break;
1070 case CMD_SIMULATE_TAG_ICLASS:
1071 SimulateIClass(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1072 break;
1073 case CMD_READER_ICLASS:
1074 ReaderIClass(c->arg[0]);
1075 break;
1076 case CMD_READER_ICLASS_REPLAY:
1077 ReaderIClass_Replay(c->arg[0], c->d.asBytes);
1078 break;
1079 case CMD_ICLASS_EML_MEMSET:
1080 emlSet(c->d.asBytes,c->arg[0], c->arg[1]);
1081 break;
1082 #endif
1083
1084 case CMD_BUFF_CLEAR:
1085 BigBuf_Clear();
1086 break;
1087
1088 case CMD_MEASURE_ANTENNA_TUNING:
1089 MeasureAntennaTuning();
1090 break;
1091
1092 case CMD_MEASURE_ANTENNA_TUNING_HF:
1093 MeasureAntennaTuningHf();
1094 break;
1095
1096 case CMD_LISTEN_READER_FIELD:
1097 ListenReaderField(c->arg[0]);
1098 break;
1099
1100 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
1101 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1102 SpinDelay(200);
1103 LED_D_OFF(); // LED D indicates field ON or OFF
1104 break;
1105
1106 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
1107
1108 LED_B_ON();
1109 uint8_t *BigBuf = BigBuf_get_addr();
1110 for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
1111 size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
1112 cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len);
1113 }
1114 // Trigger a finish downloading signal with an ACK frame
1115 cmd_send(CMD_ACK,1,0,BigBuf_get_traceLen(),getSamplingConfig(),sizeof(sample_config));
1116 LED_B_OFF();
1117 break;
1118
1119 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
1120 uint8_t *b = BigBuf_get_addr();
1121 memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
1122 cmd_send(CMD_ACK,0,0,0,0,0);
1123 break;
1124 }
1125 case CMD_READ_MEM:
1126 ReadMem(c->arg[0]);
1127 break;
1128
1129 case CMD_SET_LF_DIVISOR:
1130 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
1131 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]);
1132 break;
1133
1134 case CMD_SET_ADC_MUX:
1135 switch(c->arg[0]) {
1136 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD); break;
1137 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW); break;
1138 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); break;
1139 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW); break;
1140 }
1141 break;
1142
1143 case CMD_VERSION:
1144 SendVersion();
1145 break;
1146
1147 #ifdef WITH_LCD
1148 case CMD_LCD_RESET:
1149 LCDReset();
1150 break;
1151 case CMD_LCD:
1152 LCDSend(c->arg[0]);
1153 break;
1154 #endif
1155 case CMD_SETUP_WRITE:
1156 case CMD_FINISH_WRITE:
1157 case CMD_HARDWARE_RESET:
1158 usb_disable();
1159 SpinDelay(1000);
1160 SpinDelay(1000);
1161 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
1162 for(;;) {
1163 // We're going to reset, and the bootrom will take control.
1164 }
1165 break;
1166
1167 case CMD_START_FLASH:
1168 if(common_area.flags.bootrom_present) {
1169 common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
1170 }
1171 usb_disable();
1172 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
1173 for(;;);
1174 break;
1175
1176 case CMD_DEVICE_INFO: {
1177 uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
1178 if(common_area.flags.bootrom_present) dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
1179 cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0);
1180 break;
1181 }
1182 default:
1183 Dbprintf("%s: 0x%04x","unknown command:",c->cmd);
1184 break;
1185 }
1186 }
1187
1188 void __attribute__((noreturn)) AppMain(void)
1189 {
1190 SpinDelay(100);
1191 clear_trace();
1192 if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
1193 /* Initialize common area */
1194 memset(&common_area, 0, sizeof(common_area));
1195 common_area.magic = COMMON_AREA_MAGIC;
1196 common_area.version = 1;
1197 }
1198 common_area.flags.osimage_present = 1;
1199
1200 LED_D_OFF();
1201 LED_C_OFF();
1202 LED_B_OFF();
1203 LED_A_OFF();
1204
1205 // Init USB device
1206 usb_enable();
1207
1208 // The FPGA gets its clock from us from PCK0 output, so set that up.
1209 AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
1210 AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0;
1211 AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK0;
1212 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
1213 AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK |
1214 AT91C_PMC_PRES_CLK_4;
1215 AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0;
1216
1217 // Reset SPI
1218 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
1219 // Reset SSC
1220 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
1221
1222 // Load the FPGA image, which we have stored in our flash.
1223 // (the HF version by default)
1224 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
1225
1226 StartTickCount();
1227
1228 #ifdef WITH_LCD
1229 LCDInit();
1230 #endif
1231
1232 byte_t rx[sizeof(UsbCommand)];
1233 size_t rx_len;
1234
1235 for(;;) {
1236 if (usb_poll()) {
1237 rx_len = usb_read(rx,sizeof(UsbCommand));
1238 if (rx_len) {
1239 UsbPacketReceived(rx,rx_len);
1240 }
1241 }
1242 WDT_HIT();
1243
1244 #ifdef WITH_LF
1245 #ifndef WITH_ISO14443a_StandAlone
1246 if (BUTTON_HELD(1000) > 0)
1247 SamyRun();
1248 #endif
1249 #endif
1250 #ifdef WITH_ISO14443a
1251 #ifdef WITH_ISO14443a_StandAlone
1252 if (BUTTON_HELD(1000) > 0)
1253 StandAloneMode14a();
1254 #endif
1255 #endif
1256 }
1257 }
Impressum, Datenschutz