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