Merge pull request #133 from marshmellow42/master
[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"
15c4dc5a 28#ifdef WITH_LCD
902cb3c0 29 #include "LCD.h"
15c4dc5a 30#endif
31
e46fe044
CY
32// Craig Young - 14a stand-alone code
33#ifdef WITH_ISO14443a_StandAlone
34 #include "iso14443a.h"
35#endif
36
15c4dc5a 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
6a1f2d82 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
46uint8_t ToSend[TOSEND_BUFFER_SIZE];
15c4dc5a 47int ToSendMax;
48static int ToSendBit;
49struct common_area common_area __attribute__((section(".commonarea")));
50
15c4dc5a 51void ToSendReset(void)
52{
53 ToSendMax = -1;
54 ToSendBit = 8;
55}
56
57void 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
6a1f2d82 71 if(ToSendMax >= sizeof(ToSend)) {
15c4dc5a 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
81void DbpString(char *str)
82{
9440213d 83 byte_t len = strlen(str);
84 cmd_send(CMD_DEBUG_PRINT_STRING,len,0,0,(byte_t*)str,len);
15c4dc5a 85}
86
87#if 0
88void DbpIntegers(int x1, int x2, int x3)
89{
902cb3c0 90 cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0);
15c4dc5a 91}
92#endif
93
94void 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);
e30c654b 102
15c4dc5a 103 DbpString(output_string);
104}
105
9455b51c 106// prints HEX & ASCII
d19929cb 107void Dbhexdump(int len, uint8_t *d, bool bAsci) {
9455b51c 108 int l=0,i;
109 char ascii[9];
d19929cb 110
9455b51c 111 while (len>0) {
112 if (len>8) l=8;
113 else l=len;
114
115 memcpy(ascii,d,l);
d19929cb 116 ascii[l]=0;
9455b51c 117
118 // filter safe ascii
d19929cb 119 for (i=0;i<l;i++)
9455b51c 120 if (ascii[i]<32 || ascii[i]>126) ascii[i]='.';
d19929cb 121
122 if (bAsci) {
123 Dbprintf("%-8s %*D",ascii,l,d," ");
124 } else {
125 Dbprintf("%*D",l,d," ");
126 }
127
9455b51c 128 len-=8;
129 d+=8;
130 }
131}
132
15c4dc5a 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//-----------------------------------------------------------------------------
138static int ReadAdc(int ch)
139{
f7e3ed82 140 uint32_t d;
15c4dc5a 141
142 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
143 AT91C_BASE_ADC->ADC_MR =
3b692427 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
15c4dc5a 159 AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch);
160
161 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
3b692427 162
15c4dc5a 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
9ca155ba 170int AvgAdc(int ch) // was static - merlok
15c4dc5a 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
182void MeasureAntennaTuning(void)
183{
2bdd68c3 184 uint8_t LF_Results[256];
9f693930 185 int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0
15c4dc5a 186 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
187
2bdd68c3 188 LED_B_ON();
15c4dc5a 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 */
d19929cb 198
7cc204bf 199 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
b014c96d 200 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
2bdd68c3 201 for (i=255; i>=19; i--) {
d19929cb 202 WDT_HIT();
15c4dc5a 203 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
204 SpinDelay(20);
3b692427 205 adcval = ((MAX_ADC_LF_VOLTAGE * AvgAdc(ADC_CHAN_LF)) >> 10);
15c4dc5a 206 if (i==95) vLf125 = adcval; // voltage at 125Khz
207 if (i==89) vLf134 = adcval; // voltage at 134Khz
208
2bdd68c3 209 LF_Results[i] = adcval>>8; // scale int to fit in byte for graphing purposes
210 if(LF_Results[i] > peak) {
15c4dc5a 211 peakv = adcval;
2bdd68c3 212 peak = LF_Results[i];
15c4dc5a 213 peakf = i;
9f693930 214 //ptr = i;
15c4dc5a 215 }
216 }
217
2bdd68c3 218 for (i=18; i >= 0; i--) LF_Results[i] = 0;
219
220 LED_A_ON();
15c4dc5a 221 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
7cc204bf 222 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 223 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
224 SpinDelay(20);
3b692427 225 vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
15c4dc5a 226
3b692427 227 cmd_send(CMD_MEASURED_ANTENNA_TUNING, vLf125 | (vLf134<<16), vHf, peakf | (peakv<<16), LF_Results, 256);
d19929cb 228 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
2bdd68c3 229 LED_A_OFF();
230 LED_B_OFF();
231 return;
15c4dc5a 232}
233
234void MeasureAntennaTuningHf(void)
235{
236 int vHf = 0; // in mV
237
238 DbpString("Measuring HF antenna, press button to exit");
239
3b692427 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
15c4dc5a 244 for (;;) {
15c4dc5a 245 SpinDelay(20);
3b692427 246 vHf = (MAX_ADC_HF_VOLTAGE * AvgAdc(ADC_CHAN_HF)) >> 10;
e30c654b 247
15c4dc5a 248 Dbprintf("%d mV",vHf);
249 if (BUTTON_PRESS()) break;
250 }
251 DbpString("cancelled");
3b692427 252
253 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
254
15c4dc5a 255}
256
257
15c4dc5a 258void ReadMem(int addr)
259{
f7e3ed82 260 const uint8_t *data = ((uint8_t *)addr);
15c4dc5a 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 */
267extern struct version_information version_information;
268/* bootrom version information is pointed to from _bootphase1_version_pointer */
0fa01ec7 269extern char *_bootphase1_version_pointer, _flash_start, _flash_end, _bootrom_start, _bootrom_end, __data_src_start__;
15c4dc5a 270void SendVersion(void)
271{
8e074056 272 char temp[USB_CMD_DATA_SIZE]; /* Limited data payload in USB packets */
273 char VersionString[USB_CMD_DATA_SIZE] = { '\0' };
e30c654b 274
275 /* Try to find the bootrom version information. Expect to find a pointer at
15c4dc5a 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 ) {
8e074056 281 strcat(VersionString, "bootrom version information appears invalid\n");
15c4dc5a 282 } else {
283 FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);
8e074056 284 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
15c4dc5a 285 }
e30c654b 286
15c4dc5a 287 FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
8e074056 288 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
e30c654b 289
e6153040 290 FpgaGatherVersion(FPGA_BITSTREAM_LF, temp, sizeof(temp));
8e074056 291 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
e6153040 292 FpgaGatherVersion(FPGA_BITSTREAM_HF, temp, sizeof(temp));
8e074056 293 strncat(VersionString, temp, sizeof(VersionString) - strlen(VersionString) - 1);
0fa01ec7 294
e6153040 295 // Send Chip ID and used flash memory
0fa01ec7 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;
8e074056 298 cmd_send(CMD_ACK, *(AT91C_DBGU_CIDR), text_and_rodata_section_size + compressed_data_section_size, 0, VersionString, strlen(VersionString));
15c4dc5a 299}
300
86a83668 301#if defined(WITH_ISO14443a_StandAlone) || defined(WITH_LF)
15c4dc5a 302
15c4dc5a 303#define OPTS 2
304
86a83668
MHS
305void StandAloneMode()
306{
307 DbpString("Stand-alone mode! No PC necessary.");
15c4dc5a 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
86a83668
MHS
319}
320
321#endif
322
323
324
325#ifdef WITH_ISO14443a_StandAlone
326void StandAloneMode14a()
327{
328 StandAloneMode();
329 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
330
15c4dc5a 331 int selected = 0;
332 int playing = 0;
86a83668
MHS
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};
15c4dc5a 337
15c4dc5a 338 LED(selected + 1, 0);
339
340 for (;;)
341 {
6e82300d 342 usb_poll();
86a83668 343 WDT_HIT();
15c4dc5a 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
86a83668 350 if (button_pressed > 0 && cardRead[selected] == 0)
15c4dc5a 351 {
352 LEDsoff();
353 LED(selected + 1, 0);
354 LED(LED_RED2, 0);
355
356 // record
86a83668 357 Dbprintf("Enabling iso14443a reader mode for [Bank: %u]...", selected);
15c4dc5a 358
359 // wait for button to be released
360 while(BUTTON_PRESS())
361 WDT_HIT();
15c4dc5a 362 /* need this delay to prevent catching some weird data */
363 SpinDelay(500);
86a83668
MHS
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);
15c4dc5a 368
86a83668
MHS
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);
15c4dc5a 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;
3fe4ff4f 401
86a83668
MHS
402 cardRead[selected] = 1;
403
404 }
405 /* MF UID clone */
406 else if (button_pressed > 0 && cardRead[selected] == 1)
3fe4ff4f 407 {
408 LEDsoff();
409 LED(selected + 1, 0);
86a83668
MHS
410 LED(LED_ORANGE, 250);
411
3fe4ff4f 412
413 // record
86a83668 414 Dbprintf("Preparing to Clone card [Bank: %x]; uid: %08x", selected, uid_1st[selected]);
3fe4ff4f 415
416 // wait for button to be released
417 while(BUTTON_PRESS())
86a83668
MHS
418 {
419 // Delay cloning until card is in place
3fe4ff4f 420 WDT_HIT();
86a83668
MHS
421 }
422 Dbprintf("Starting clone. [Bank: %u]", selected);
423 // need this delay to prevent catching some weird data
3fe4ff4f 424 SpinDelay(500);
86a83668
MHS
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;
3fe4ff4f 444
86a83668
MHS
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 }
3fe4ff4f 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;
15c4dc5a 481
86a83668 482 }
15c4dc5a 483 // Change where to record (or begin playing)
86a83668 484 else if (button_pressed && cardRead[selected])
15c4dc5a 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");
86a83668
MHS
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);
15c4dc5a 502 }
86a83668
MHS
503 //cardRead[selected] = 1;
504 Dbprintf("Done playing [Bank: %u]",selected);
15c4dc5a 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}
86a83668
MHS
521#elif WITH_LF
522// samy's sniff and repeat routine
523void SamyRun()
e46fe044 524{
86a83668
MHS
525 StandAloneMode();
526 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
e46fe044 527
86a83668 528 int high[OPTS], low[OPTS];
e46fe044
CY
529 int selected = 0;
530 int playing = 0;
86a83668 531 int cardRead = 0;
e46fe044 532
86a83668 533 // Turn on selected LED
e46fe044
CY
534 LED(selected + 1, 0);
535
536 for (;;)
537 {
538 usb_poll();
86a83668 539 WDT_HIT();
e46fe044
CY
540
541 // Was our button held down or pressed?
542 int button_pressed = BUTTON_HELD(1000);
e46fe044
CY
543 SpinDelay(300);
544
545 // Button was held for a second, begin recording
86a83668 546 if (button_pressed > 0 && cardRead == 0)
e46fe044
CY
547 {
548 LEDsoff();
549 LED(selected + 1, 0);
550 LED(LED_RED2, 0);
551
552 // record
86a83668 553 DbpString("Starting recording");
e46fe044
CY
554
555 // wait for button to be released
556 while(BUTTON_PRESS())
557 WDT_HIT();
86a83668 558
e46fe044
CY
559 /* need this delay to prevent catching some weird data */
560 SpinDelay(500);
e46fe044 561
86a83668
MHS
562 CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
563 Dbprintf("Recorded %x %x %x", selected, high[selected], low[selected]);
564
e46fe044
CY
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
86a83668 573 cardRead = 1;
e46fe044
CY
574
575 }
86a83668
MHS
576
577 else if (button_pressed > 0 && cardRead == 1)
e46fe044
CY
578 {
579 LEDsoff();
580 LED(selected + 1, 0);
86a83668 581 LED(LED_ORANGE, 0);
15c4dc5a 582
e46fe044 583 // record
86a83668 584 Dbprintf("Cloning %x %x %x", selected, high[selected], low[selected]);
e46fe044
CY
585
586 // wait for button to be released
587 while(BUTTON_PRESS())
e46fe044 588 WDT_HIT();
86a83668
MHS
589
590 /* need this delay to prevent catching some weird data */
e46fe044 591 SpinDelay(500);
e46fe044 592
86a83668
MHS
593 CopyHIDtoT55x7(high[selected], low[selected], 0, 0);
594 Dbprintf("Cloned %x %x %x", selected, high[selected], low[selected]);
595
e46fe044
CY
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;
86a83668
MHS
603
604 cardRead = 0;
e46fe044
CY
605
606 }
86a83668 607
e46fe044 608 // Change where to record (or begin playing)
86a83668 609 else if (button_pressed)
e46fe044
CY
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");
86a83668
MHS
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;
e46fe044 635 }
e46fe044
CY
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 }
86a83668 646 else
e46fe044
CY
647 while(BUTTON_PRESS())
648 WDT_HIT();
649 }
650 }
651}
86a83668 652
e46fe044 653#endif
15c4dc5a 654/*
655OBJECTIVE
656Listen and detect an external reader. Determine the best location
657for the antenna.
658
659INSTRUCTIONS:
660Inside the ListenReaderField() function, there is two mode.
661By default, when you call the function, you will enter mode 1.
662If you press the PM3 button one time, you will enter mode 2.
663If you press the PM3 button a second time, you will exit the function.
664
665DESCRIPTION OF MODE 1:
666This mode just listens for an external reader field and lights up green
667for HF and/or red for LF. This is the original mode of the detectreader
668function.
669
670DESCRIPTION OF MODE 2:
671This mode will visually represent, using the LEDs, the actual strength of the
672current compared to the maximum current detected. Basically, once you know
673what kind of external reader is present, it will help you spot the best location to place
674your antenna. You will probably not get some good results if there is a LF and a HF reader
675at the same place! :-)
676
677LIGHT SCHEME USED:
678*/
679static 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};
689static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]);
690
691void ListenReaderField(int limit)
692{
3b692427 693 int lf_av, lf_av_new, lf_baseline= 0, lf_max;
694 int hf_av, hf_av_new, hf_baseline= 0, hf_max;
15c4dc5a 695 int mode=1, display_val, display_max, i;
696
3b692427 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);
15c4dc5a 705
706 LEDsoff();
707
3b692427 708 lf_av = lf_max = AvgAdc(ADC_CHAN_LF);
15c4dc5a 709
710 if(limit != HF_ONLY) {
3b692427 711 Dbprintf("LF 125/134kHz Baseline: %dmV", (MAX_ADC_LF_VOLTAGE * lf_av) >> 10);
15c4dc5a 712 lf_baseline = lf_av;
713 }
714
3b692427 715 hf_av = hf_max = AvgAdc(ADC_CHAN_HF);
15c4dc5a 716
717 if (limit != LF_ONLY) {
3b692427 718 Dbprintf("HF 13.56MHz Baseline: %dmV", (MAX_ADC_HF_VOLTAGE * hf_av) >> 10);
15c4dc5a 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) {
3b692427 741 if(mode == 1) {
742 if (abs(lf_av - lf_baseline) > REPORT_CHANGE)
743 LED_D_ON();
744 else
745 LED_D_OFF();
15c4dc5a 746 }
e30c654b 747
3b692427 748 lf_av_new = AvgAdc(ADC_CHAN_LF);
15c4dc5a 749 // see if there's a significant change
3b692427 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);
15c4dc5a 752 lf_av = lf_av_new;
753 if (lf_av > lf_max)
754 lf_max = lf_av;
15c4dc5a 755 }
756 }
757
758 if (limit != LF_ONLY) {
759 if (mode == 1){
3b692427 760 if (abs(hf_av - hf_baseline) > REPORT_CHANGE)
761 LED_B_ON();
762 else
763 LED_B_OFF();
15c4dc5a 764 }
e30c654b 765
3b692427 766 hf_av_new = AvgAdc(ADC_CHAN_HF);
15c4dc5a 767 // see if there's a significant change
3b692427 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);
15c4dc5a 770 hf_av = hf_av_new;
771 if (hf_av > hf_max)
772 hf_max = hf_av;
15c4dc5a 773 }
774 }
e30c654b 775
15c4dc5a 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
f7e3ed82 805void UsbPacketReceived(uint8_t *packet, int len)
15c4dc5a 806{
807 UsbCommand *c = (UsbCommand *)packet;
15c4dc5a 808
902cb3c0 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
15c4dc5a 811 switch(c->cmd) {
812#ifdef WITH_LF
31abe49f
MHS
813 case CMD_SET_LF_SAMPLING_CONFIG:
814 setSamplingConfig((sample_config *) c->d.asBytes);
815 break;
15c4dc5a 816 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
1fbf8956 817 cmd_send(CMD_ACK,SampleLF(c->arg[0]),0,0,0,0);
15c4dc5a 818 break;
15c4dc5a 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;
b014c96d 822 case CMD_LF_SNOOP_RAW_ADC_SAMPLES:
31abe49f 823 cmd_send(CMD_ACK,SnoopLF(),0,0,0,0);
b014c96d 824 break;
7e67e42f 825 case CMD_HID_DEMOD_FSK:
3fe4ff4f 826 CmdHIDdemodFSK(c->arg[0], 0, 0, 1);
7e67e42f 827 break;
828 case CMD_HID_SIM_TAG:
3fe4ff4f 829 CmdHIDsimTAG(c->arg[0], c->arg[1], 1);
7e67e42f 830 break;
abd6112f 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;
872e3d4d 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:
1c611bbd 841 CopyHIDtoT55x7(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
7e67e42f 842 break;
a1f3bb12 843 case CMD_IO_DEMOD_FSK:
3fe4ff4f 844 CmdIOdemodFSK(c->arg[0], 0, 0, 1);
a1f3bb12 845 break;
3fe4ff4f 846 case CMD_IO_CLONE_TAG:
a1f3bb12 847 CopyIOtoT55x7(c->arg[0], c->arg[1], c->d.asBytes[0]);
848 break;
66707a3b 849 case CMD_EM410X_DEMOD:
850 CmdEM410xdemod(c->arg[0], 0, 0, 1);
851 break;
2d4eae76 852 case CMD_EM410X_WRITE_TAG:
853 WriteEM410x(c->arg[0], c->arg[1], c->arg[2]);
854 break;
7e67e42f 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:
31d1caa5 862 LED_A_ON();
7e67e42f 863 SimulateTagLowFrequency(c->arg[0], c->arg[1], 1);
31d1caa5 864 LED_A_OFF();
7e67e42f 865 break;
866 case CMD_LF_SIMULATE_BIDIR:
867 SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]);
868 break;
3fe4ff4f 869 case CMD_INDALA_CLONE_TAG:
2414f978 870 CopyIndala64toT55x7(c->arg[0], c->arg[1]);
871 break;
3fe4ff4f 872 case CMD_INDALA_CLONE_TAG_L:
2414f978 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;
1c611bbd 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]);
976627d5 880 cmd_send(CMD_ACK,0,0,0,0,0);
1c611bbd 881 break;
3fe4ff4f 882 case CMD_T55XX_READ_TRACE:
1c611bbd 883 T55xxReadTrace();
884 break;
3fe4ff4f 885 case CMD_PCF7931_READ:
1c611bbd 886 ReadPCF7931();
887 cmd_send(CMD_ACK,0,0,0,0,0);
1c611bbd 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;
dbf6e824
CY
895 case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
896 CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
897 break;
15c4dc5a 898#endif
899
d19929cb 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
f168b263 911
15c4dc5a 912#ifdef WITH_ISO15693
913 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
914 AcquireRawAdcSamplesIso15693();
915 break;
9455b51c 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;
15c4dc5a 931
15c4dc5a 932 case CMD_READER_ISO_15693:
933 ReaderIso15693(c->arg[0]);
934 break;
7e67e42f 935 case CMD_SIMTAG_ISO_15693:
3fe4ff4f 936 SimTagIso15693(c->arg[0], c->d.asBytes);
7e67e42f 937 break;
15c4dc5a 938#endif
939
7e67e42f 940#ifdef WITH_LEGICRF
941 case CMD_SIMULATE_TAG_LEGIC_RF:
942 LegicRfSimulate(c->arg[0], c->arg[1], c->arg[2]);
943 break;
3612a8a8 944
7e67e42f 945 case CMD_WRITER_LEGIC_RF:
946 LegicRfWriter(c->arg[1], c->arg[0]);
947 break;
3612a8a8 948
15c4dc5a 949 case CMD_READER_LEGIC_RF:
950 LegicRfReader(c->arg[0], c->arg[1]);
951 break;
15c4dc5a 952#endif
953
954#ifdef WITH_ISO14443b
15c4dc5a 955 case CMD_READ_SRI512_TAG:
51d4f6f1 956 ReadSTMemoryIso14443b(0x0F);
15c4dc5a 957 break;
7e67e42f 958 case CMD_READ_SRIX4K_TAG:
51d4f6f1 959 ReadSTMemoryIso14443b(0x7F);
7e67e42f 960 break;
132a0217 961 case CMD_SNOOP_ISO_14443B:
51d4f6f1 962 SnoopIso14443b();
7e67e42f 963 break;
132a0217 964 case CMD_SIMULATE_TAG_ISO_14443B:
51d4f6f1 965 SimulateIso14443bTag();
7e67e42f 966 break;
7cf3ef20 967 case CMD_ISO_14443B_COMMAND:
968 SendRawCommand14443B(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
969 break;
15c4dc5a 970#endif
971
972#ifdef WITH_ISO14443a
7e67e42f 973 case CMD_SNOOP_ISO_14443a:
5cd9ec01 974 SnoopIso14443a(c->arg[0]);
7e67e42f 975 break;
15c4dc5a 976 case CMD_READER_ISO_14443a:
902cb3c0 977 ReaderIso14443a(c);
15c4dc5a 978 break;
7e67e42f 979 case CMD_SIMULATE_TAG_ISO_14443a:
28afbd2b 980 SimulateIso14443aTag(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes); // ## Simulate iso14443a tag - pass tag type & UID
7e67e42f 981 break;
3fe4ff4f 982
5acd09bd 983 case CMD_EPA_PACE_COLLECT_NONCE:
902cb3c0 984 EPA_PACE_Collect_Nonce(c);
5acd09bd 985 break;
3bb07d96
FM
986 case CMD_EPA_PACE_REPLAY:
987 EPA_PACE_Replay(c);
988 break;
7e67e42f 989
15c4dc5a 990 case CMD_READER_MIFARE:
f168b263 991 ReaderMifare(c->arg[0]);
15c4dc5a 992 break;
20f9a2a1
M
993 case CMD_MIFARE_READBL:
994 MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
995 break;
981bd429 996 case CMD_MIFAREU_READBL:
f168b263 997 MifareUReadBlock(c->arg[0],c->arg[1], c->d.asBytes);
981bd429 998 break;
8258f409 999 case CMD_MIFAREUC_AUTH:
1000 MifareUC_Auth(c->arg[0],c->d.asBytes);
a631936e 1001 break;
981bd429 1002 case CMD_MIFAREU_READCARD:
75377d29 1003 MifareUReadCard(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
117d9ec2 1004 break;
f168b263 1005 case CMD_MIFAREUC_SETPWD:
1006 MifareUSetPwd(c->arg[0], c->d.asBytes);
1007 break;
20f9a2a1
M
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;
4973f23d 1014 //case CMD_MIFAREU_WRITEBL_COMPAT:
1015 //MifareUWriteBlockCompat(c->arg[0], c->d.asBytes);
1016 //break;
981bd429 1017 case CMD_MIFAREU_WRITEBL:
4973f23d 1018 MifareUWriteBlock(c->arg[0], c->arg[1], c->d.asBytes);
f168b263 1019 break;
20f9a2a1
M
1020 case CMD_MIFARE_NESTED:
1021 MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
f397b5cc
M
1022 break;
1023 case CMD_MIFARE_CHKKEYS:
1024 MifareChkKeys(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
20f9a2a1
M
1025 break;
1026 case CMD_SIMULATE_MIFARE_CARD:
1027 Mifare1ksim(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1028 break;
8556b852
M
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);
0675f200
M
1045 break;
1046
1047 // Work with "magic Chinese" card
3fe4ff4f 1048 case CMD_MIFARE_CSETBLOCK:
0675f200 1049 MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
545a1f38 1050 break;
3fe4ff4f 1051 case CMD_MIFARE_CGETBLOCK:
545a1f38 1052 MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
8556b852 1053 break;
3fe4ff4f 1054 case CMD_MIFARE_CIDENT:
1055 MifareCIdent();
1056 break;
b62a5a84
M
1057
1058 // mifare sniffer
1059 case CMD_MIFARE_SNIFFER:
5cd9ec01 1060 SniffMifare(c->arg[0]);
b62a5a84 1061 break;
a631936e 1062
20f9a2a1
M
1063#endif
1064
7e67e42f 1065#ifdef WITH_ICLASS
cee5a30d 1066 // Makes use of ISO14443a FPGA Firmware
1067 case CMD_SNOOP_ICLASS:
1068 SnoopIClass();
1069 break;
1e262141 1070 case CMD_SIMULATE_TAG_ICLASS:
ff7bb4ef 1071 SimulateIClass(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
1e262141 1072 break;
1073 case CMD_READER_ICLASS:
1074 ReaderIClass(c->arg[0]);
1075 break;
c3963755 1076 case CMD_READER_ICLASS_REPLAY:
fecd8202 1077 ReaderIClass_Replay(c->arg[0], c->d.asBytes);
c3963755 1078 break;
e80aeb96
MHS
1079 case CMD_ICLASS_EML_MEMSET:
1080 emlSet(c->d.asBytes,c->arg[0], c->arg[1]);
1081 break;
cee5a30d 1082#endif
1083
7e67e42f 1084 case CMD_BUFF_CLEAR:
117d9ec2 1085 BigBuf_Clear();
15c4dc5a 1086 break;
15c4dc5a 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
15c4dc5a 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
1c611bbd 1106 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
902cb3c0 1107
1c611bbd 1108 LED_B_ON();
117d9ec2 1109 uint8_t *BigBuf = BigBuf_get_addr();
1c611bbd 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);
3000dc4e 1112 cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,BigBuf_get_traceLen(),BigBuf+c->arg[0]+i,len);
1c611bbd 1113 }
1114 // Trigger a finish downloading signal with an ACK frame
3000dc4e 1115 cmd_send(CMD_ACK,1,0,BigBuf_get_traceLen(),getSamplingConfig(),sizeof(sample_config));
d3b1f4e4 1116 LED_B_OFF();
1c611bbd 1117 break;
15c4dc5a 1118
1119 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
117d9ec2 1120 uint8_t *b = BigBuf_get_addr();
3fe4ff4f 1121 memcpy(b+c->arg[0], c->d.asBytes, USB_CMD_DATA_SIZE);
1c611bbd 1122 cmd_send(CMD_ACK,0,0,0,0,0);
1123 break;
1124 }
15c4dc5a 1125 case CMD_READ_MEM:
1126 ReadMem(c->arg[0]);
1127 break;
1128
1129 case CMD_SET_LF_DIVISOR:
7cc204bf 1130 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
15c4dc5a 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
15c4dc5a 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:
1c611bbd 1157 case CMD_HARDWARE_RESET:
1158 usb_disable();
15c4dc5a 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 }
1c611bbd 1165 break;
15c4dc5a 1166
1c611bbd 1167 case CMD_START_FLASH:
15c4dc5a 1168 if(common_area.flags.bootrom_present) {
1169 common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
1170 }
1c611bbd 1171 usb_disable();
15c4dc5a 1172 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
1173 for(;;);
1c611bbd 1174 break;
e30c654b 1175
15c4dc5a 1176 case CMD_DEVICE_INFO: {
902cb3c0 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;
1c611bbd 1179 cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0);
1180 break;
1181 }
1182 default:
15c4dc5a 1183 Dbprintf("%s: 0x%04x","unknown command:",c->cmd);
1c611bbd 1184 break;
15c4dc5a 1185 }
1186}
1187
1188void __attribute__((noreturn)) AppMain(void)
1189{
1190 SpinDelay(100);
9e8255d4 1191 clear_trace();
15c4dc5a 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
3fe4ff4f 1205 // Init USB device
902cb3c0 1206 usb_enable();
15c4dc5a 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.
7cc204bf 1223 // (the HF version by default)
1224 FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
15c4dc5a 1225
9ca155ba 1226 StartTickCount();
902cb3c0 1227
15c4dc5a 1228#ifdef WITH_LCD
15c4dc5a 1229 LCDInit();
15c4dc5a 1230#endif
1231
902cb3c0 1232 byte_t rx[sizeof(UsbCommand)];
1233 size_t rx_len;
1234
15c4dc5a 1235 for(;;) {
902cb3c0 1236 if (usb_poll()) {
1237 rx_len = usb_read(rx,sizeof(UsbCommand));
1238 if (rx_len) {
1239 UsbPacketReceived(rx,rx_len);
1240 }
1241 }
15c4dc5a 1242 WDT_HIT();
1243
1244#ifdef WITH_LF
e46fe044 1245#ifndef WITH_ISO14443a_StandAlone
15c4dc5a 1246 if (BUTTON_HELD(1000) > 0)
1247 SamyRun();
e46fe044
CY
1248#endif
1249#endif
1250#ifdef WITH_ISO14443a
1251#ifdef WITH_ISO14443a_StandAlone
1252 if (BUTTON_HELD(1000) > 0)
1253 StandAloneMode14a();
1254#endif
15c4dc5a 1255#endif
1256 }
1257}
Impressum, Datenschutz