]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/appmain.c
Implemented 'hw status' and 'hw ping', put back client-side cacheing of 'hw version'
[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
902cb3c0 13#include "usb_cdc.h"
14#include "cmd.h"
15
e30c654b 16#include "proxmark3.h"
15c4dc5a 17#include "apps.h"
f7e3ed82 18#include "util.h"
9ab7a6c7 19#include "printf.h"
20#include "string.h"
31d1caa5 21
9ab7a6c7 22#include <stdarg.h>
f7e3ed82 23
15c4dc5a 24#include "legicrf.h"
d19929cb 25#include <hitag2.h>
31abe49f 26#include "lfsampling.h"
3000dc4e 27#include "BigBuf.h"
e2012d1b 28#include "mifareutil.h"
15c4dc5a 29#ifdef WITH_LCD
902cb3c0 30 #include "LCD.h"
15c4dc5a 31#endif
32
e46fe044
CY
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
47uint8_t ToSend[TOSEND_BUFFER_SIZE];
15c4dc5a 48int ToSendMax;
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{
2bdd68c3 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
2bdd68c3 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);
2bdd68c3 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
2bdd68c3 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;
2bdd68c3 213 peak = LF_Results[i];
15c4dc5a 214 peakf = i;
9f693930 215 //ptr = i;
15c4dc5a 216 }
217 }
218
2bdd68c3 219 for (i=18; i >= 0; i--) LF_Results[i] = 0;
220
221 LED_A_ON();
15c4dc5a 222 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
7cc204bf 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);
2bdd68c3 230 LED_A_OFF();
231 LED_B_OFF();
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 */
0fa01ec7 270extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__;
15c4dc5a 271void SendVersion(void)
272{
8e074056 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 ) {
8e074056 282 strcat(VersionString, "bootrom version information appears invalid\n");
15c4dc5a 283 } else {
284 FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);
8e074056 285 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
15c4dc5a 286 }
e30c654b 287
15c4dc5a 288 FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
8e074056 289 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
e30c654b 290
e6153040 291 FpgaGatherVersion(FPGA_BITSTREAM_LF, temp, sizeof(temp));
8e074056 292 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
e6153040 293 FpgaGatherVersion(FPGA_BITSTREAM_HF, temp, sizeof(temp));
8e074056 294 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
0fa01ec7 295
e6153040 296 // Send Chip ID and used flash memory
0fa01ec7 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;
8e074056 299 cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString));
15c4dc5a 300}
e2012d1b
MHS
301/**
302 * Prints runtime information about the PM3.
303**/
304void SendStatus(void)
305{
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
86a83668 315#if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF)
15c4dc5a 316
15c4dc5a 317#define OPTS 2
318
86a83668
MHS
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
86a83668
MHS
333}
334
335#endif
336
337
338
339#ifdef WITH_ISO14443a_StandAlone
340void StandAloneMode14a()
341{
342 StandAloneMode();
343 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
344
15c4dc5a 345 int selected = 0;
346 int playing = 0;
86a83668
MHS
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};
15c4dc5a 351
15c4dc5a 352 LED(selected + 1, 0);
353
354 for (;;)
355 {
6e82300d 356 usb_poll();
86a83668 357 WDT_HIT();
15c4dc5a 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
86a83668 364 if (button_pressed > 0 && cardRead[selected] == 0)
15c4dc5a 365 {
366 LEDsoff();
367 LED(selected + 1, 0);
368 LED(LED_RED2, 0);
369
370 // record
86a83668 371 Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected);
15c4dc5a 372
373 // wait for button to be released
374 while(BUTTON_PRESS())
375 WDT_HIT();
15c4dc5a 376 /* need this delay to prevent catching some weird data */
377 SpinDelay(500);
86a83668
MHS
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);
15c4dc5a 382
86a83668
MHS
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);
15c4dc5a 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;
3fe4ff4f 415
86a83668
MHS
416 cardRead[selected] = 1;
417
418 }
419 /* MF UID clone */
420 else if (button_pressed > 0 && cardRead[selected] == 1)
3fe4ff4f 421 {
422 LEDsoff();
423 LED(selected + 1, 0);
86a83668
MHS
424 LED(LED_ORANGE, 250);
425
3fe4ff4f 426
427 // record
86a83668 428 Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
3fe4ff4f 429
430 // wait for button to be released
431 while(BUTTON_PRESS())
86a83668
MHS
432 {
433 // Delay cloning until card is in place
3fe4ff4f 434 WDT_HIT();
86a83668
MHS
435 }
436 Dbprintf("Starting clone. [Bank: %u]", selected);
437 // need this delay to prevent catching some weird data
3fe4ff4f 438 SpinDelay(500);
86a83668
MHS
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;
3fe4ff4f 458
86a83668
MHS
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 }
3fe4ff4f 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;
15c4dc5a 495
86a83668 496 }
15c4dc5a 497 // Change where to record (or begin playing)
86a83668 498 else if (button_pressed && cardRead[selected])
15c4dc5a 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");
86a83668
MHS
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);
15c4dc5a 516 }
86a83668
MHS
517 //cardRead[selected] = 1;
518 Dbprintf("Done playing [Bank: %u]",selected);
15c4dc5a 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}
86a83668
MHS
535#elif WITH_LF
536// samy's sniff and repeat routine
537void SamyRun()
e46fe044 538{
86a83668
MHS
539 StandAloneMode();
540 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
e46fe044 541
86a83668 542 int high[OPTS], low[OPTS];
e46fe044
CY
543 int selected = 0;
544 int playing = 0;
86a83668 545 int cardRead = 0;
e46fe044 546
86a83668 547 // Turn on selected LED
e46fe044
CY
548 LED(selected + 1, 0);
549
550 for (;;)
551 {
552 usb_poll();
86a83668 553 WDT_HIT();
e46fe044
CY
554
555 // Was our button held down or pressed?
556 int button_pressed = BUTTON_HELD(1000);
e46fe044
CY
557 SpinDelay(300);
558
559 // Button was held for a second, begin recording
86a83668 560 if (button_pressed > 0 && cardRead == 0)
e46fe044
CY
561 {
562 LEDsoff();
563 LED(selected + 1, 0);
564 LED(LED_RED2, 0);
565
566 // record
86a83668 567 DbpString("Starting recording");
e46fe044
CY
568
569 // wait for button to be released
570 while(BUTTON_PRESS())
571 WDT_HIT();
86a83668 572
e46fe044
CY
573 /* need this delay to prevent catching some weird data */
574 SpinDelay(500);
e46fe044 575
86a83668
MHS
576 CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
577 Dbprintf("Recorded %x %x %x", selected, high[selected], low[selected]);
578
e46fe044
CY
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;
586
86a83668 587 cardRead = 1;
e46fe044
CY
588
589 }
86a83668
MHS
590
591 else if (button_pressed > 0 && cardRead == 1)
e46fe044
CY
592 {
593 LEDsoff();
594 LED(selected + 1, 0);
86a83668 595 LED(LED_ORANGE, 0);
15c4dc5a 596
e46fe044 597 // record
86a83668 598 Dbprintf("Cloning %x %x %x", selected, high[selected], low[selected]);
e46fe044
CY
599
600 // wait for button to be released
601 while(BUTTON_PRESS())
e46fe044 602 WDT_HIT();
86a83668
MHS
603
604 /* need this delay to prevent catching some weird data */
e46fe044 605 SpinDelay(500);
e46fe044 606
86a83668
MHS
607 CopyHIDtoT55x7(high[selected], low[selected], 0, 0);
608 Dbprintf("Cloned %x %x %x", selected, high[selected], low[selected]);
609
e46fe044
CY
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;
86a83668
MHS
617
618 cardRead = 0;
e46fe044
CY
619
620 }
86a83668 621
e46fe044 622 // Change where to record (or begin playing)
86a83668 623 else if (button_pressed)
e46fe044
CY
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");
86a83668
MHS
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;
e46fe044 649 }
e46fe044
CY
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 }
86a83668 660 else
e46fe044
CY
661 while(BUTTON_PRESS())
662 WDT_HIT();
663 }
664 }
665}
86a83668 666
e46fe044 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
902cb3c0 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]);
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:
3fe4ff4f 840 CmdHIDdemodFSK(c->arg[0], 0, 0, 1);
7e67e42f 841 break;
842 case CMD_HID_SIM_TAG:
3fe4ff4f 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;
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:
3fe4ff4f 858 CmdIOdemodFSK(c->arg[0], 0, 0, 1);
a1f3bb12 859 break;
3fe4ff4f 860 case CMD_IO_CLONE_TAG:
a1f3bb12 861 CopyIOtoT55x7(c->arg[0], c->arg[1], c->d.asBytes[0]);
862 break;
66707a3b 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:
31d1caa5 876 LED_A_ON();
7e67e42f 877 SimulateTagLowFrequency(c->arg[0], c->arg[1], 1);
31d1caa5 878 LED_A_OFF();
7e67e42f 879 break;
880 case CMD_LF_SIMULATE_BIDIR:
881 SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]);
882 break;
3fe4ff4f 883 case CMD_INDALA_CLONE_TAG:
2414f978 884 CopyIndala64toT55x7(c->arg[0], c->arg[1]);
885 break;
3fe4ff4f 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]);
976627d5 894 cmd_send(CMD_ACK,0,0,0,0,0);
1c611bbd 895 break;
3fe4ff4f 896 case CMD_T55XX_READ_TRACE:
1c611bbd 897 T55xxReadTrace();
898 break;
3fe4ff4f 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;
dbf6e824
CY
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:
3fe4ff4f 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:
51d4f6f1 970 ReadSTMemoryIso14443b(0x0F);
15c4dc5a 971 break;
7e67e42f 972 case CMD_READ_SRIX4K_TAG:
51d4f6f1 973 ReadSTMemoryIso14443b(0x7F);
7e67e42f 974 break;
132a0217 975 case CMD_SNOOP_ISO_14443B:
51d4f6f1 976 SnoopIso14443b();
7e67e42f 977 break;
132a0217 978 case CMD_SIMULATE_TAG_ISO_14443B:
51d4f6f1 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:
5cd9ec01 988 SnoopIso14443a(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;
3fe4ff4f 996
5acd09bd 997 case CMD_EPA_PACE_COLLECT_NONCE:
902cb3c0 998 EPA_PACE_Collect_Nonce(c);
5acd09bd 999 break;
3bb07d96
FM
1000 case CMD_EPA_PACE_REPLAY:
1001 EPA_PACE_Replay(c);
1002 break;
7e67e42f 1003
15c4dc5a 1004 case CMD_READER_MIFARE:
f168b263 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:
f168b263 1011 MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes);
981bd429 1012 break;
8258f409 1013 case CMD_MIFAREUC_AUTH:
1014 MifareUC_Auth(c->arg[0],c->d.asBytes);
a631936e 1015 break;
981bd429 1016 case CMD_MIFAREU_READCARD:
75377d29 1017 MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
117d9ec2 1018 break;
f168b263 1019 case CMD_MIFAREUC_SETPWD:
1020 MifareUSetPwd(c->arg[0], c->d.asBytes);
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;
4973f23d 1028 //case CMD_MIFAREU_WRITEBL_COMPAT:
1029 //MifareUWriteBlockCompat(c->arg[0], c->d.asBytes);
1030 //break;
981bd429 1031 case CMD_MIFAREU_WRITEBL:
4973f23d 1032 MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
f168b263 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
3fe4ff4f 1062 case CMD_MIFARE_CSETBLOCK:
0675f200 1063 MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
545a1f38 1064 break;
3fe4ff4f 1065 case CMD_MIFARE_CGETBLOCK:
545a1f38 1066 MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
8556b852 1067 break;
3fe4ff4f 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;
a631936e 1076
20f9a2a1
M
1077#endif
1078
7e67e42f 1079#ifdef WITH_ICLASS
cee5a30d 1080 // Makes use of ISO14443a FPGA Firmware
1081 case CMD_SNOOP_ICLASS:
1082 SnoopIClass();
1083 break;
1e262141 1084 case CMD_SIMULATE_TAG_ICLASS:
ff7bb4ef 1085 SimulateIClass(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1e262141 1086 break;
1087 case CMD_READER_ICLASS:
1088 ReaderIClass(c->arg[0]);
1089 break;
c3963755 1090 case CMD_READER_ICLASS_REPLAY:
fecd8202 1091 ReaderIClass_Replay(c->arg[0], c->d.asBytes);
c3963755 1092 break;
e80aeb96
MHS
1093 case CMD_ICLASS_EML_MEMSET:
1094 emlSet(c->d.asBytes,c->arg[0], c->arg[1]);
1095 break;
cee5a30d 1096#endif
1097
7e67e42f 1098 case CMD_BUFF_CLEAR:
117d9ec2 1099 BigBuf_Clear();
15c4dc5a 1100 break;
15c4dc5a 1101
1102 case CMD_MEASURE_ANTENNA_TUNING:
1103 MeasureAntennaTuning();
1104 break;
1105
1106 case CMD_MEASURE_ANTENNA_TUNING_HF:
1107 MeasureAntennaTuningHf();
1108 break;
1109
1110 case CMD_LISTEN_READER_FIELD:
1111 ListenReaderField(c->arg[0]);
1112 break;
1113
15c4dc5a 1114 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
1115 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1116 SpinDelay(200);
1117 LED_D_OFF(); // LED D indicates field ON or OFF
1118 break;
1119
1c611bbd 1120 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
902cb3c0 1121
1c611bbd 1122 LED_B_ON();
117d9ec2 1123 uint8_t *BigBuf = BigBuf_get_addr();
1c611bbd 1124 for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
1125 size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
3000dc4e 1126 cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len);
1c611bbd 1127 }
1128 // Trigger a finish downloading signal with an ACK frame
3000dc4e 1129 cmd_send(CMD_ACK,1,0,BigBuf_get_traceLen(),getSamplingConfig(),sizeof(sample_config));
d3b1f4e4 1130 LED_B_OFF();
1c611bbd 1131 break;
15c4dc5a 1132
1133 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
117d9ec2 1134 uint8_t *b = BigBuf_get_addr();
3fe4ff4f 1135 memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
1c611bbd 1136 cmd_send(CMD_ACK,0,0,0,0,0);
1137 break;
1138 }
15c4dc5a 1139 case CMD_READ_MEM:
1140 ReadMem(c->arg[0]);
1141 break;
1142
1143 case CMD_SET_LF_DIVISOR:
7cc204bf 1144 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
15c4dc5a 1145 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]);
1146 break;
1147
1148 case CMD_SET_ADC_MUX:
1149 switch(c->arg[0]) {
1150 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD); break;
1151 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW); break;
1152 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); break;
1153 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW); break;
1154 }
1155 break;
1156
1157 case CMD_VERSION:
1158 SendVersion();
1159 break;
e2012d1b
MHS
1160 case CMD_STATUS:
1161 SendStatus();
1162 break;
1163 case CMD_PING:
1164 cmd_send(CMD_ACK,0,0,0,0,0);
1165 break;
15c4dc5a 1166#ifdef WITH_LCD
1167 case CMD_LCD_RESET:
1168 LCDReset();
1169 break;
1170 case CMD_LCD:
1171 LCDSend(c->arg[0]);
1172 break;
1173#endif
1174 case CMD_SETUP_WRITE:
1175 case CMD_FINISH_WRITE:
1c611bbd 1176 case CMD_HARDWARE_RESET:
1177 usb_disable();
15c4dc5a 1178 SpinDelay(1000);
1179 SpinDelay(1000);
1180 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
1181 for(;;) {
1182 // We're going to reset, and the bootrom will take control.
1183 }
1c611bbd 1184 break;
15c4dc5a 1185
1c611bbd 1186 case CMD_START_FLASH:
15c4dc5a 1187 if(common_area.flags.bootrom_present) {
1188 common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
1189 }
1c611bbd 1190 usb_disable();
15c4dc5a 1191 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
1192 for(;;);
1c611bbd 1193 break;
e30c654b 1194
15c4dc5a 1195 case CMD_DEVICE_INFO: {
902cb3c0 1196 uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
1197 if(common_area.flags.bootrom_present) dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
1c611bbd 1198 cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0);
1199 break;
1200 }
1201 default:
15c4dc5a 1202 Dbprintf("%s: 0x%04x","unknown command:",c->cmd);
1c611bbd 1203 break;
15c4dc5a 1204 }
1205}
1206
1207void __attribute__((noreturn)) AppMain(void)
1208{
1209 SpinDelay(100);
9e8255d4 1210 clear_trace();
15c4dc5a 1211 if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
1212 /* Initialize common area */
1213 memset(&common_area, 0, sizeof(common_area));
1214 common_area.magic = COMMON_AREA_MAGIC;
1215 common_area.version = 1;
1216 }
1217 common_area.flags.osimage_present = 1;
1218
1219 LED_D_OFF();
1220 LED_C_OFF();
1221 LED_B_OFF();
1222 LED_A_OFF();
1223
3fe4ff4f 1224 // Init USB device
902cb3c0 1225 usb_enable();
15c4dc5a 1226
1227 // The FPGA gets its clock from us from PCK0 output, so set that up.
1228 AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
1229 AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0;
1230 AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK0;
1231 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
1232 AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK |
1233 AT91C_PMC_PRES_CLK_4;
1234 AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0;
1235
1236 // Reset SPI
1237 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
1238 // Reset SSC
1239 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
1240
1241 // Load the FPGA image, which we have stored in our flash.
7cc204bf 1242 // (the HF version by default)
1243 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1244
9ca155ba 1245 StartTickCount();
902cb3c0 1246
15c4dc5a 1247#ifdef WITH_LCD
15c4dc5a 1248 LCDInit();
15c4dc5a 1249#endif
1250
902cb3c0 1251 byte_t rx[sizeof(UsbCommand)];
1252 size_t rx_len;
1253
15c4dc5a 1254 for(;;) {
902cb3c0 1255 if (usb_poll()) {
1256 rx_len = usb_read(rx,sizeof(UsbCommand));
1257 if (rx_len) {
1258 UsbPacketReceived(rx,rx_len);
1259 }
1260 }
15c4dc5a 1261 WDT_HIT();
1262
1263#ifdef WITH_LF
e46fe044 1264#ifndef WITH_ISO14443a_StandAlone
15c4dc5a 1265 if (BUTTON_HELD(1000) > 0)
1266 SamyRun();
e46fe044
CY
1267#endif
1268#endif
1269#ifdef WITH_ISO14443a
1270#ifdef WITH_ISO14443a_StandAlone
1271 if (BUTTON_HELD(1000) > 0)
1272 StandAloneMode14a();
1273#endif
15c4dc5a 1274#endif
1275 }
1276}
Impressum, Datenschutz