]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/appmain.c
tryout.... changed to 64-bit command arguments in stead of 32-bit
[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"
21
22#include <stdarg.h>
f7e3ed82 23
15c4dc5a 24#include "legicrf.h"
d19929cb 25#include <hitag2.h>
f7e3ed82 26
15c4dc5a 27#ifdef WITH_LCD
902cb3c0 28 #include "LCD.h"
15c4dc5a 29#endif
30
15c4dc5a 31#define abs(x) ( ((x)<0) ? -(x) : (x) )
32
33//=============================================================================
34// A buffer where we can queue things up to be sent through the FPGA, for
35// any purpose (fake tag, as reader, whatever). We go MSB first, since that
36// is the order in which they go out on the wire.
37//=============================================================================
38
f7e3ed82 39uint8_t ToSend[512];
15c4dc5a 40int ToSendMax;
41static int ToSendBit;
42struct common_area common_area __attribute__((section(".commonarea")));
43
44void BufferClear(void)
45{
46 memset(BigBuf,0,sizeof(BigBuf));
47 Dbprintf("Buffer cleared (%i bytes)",sizeof(BigBuf));
48}
49
50void ToSendReset(void)
51{
52 ToSendMax = -1;
53 ToSendBit = 8;
54}
55
56void ToSendStuffBit(int b)
57{
58 if(ToSendBit >= 8) {
59 ToSendMax++;
60 ToSend[ToSendMax] = 0;
61 ToSendBit = 0;
62 }
63
64 if(b) {
65 ToSend[ToSendMax] |= (1 << (7 - ToSendBit));
66 }
67
68 ToSendBit++;
69
70 if(ToSendBit >= sizeof(ToSend)) {
71 ToSendBit = 0;
72 DbpString("ToSendStuffBit overflowed!");
73 }
74}
75
76//=============================================================================
77// Debug print functions, to go out over USB, to the usual PC-side client.
78//=============================================================================
79
80void DbpString(char *str)
81{
902cb3c0 82 cmd_send(CMD_DEBUG_PRINT_STRING,strlen(str),0,0,(byte_t*)str,strlen(str));
83// /* this holds up stuff unless we're connected to usb */
84// if (!UsbConnected())
85// return;
86//
87// UsbCommand c;
88// c.cmd = CMD_DEBUG_PRINT_STRING;
89// c.arg[0] = strlen(str);
90// if(c.arg[0] > sizeof(c.d.asBytes)) {
91// c.arg[0] = sizeof(c.d.asBytes);
92// }
93// memcpy(c.d.asBytes, str, c.arg[0]);
94//
95// UsbSendPacket((uint8_t *)&c, sizeof(c));
96// // TODO fix USB so stupid things like this aren't req'd
97// SpinDelay(50);
15c4dc5a 98}
99
100#if 0
101void DbpIntegers(int x1, int x2, int x3)
102{
902cb3c0 103 cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0);
104// /* this holds up stuff unless we're connected to usb */
105// if (!UsbConnected())
106// return;
107//
108// UsbCommand c;
109// c.cmd = CMD_DEBUG_PRINT_INTEGERS;
110// c.arg[0] = x1;
111// c.arg[1] = x2;
112// c.arg[2] = x3;
113//
114// UsbSendPacket((uint8_t *)&c, sizeof(c));
115// // XXX
116// SpinDelay(50);
15c4dc5a 117}
118#endif
119
120void Dbprintf(const char *fmt, ...) {
121// should probably limit size here; oh well, let's just use a big buffer
122 char output_string[128];
123 va_list ap;
124
125 va_start(ap, fmt);
126 kvsprintf(fmt, output_string, 10, ap);
127 va_end(ap);
e30c654b 128
15c4dc5a 129 DbpString(output_string);
130}
131
9455b51c 132// prints HEX & ASCII
d19929cb 133void Dbhexdump(int len, uint8_t *d, bool bAsci) {
9455b51c 134 int l=0,i;
135 char ascii[9];
d19929cb 136
9455b51c 137 while (len>0) {
138 if (len>8) l=8;
139 else l=len;
140
141 memcpy(ascii,d,l);
d19929cb 142 ascii[l]=0;
9455b51c 143
144 // filter safe ascii
d19929cb 145 for (i=0;i<l;i++)
9455b51c 146 if (ascii[i]<32 || ascii[i]>126) ascii[i]='.';
d19929cb 147
148 if (bAsci) {
149 Dbprintf("%-8s %*D",ascii,l,d," ");
150 } else {
151 Dbprintf("%*D",l,d," ");
152 }
153
9455b51c 154 len-=8;
155 d+=8;
156 }
157}
158
15c4dc5a 159//-----------------------------------------------------------------------------
160// Read an ADC channel and block till it completes, then return the result
161// in ADC units (0 to 1023). Also a routine to average 32 samples and
162// return that.
163//-----------------------------------------------------------------------------
164static int ReadAdc(int ch)
165{
f7e3ed82 166 uint32_t d;
15c4dc5a 167
168 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;
169 AT91C_BASE_ADC->ADC_MR =
170 ADC_MODE_PRESCALE(32) |
171 ADC_MODE_STARTUP_TIME(16) |
172 ADC_MODE_SAMPLE_HOLD_TIME(8);
173 AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch);
174
175 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;
176 while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch)))
177 ;
178 d = AT91C_BASE_ADC->ADC_CDR[ch];
179
180 return d;
181}
182
9ca155ba 183int AvgAdc(int ch) // was static - merlok
15c4dc5a 184{
185 int i;
186 int a = 0;
187
188 for(i = 0; i < 32; i++) {
189 a += ReadAdc(ch);
190 }
191
192 return (a + 15) >> 5;
193}
194
195void MeasureAntennaTuning(void)
196{
d19929cb 197 uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET;
9f693930 198 int i, adcval = 0, peak = 0, peakv = 0, peakf = 0; //ptr = 0
15c4dc5a 199 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
200
902cb3c0 201// UsbCommand c;
15c4dc5a 202
d19929cb 203 LED_B_ON();
204 DbpString("Measuring antenna characteristics, please wait...");
205 memset(dest,0,sizeof(FREE_BUFFER_SIZE));
15c4dc5a 206
207/*
208 * Sweeps the useful LF range of the proxmark from
209 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
210 * read the voltage in the antenna, the result left
211 * in the buffer is a graph which should clearly show
212 * the resonating frequency of your LF antenna
213 * ( hopefully around 95 if it is tuned to 125kHz!)
214 */
d19929cb 215
15c4dc5a 216 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
217 for (i=255; i>19; i--) {
d19929cb 218 WDT_HIT();
15c4dc5a 219 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
220 SpinDelay(20);
221 // Vref = 3.3V, and a 10000:240 voltage divider on the input
222 // can measure voltages up to 137500 mV
223 adcval = ((137500 * AvgAdc(ADC_CHAN_LF)) >> 10);
224 if (i==95) vLf125 = adcval; // voltage at 125Khz
225 if (i==89) vLf134 = adcval; // voltage at 134Khz
226
227 dest[i] = adcval>>8; // scale int to fit in byte for graphing purposes
228 if(dest[i] > peak) {
229 peakv = adcval;
230 peak = dest[i];
231 peakf = i;
9f693930 232 //ptr = i;
15c4dc5a 233 }
234 }
235
d19929cb 236 LED_A_ON();
15c4dc5a 237 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
238 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
239 SpinDelay(20);
240 // Vref = 3300mV, and an 10:1 voltage divider on the input
241 // can measure voltages up to 33000 mV
242 vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
243
902cb3c0 244// c.cmd = CMD_MEASURED_ANTENNA_TUNING;
245// c.arg[0] = (vLf125 << 0) | (vLf134 << 16);
246// c.arg[1] = vHf;
247// c.arg[2] = peakf | (peakv << 16);
d19929cb 248
249 DbpString("Measuring complete, sending report back to host");
902cb3c0 250 cmd_send(CMD_MEASURED_ANTENNA_TUNING,vLf125|(vLf134<<16),vHf,peakf|(peakv<<16),0,0);
251// UsbSendPacket((uint8_t *)&c, sizeof(c));
d19929cb 252 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
253 LED_A_OFF();
254 LED_B_OFF();
255 return;
15c4dc5a 256}
257
258void MeasureAntennaTuningHf(void)
259{
260 int vHf = 0; // in mV
261
262 DbpString("Measuring HF antenna, press button to exit");
263
264 for (;;) {
265 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
266 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
267 SpinDelay(20);
268 // Vref = 3300mV, and an 10:1 voltage divider on the input
269 // can measure voltages up to 33000 mV
270 vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
e30c654b 271
15c4dc5a 272 Dbprintf("%d mV",vHf);
273 if (BUTTON_PRESS()) break;
274 }
275 DbpString("cancelled");
276}
277
278
279void SimulateTagHfListen(void)
280{
d19929cb 281 uint8_t *dest = (uint8_t *)BigBuf+FREE_BUFFER_OFFSET;
f7e3ed82 282 uint8_t v = 0;
15c4dc5a 283 int i;
284 int p = 0;
285
286 // We're using this mode just so that I can test it out; the simulated
287 // tag mode would work just as well and be simpler.
288 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP);
289
290 // We need to listen to the high-frequency, peak-detected path.
291 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
292
293 FpgaSetupSsc();
294
295 i = 0;
296 for(;;) {
297 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
298 AT91C_BASE_SSC->SSC_THR = 0xff;
299 }
300 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
f7e3ed82 301 uint8_t r = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
15c4dc5a 302
303 v <<= 1;
304 if(r & 1) {
305 v |= 1;
306 }
307 p++;
308
309 if(p >= 8) {
310 dest[i] = v;
311 v = 0;
312 p = 0;
313 i++;
314
d19929cb 315 if(i >= FREE_BUFFER_SIZE) {
15c4dc5a 316 break;
317 }
318 }
319 }
320 }
321 DbpString("simulate tag (now type bitsamples)");
322}
323
324void ReadMem(int addr)
325{
f7e3ed82 326 const uint8_t *data = ((uint8_t *)addr);
15c4dc5a 327
328 Dbprintf("%x: %02x %02x %02x %02x %02x %02x %02x %02x",
329 addr, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]);
330}
331
332/* osimage version information is linked in */
333extern struct version_information version_information;
334/* bootrom version information is pointed to from _bootphase1_version_pointer */
335extern char *_bootphase1_version_pointer, _flash_start, _flash_end;
336void SendVersion(void)
337{
338 char temp[48]; /* Limited data payload in USB packets */
339 DbpString("Prox/RFID mark3 RFID instrument");
e30c654b 340
341 /* Try to find the bootrom version information. Expect to find a pointer at
15c4dc5a 342 * symbol _bootphase1_version_pointer, perform slight sanity checks on the
343 * pointer, then use it.
344 */
345 char *bootrom_version = *(char**)&_bootphase1_version_pointer;
346 if( bootrom_version < &_flash_start || bootrom_version >= &_flash_end ) {
347 DbpString("bootrom version information appears invalid");
348 } else {
349 FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);
350 DbpString(temp);
351 }
e30c654b 352
15c4dc5a 353 FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);
354 DbpString(temp);
e30c654b 355
15c4dc5a 356 FpgaGatherVersion(temp, sizeof(temp));
357 DbpString(temp);
358}
359
360#ifdef WITH_LF
361// samy's sniff and repeat routine
362void SamyRun()
363{
364 DbpString("Stand-alone mode! No PC necessary.");
365
366 // 3 possible options? no just 2 for now
367#define OPTS 2
368
369 int high[OPTS], low[OPTS];
370
371 // Oooh pretty -- notify user we're in elite samy mode now
372 LED(LED_RED, 200);
373 LED(LED_ORANGE, 200);
374 LED(LED_GREEN, 200);
375 LED(LED_ORANGE, 200);
376 LED(LED_RED, 200);
377 LED(LED_ORANGE, 200);
378 LED(LED_GREEN, 200);
379 LED(LED_ORANGE, 200);
380 LED(LED_RED, 200);
381
382 int selected = 0;
383 int playing = 0;
384
385 // Turn on selected LED
386 LED(selected + 1, 0);
387
388 for (;;)
389 {
6e82300d 390// UsbPoll(FALSE);
391 usb_poll();
392 WDT_HIT();
15c4dc5a 393
394 // Was our button held down or pressed?
395 int button_pressed = BUTTON_HELD(1000);
396 SpinDelay(300);
397
398 // Button was held for a second, begin recording
399 if (button_pressed > 0)
400 {
401 LEDsoff();
402 LED(selected + 1, 0);
403 LED(LED_RED2, 0);
404
405 // record
406 DbpString("Starting recording");
407
408 // wait for button to be released
409 while(BUTTON_PRESS())
410 WDT_HIT();
411
412 /* need this delay to prevent catching some weird data */
413 SpinDelay(500);
414
415 CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
416 Dbprintf("Recorded %x %x %x", selected, high[selected], low[selected]);
417
418 LEDsoff();
419 LED(selected + 1, 0);
420 // Finished recording
421
422 // If we were previously playing, set playing off
423 // so next button push begins playing what we recorded
424 playing = 0;
425 }
426
427 // Change where to record (or begin playing)
428 else if (button_pressed)
429 {
430 // Next option if we were previously playing
431 if (playing)
432 selected = (selected + 1) % OPTS;
433 playing = !playing;
434
435 LEDsoff();
436 LED(selected + 1, 0);
437
438 // Begin transmitting
439 if (playing)
440 {
441 LED(LED_GREEN, 0);
442 DbpString("Playing");
443 // wait for button to be released
444 while(BUTTON_PRESS())
445 WDT_HIT();
446 Dbprintf("%x %x %x", selected, high[selected], low[selected]);
447 CmdHIDsimTAG(high[selected], low[selected], 0);
448 DbpString("Done playing");
449 if (BUTTON_HELD(1000) > 0)
450 {
451 DbpString("Exiting");
452 LEDsoff();
453 return;
454 }
455
456 /* We pressed a button so ignore it here with a delay */
457 SpinDelay(300);
458
459 // when done, we're done playing, move to next option
460 selected = (selected + 1) % OPTS;
461 playing = !playing;
462 LEDsoff();
463 LED(selected + 1, 0);
464 }
465 else
466 while(BUTTON_PRESS())
467 WDT_HIT();
468 }
469 }
470}
471#endif
472
473/*
474OBJECTIVE
475Listen and detect an external reader. Determine the best location
476for the antenna.
477
478INSTRUCTIONS:
479Inside the ListenReaderField() function, there is two mode.
480By default, when you call the function, you will enter mode 1.
481If you press the PM3 button one time, you will enter mode 2.
482If you press the PM3 button a second time, you will exit the function.
483
484DESCRIPTION OF MODE 1:
485This mode just listens for an external reader field and lights up green
486for HF and/or red for LF. This is the original mode of the detectreader
487function.
488
489DESCRIPTION OF MODE 2:
490This mode will visually represent, using the LEDs, the actual strength of the
491current compared to the maximum current detected. Basically, once you know
492what kind of external reader is present, it will help you spot the best location to place
493your antenna. You will probably not get some good results if there is a LF and a HF reader
494at the same place! :-)
495
496LIGHT SCHEME USED:
497*/
498static const char LIGHT_SCHEME[] = {
499 0x0, /* ---- | No field detected */
500 0x1, /* X--- | 14% of maximum current detected */
501 0x2, /* -X-- | 29% of maximum current detected */
502 0x4, /* --X- | 43% of maximum current detected */
503 0x8, /* ---X | 57% of maximum current detected */
504 0xC, /* --XX | 71% of maximum current detected */
505 0xE, /* -XXX | 86% of maximum current detected */
506 0xF, /* XXXX | 100% of maximum current detected */
507};
508static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]);
509
510void ListenReaderField(int limit)
511{
512 int lf_av, lf_av_new, lf_baseline= 0, lf_count= 0, lf_max;
513 int hf_av, hf_av_new, hf_baseline= 0, hf_count= 0, hf_max;
514 int mode=1, display_val, display_max, i;
515
516#define LF_ONLY 1
517#define HF_ONLY 2
518
519 LEDsoff();
520
521 lf_av=lf_max=ReadAdc(ADC_CHAN_LF);
522
523 if(limit != HF_ONLY) {
524 Dbprintf("LF 125/134 Baseline: %d", lf_av);
525 lf_baseline = lf_av;
526 }
527
528 hf_av=hf_max=ReadAdc(ADC_CHAN_HF);
529
530 if (limit != LF_ONLY) {
531 Dbprintf("HF 13.56 Baseline: %d", hf_av);
532 hf_baseline = hf_av;
533 }
534
535 for(;;) {
536 if (BUTTON_PRESS()) {
537 SpinDelay(500);
538 switch (mode) {
539 case 1:
540 mode=2;
541 DbpString("Signal Strength Mode");
542 break;
543 case 2:
544 default:
545 DbpString("Stopped");
546 LEDsoff();
547 return;
548 break;
549 }
550 }
551 WDT_HIT();
552
553 if (limit != HF_ONLY) {
554 if(mode==1) {
555 if (abs(lf_av - lf_baseline) > 10) LED_D_ON();
556 else LED_D_OFF();
557 }
e30c654b 558
15c4dc5a 559 ++lf_count;
560 lf_av_new= ReadAdc(ADC_CHAN_LF);
561 // see if there's a significant change
562 if(abs(lf_av - lf_av_new) > 10) {
563 Dbprintf("LF 125/134 Field Change: %x %x %x", lf_av, lf_av_new, lf_count);
564 lf_av = lf_av_new;
565 if (lf_av > lf_max)
566 lf_max = lf_av;
567 lf_count= 0;
568 }
569 }
570
571 if (limit != LF_ONLY) {
572 if (mode == 1){
573 if (abs(hf_av - hf_baseline) > 10) LED_B_ON();
574 else LED_B_OFF();
575 }
e30c654b 576
15c4dc5a 577 ++hf_count;
578 hf_av_new= ReadAdc(ADC_CHAN_HF);
579 // see if there's a significant change
580 if(abs(hf_av - hf_av_new) > 10) {
581 Dbprintf("HF 13.56 Field Change: %x %x %x", hf_av, hf_av_new, hf_count);
582 hf_av = hf_av_new;
583 if (hf_av > hf_max)
584 hf_max = hf_av;
585 hf_count= 0;
586 }
587 }
e30c654b 588
15c4dc5a 589 if(mode == 2) {
590 if (limit == LF_ONLY) {
591 display_val = lf_av;
592 display_max = lf_max;
593 } else if (limit == HF_ONLY) {
594 display_val = hf_av;
595 display_max = hf_max;
596 } else { /* Pick one at random */
597 if( (hf_max - hf_baseline) > (lf_max - lf_baseline) ) {
598 display_val = hf_av;
599 display_max = hf_max;
600 } else {
601 display_val = lf_av;
602 display_max = lf_max;
603 }
604 }
605 for (i=0; i<LIGHT_LEN; i++) {
606 if (display_val >= ((display_max/LIGHT_LEN)*i) && display_val <= ((display_max/LIGHT_LEN)*(i+1))) {
607 if (LIGHT_SCHEME[i] & 0x1) LED_C_ON(); else LED_C_OFF();
608 if (LIGHT_SCHEME[i] & 0x2) LED_A_ON(); else LED_A_OFF();
609 if (LIGHT_SCHEME[i] & 0x4) LED_B_ON(); else LED_B_OFF();
610 if (LIGHT_SCHEME[i] & 0x8) LED_D_ON(); else LED_D_OFF();
611 break;
612 }
613 }
614 }
615 }
616}
617
f7e3ed82 618void UsbPacketReceived(uint8_t *packet, int len)
15c4dc5a 619{
620 UsbCommand *c = (UsbCommand *)packet;
15c4dc5a 621
902cb3c0 622// 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]);
623
15c4dc5a 624 switch(c->cmd) {
625#ifdef WITH_LF
626 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
627 AcquireRawAdcSamples125k(c->arg[0]);
902cb3c0 628 cmd_send(CMD_ACK,0,0,0,0,0);
15c4dc5a 629 break;
15c4dc5a 630 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
631 ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
632 break;
7e67e42f 633 case CMD_HID_DEMOD_FSK:
2414f978 634 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
7e67e42f 635 break;
636 case CMD_HID_SIM_TAG:
637 CmdHIDsimTAG(c->arg[0], c->arg[1], 1); // Simulate HID tag by ID
638 break;
639 case CMD_HID_CLONE_TAG:
2414f978 640 CopyHIDtoT55x7(c->arg[0], c->arg[1]); // Clone HID tag by ID to T55x7
7e67e42f 641 break;
2d4eae76 642 case CMD_EM410X_WRITE_TAG:
643 WriteEM410x(c->arg[0], c->arg[1], c->arg[2]);
644 break;
7e67e42f 645 case CMD_READ_TI_TYPE:
646 ReadTItag();
647 break;
648 case CMD_WRITE_TI_TYPE:
649 WriteTItag(c->arg[0],c->arg[1],c->arg[2]);
650 break;
651 case CMD_SIMULATE_TAG_125K:
652 LED_A_ON();
653 SimulateTagLowFrequency(c->arg[0], c->arg[1], 1);
654 LED_A_OFF();
655 break;
656 case CMD_LF_SIMULATE_BIDIR:
657 SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]);
658 break;
2414f978 659 case CMD_INDALA_CLONE_TAG: // Clone Indala 64-bit tag by UID to T55x7
660 CopyIndala64toT55x7(c->arg[0], c->arg[1]);
661 break;
662 case CMD_INDALA_CLONE_TAG_L: // Clone Indala 224-bit tag by UID to T55x7
663 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]);
664 break;
15c4dc5a 665#endif
666
d19929cb 667#ifdef WITH_HITAG
668 case CMD_SNOOP_HITAG: // Eavesdrop Hitag tag, args = type
669 SnoopHitag(c->arg[0]);
670 break;
671 case CMD_SIMULATE_HITAG: // Simulate Hitag tag, args = memory content
672 SimulateHitagTag((bool)c->arg[0],(byte_t*)c->d.asBytes);
673 break;
674 case CMD_READER_HITAG: // Reader for Hitag tags, args = type and function
675 ReaderHitag((hitag_function)c->arg[0],(hitag_data*)c->d.asBytes);
676 break;
677#endif
678
15c4dc5a 679#ifdef WITH_ISO15693
680 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
681 AcquireRawAdcSamplesIso15693();
682 break;
9455b51c 683 case CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693:
684 RecordRawAdcSamplesIso15693();
685 break;
686
687 case CMD_ISO_15693_COMMAND:
688 DirectTag15693Command(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);
689 break;
690
691 case CMD_ISO_15693_FIND_AFI:
692 BruteforceIso15693Afi(c->arg[0]);
693 break;
694
695 case CMD_ISO_15693_DEBUG:
696 SetDebugIso15693(c->arg[0]);
697 break;
15c4dc5a 698
15c4dc5a 699 case CMD_READER_ISO_15693:
700 ReaderIso15693(c->arg[0]);
701 break;
7e67e42f 702 case CMD_SIMTAG_ISO_15693:
703 SimTagIso15693(c->arg[0]);
704 break;
15c4dc5a 705#endif
706
7e67e42f 707#ifdef WITH_LEGICRF
708 case CMD_SIMULATE_TAG_LEGIC_RF:
709 LegicRfSimulate(c->arg[0], c->arg[1], c->arg[2]);
710 break;
3612a8a8 711
7e67e42f 712 case CMD_WRITER_LEGIC_RF:
713 LegicRfWriter(c->arg[1], c->arg[0]);
714 break;
3612a8a8 715
15c4dc5a 716 case CMD_READER_LEGIC_RF:
717 LegicRfReader(c->arg[0], c->arg[1]);
718 break;
15c4dc5a 719#endif
720
721#ifdef WITH_ISO14443b
722 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:
723 AcquireRawAdcSamplesIso14443(c->arg[0]);
724 break;
15c4dc5a 725 case CMD_READ_SRI512_TAG:
726 ReadSRI512Iso14443(c->arg[0]);
727 break;
7e67e42f 728 case CMD_READ_SRIX4K_TAG:
729 ReadSRIX4KIso14443(c->arg[0]);
730 break;
731 case CMD_SNOOP_ISO_14443:
732 SnoopIso14443();
733 break;
734 case CMD_SIMULATE_TAG_ISO_14443:
735 SimulateIso14443Tag();
736 break;
15c4dc5a 737#endif
738
739#ifdef WITH_ISO14443a
7e67e42f 740 case CMD_SNOOP_ISO_14443a:
5cd9ec01 741 SnoopIso14443a(c->arg[0]);
7e67e42f 742 break;
15c4dc5a 743 case CMD_READER_ISO_14443a:
902cb3c0 744 ReaderIso14443a(c);
15c4dc5a 745 break;
7e67e42f 746 case CMD_SIMULATE_TAG_ISO_14443a:
81cd0474 747 SimulateIso14443aTag(c->arg[0], c->arg[1], c->arg[2]); // ## Simulate iso14443a tag - pass tag type & UID
7e67e42f 748 break;
5acd09bd 749 case CMD_EPA_PACE_COLLECT_NONCE:
902cb3c0 750 EPA_PACE_Collect_Nonce(c);
5acd09bd 751 break;
7e67e42f 752
15c4dc5a 753 case CMD_READER_MIFARE:
754 ReaderMifare(c->arg[0]);
755 break;
20f9a2a1
M
756 case CMD_MIFARE_READBL:
757 MifareReadBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
758 break;
759 case CMD_MIFARE_READSC:
760 MifareReadSector(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
761 break;
762 case CMD_MIFARE_WRITEBL:
763 MifareWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
764 break;
765 case CMD_MIFARE_NESTED:
766 MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
f397b5cc
M
767 break;
768 case CMD_MIFARE_CHKKEYS:
769 MifareChkKeys(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
20f9a2a1
M
770 break;
771 case CMD_SIMULATE_MIFARE_CARD:
772 Mifare1ksim(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
773 break;
8556b852
M
774
775 // emulator
776 case CMD_MIFARE_SET_DBGMODE:
777 MifareSetDbgLvl(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
778 break;
779 case CMD_MIFARE_EML_MEMCLR:
780 MifareEMemClr(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
781 break;
782 case CMD_MIFARE_EML_MEMSET:
783 MifareEMemSet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
784 break;
785 case CMD_MIFARE_EML_MEMGET:
786 MifareEMemGet(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
787 break;
788 case CMD_MIFARE_EML_CARDLOAD:
789 MifareECardLoad(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
0675f200
M
790 break;
791
792 // Work with "magic Chinese" card
793 case CMD_MIFARE_EML_CSETBLOCK:
794 MifareCSetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
545a1f38
M
795 break;
796 case CMD_MIFARE_EML_CGETBLOCK:
797 MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
8556b852 798 break;
b62a5a84
M
799
800 // mifare sniffer
801 case CMD_MIFARE_SNIFFER:
5cd9ec01 802 SniffMifare(c->arg[0]);
b62a5a84 803 break;
20f9a2a1
M
804#endif
805
7e67e42f 806#ifdef WITH_ICLASS
cee5a30d 807 // Makes use of ISO14443a FPGA Firmware
808 case CMD_SNOOP_ICLASS:
809 SnoopIClass();
810 break;
1e262141 811 case CMD_SIMULATE_TAG_ICLASS:
812 SimulateIClass(c->arg[0], c->d.asBytes);
813 break;
814 case CMD_READER_ICLASS:
815 ReaderIClass(c->arg[0]);
816 break;
cee5a30d 817#endif
818
15c4dc5a 819 case CMD_SIMULATE_TAG_HF_LISTEN:
820 SimulateTagHfListen();
821 break;
822
7e67e42f 823 case CMD_BUFF_CLEAR:
824 BufferClear();
15c4dc5a 825 break;
15c4dc5a 826
827 case CMD_MEASURE_ANTENNA_TUNING:
828 MeasureAntennaTuning();
829 break;
830
831 case CMD_MEASURE_ANTENNA_TUNING_HF:
832 MeasureAntennaTuningHf();
833 break;
834
835 case CMD_LISTEN_READER_FIELD:
836 ListenReaderField(c->arg[0]);
837 break;
838
15c4dc5a 839 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
840 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
841 SpinDelay(200);
842 LED_D_OFF(); // LED D indicates field ON or OFF
843 break;
844
15c4dc5a 845 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: {
902cb3c0 846// UsbCommand n;
847// if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {
848// n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;
849// } else {
850// n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;
851// }
852// n.arg[0] = c->arg[0];
853 // memcpy(n.d.asBytes, BigBuf+c->arg[0], 48); // 12*sizeof(uint32_t)
854 // LED_B_ON();
855 // usb_write((uint8_t *)&n, sizeof(n));
856 // UsbSendPacket((uint8_t *)&n, sizeof(n));
857 // LED_B_OFF();
858
859 LED_B_ON();
860 for(size_t i=0; i<c->arg[1]; i += USB_CMD_DATA_SIZE) {
861 size_t len = MIN((c->arg[1] - i),USB_CMD_DATA_SIZE);
862 cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,i,len,0,((byte_t*)BigBuf)+c->arg[0]+i,len);
863 }
864 // Trigger a finish downloading signal with an ACK frame
865 cmd_send(CMD_ACK,0,0,0,0,0);
d3b1f4e4 866 LED_B_OFF();
d19929cb 867 } break;
15c4dc5a 868
869 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
f7e3ed82 870 uint8_t *b = (uint8_t *)BigBuf;
15c4dc5a 871 memcpy(b+c->arg[0], c->d.asBytes, 48);
872 //Dbprintf("copied 48 bytes to %i",b+c->arg[0]);
902cb3c0 873// UsbSendPacket((uint8_t*)&ack, sizeof(ack));
874 cmd_send(CMD_ACK,0,0,0,0,0);
d19929cb 875 } break;
15c4dc5a 876
15c4dc5a 877 case CMD_READ_MEM:
878 ReadMem(c->arg[0]);
879 break;
880
881 case CMD_SET_LF_DIVISOR:
882 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]);
883 break;
884
885 case CMD_SET_ADC_MUX:
886 switch(c->arg[0]) {
887 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD); break;
888 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW); break;
889 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); break;
890 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW); break;
891 }
892 break;
893
894 case CMD_VERSION:
895 SendVersion();
896 break;
897
15c4dc5a 898#ifdef WITH_LCD
899 case CMD_LCD_RESET:
900 LCDReset();
901 break;
902 case CMD_LCD:
903 LCDSend(c->arg[0]);
904 break;
905#endif
906 case CMD_SETUP_WRITE:
907 case CMD_FINISH_WRITE:
d19929cb 908 case CMD_HARDWARE_RESET: {
6e82300d 909 usb_disable();
15c4dc5a 910 SpinDelay(1000);
911 SpinDelay(1000);
912 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
913 for(;;) {
914 // We're going to reset, and the bootrom will take control.
915 }
d19929cb 916 } break;
15c4dc5a 917
d19929cb 918 case CMD_START_FLASH: {
15c4dc5a 919 if(common_area.flags.bootrom_present) {
920 common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
921 }
6e82300d 922 usb_disable();
15c4dc5a 923 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
924 for(;;);
d19929cb 925 } break;
e30c654b 926
15c4dc5a 927 case CMD_DEVICE_INFO: {
902cb3c0 928 uint32_t dev_info = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;
929 if(common_area.flags.bootrom_present) dev_info |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;
930// UsbSendPacket((uint8_t*)&c, sizeof(c));
931 cmd_send(CMD_DEVICE_INFO,dev_info,0,0,0,0);
d19929cb 932 } break;
933
934 default: {
15c4dc5a 935 Dbprintf("%s: 0x%04x","unknown command:",c->cmd);
d19929cb 936 } break;
15c4dc5a 937 }
938}
939
940void __attribute__((noreturn)) AppMain(void)
941{
942 SpinDelay(100);
e30c654b 943
15c4dc5a 944 if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {
945 /* Initialize common area */
946 memset(&common_area, 0, sizeof(common_area));
947 common_area.magic = COMMON_AREA_MAGIC;
948 common_area.version = 1;
949 }
950 common_area.flags.osimage_present = 1;
951
952 LED_D_OFF();
953 LED_C_OFF();
954 LED_B_OFF();
955 LED_A_OFF();
956
902cb3c0 957 // Init USB device
958 usb_enable();
902cb3c0 959// UsbStart();
15c4dc5a 960
961 // The FPGA gets its clock from us from PCK0 output, so set that up.
962 AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
963 AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0;
964 AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK0;
965 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
966 AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK |
967 AT91C_PMC_PRES_CLK_4;
968 AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0;
969
970 // Reset SPI
971 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
972 // Reset SSC
973 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
974
975 // Load the FPGA image, which we have stored in our flash.
976 FpgaDownloadAndGo();
977
9ca155ba 978 StartTickCount();
902cb3c0 979
15c4dc5a 980#ifdef WITH_LCD
15c4dc5a 981 LCDInit();
15c4dc5a 982#endif
983
902cb3c0 984 byte_t rx[sizeof(UsbCommand)];
985 size_t rx_len;
986
15c4dc5a 987 for(;;) {
902cb3c0 988 if (usb_poll()) {
989 rx_len = usb_read(rx,sizeof(UsbCommand));
990 if (rx_len) {
991 UsbPacketReceived(rx,rx_len);
992 }
993 }
994// UsbPoll(FALSE);
995
15c4dc5a 996 WDT_HIT();
997
998#ifdef WITH_LF
999 if (BUTTON_HELD(1000) > 0)
1000 SamyRun();
1001#endif
1002 }
1003}
Impressum, Datenschutz