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