]> git.zerfleddert.de Git - proxmark3-svn/blame - armsrc/appmain.c
mifare usb update
[proxmark3-svn] / armsrc / appmain.c
CommitLineData
6949aca9 1//-----------------------------------------------------------------------------\r
2// The main application code. This is the first thing called after start.c\r
3// executes.\r
4// Jonathan Westhues, Mar 2006\r
5// Edits by Gerhard de Koning Gans, Sep 2007 (##)\r
6//-----------------------------------------------------------------------------\r
7\r
8#include <proxmark3.h>\r
9#include <stdlib.h>\r
10#include "apps.h"\r
a7247d85 11#include "legicrf.h"\r
6949aca9 12#ifdef WITH_LCD\r
13#include "fonts.h"\r
14#include "LCD.h"\r
15#endif\r
16\r
17//=============================================================================\r
18// A buffer where we can queue things up to be sent through the FPGA, for\r
19// any purpose (fake tag, as reader, whatever). We go MSB first, since that\r
20// is the order in which they go out on the wire.\r
21//=============================================================================\r
22\r
23BYTE ToSend[256];\r
24int ToSendMax;\r
25static int ToSendBit;\r
26struct common_area common_area __attribute__((section(".commonarea")));\r
27\r
28void BufferClear(void)\r
29{\r
30 memset(BigBuf,0,sizeof(BigBuf));\r
31 DbpString("Buffer cleared");\r
32}\r
33\r
34void ToSendReset(void)\r
35{\r
36 ToSendMax = -1;\r
37 ToSendBit = 8;\r
38}\r
39\r
40void ToSendStuffBit(int b)\r
41{\r
42 if(ToSendBit >= 8) {\r
43 ToSendMax++;\r
44 ToSend[ToSendMax] = 0;\r
45 ToSendBit = 0;\r
46 }\r
47\r
48 if(b) {\r
49 ToSend[ToSendMax] |= (1 << (7 - ToSendBit));\r
50 }\r
51\r
52 ToSendBit++;\r
53\r
54 if(ToSendBit >= sizeof(ToSend)) {\r
55 ToSendBit = 0;\r
56 DbpString("ToSendStuffBit overflowed!");\r
57 }\r
58}\r
59\r
60//=============================================================================\r
61// Debug print functions, to go out over USB, to the usual PC-side client.\r
62//=============================================================================\r
63\r
64void DbpString(char *str)\r
65{\r
66 /* this holds up stuff unless we're connected to usb */\r
67 if (!UsbConnected())\r
68 return;\r
69\r
70 UsbCommand c;\r
71 c.cmd = CMD_DEBUG_PRINT_STRING;\r
1dea88f9 72 c.arg[0] = strlen(str);\r
73 memcpy(c.d.asBytes, str, c.arg[0]);\r
6949aca9 74\r
75 UsbSendPacket((BYTE *)&c, sizeof(c));\r
76 // TODO fix USB so stupid things like this aren't req'd\r
77 SpinDelay(50);\r
78}\r
79\r
80void DbpIntegers(int x1, int x2, int x3)\r
81{\r
82 /* this holds up stuff unless we're connected to usb */\r
83 if (!UsbConnected())\r
84 return;\r
85\r
86 UsbCommand c;\r
87 c.cmd = CMD_DEBUG_PRINT_INTEGERS;\r
1dea88f9 88 c.arg[0] = x1;\r
89 c.arg[1] = x2;\r
90 c.arg[2] = x3;\r
6949aca9 91\r
92 UsbSendPacket((BYTE *)&c, sizeof(c));\r
93 // XXX\r
94 SpinDelay(50);\r
95}\r
96\r
97//-----------------------------------------------------------------------------\r
98// Read an ADC channel and block till it completes, then return the result\r
99// in ADC units (0 to 1023). Also a routine to average 32 samples and\r
100// return that.\r
101//-----------------------------------------------------------------------------\r
102static int ReadAdc(int ch)\r
103{\r
104 DWORD d;\r
105\r
106 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_SWRST;\r
107 AT91C_BASE_ADC->ADC_MR =\r
108 ADC_MODE_PRESCALE(32) |\r
109 ADC_MODE_STARTUP_TIME(16) |\r
110 ADC_MODE_SAMPLE_HOLD_TIME(8);\r
111 AT91C_BASE_ADC->ADC_CHER = ADC_CHANNEL(ch);\r
112\r
113 AT91C_BASE_ADC->ADC_CR = AT91C_ADC_START;\r
114 while(!(AT91C_BASE_ADC->ADC_SR & ADC_END_OF_CONVERSION(ch)))\r
115 ;\r
116 d = AT91C_BASE_ADC->ADC_CDR[ch];\r
117\r
118 return d;\r
119}\r
120\r
121static int AvgAdc(int ch)\r
122{\r
123 int i;\r
124 int a = 0;\r
125\r
126 for(i = 0; i < 32; i++) {\r
127 a += ReadAdc(ch);\r
128 }\r
129\r
130 return (a + 15) >> 5;\r
131}\r
132\r
133void MeasureAntennaTuning(void)\r
134{\r
135 BYTE *dest = (BYTE *)BigBuf;\r
136 int i, ptr = 0, adcval = 0, peak = 0, peakv = 0, peakf = 0;;\r
137 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV\r
138\r
139 UsbCommand c;\r
140\r
141 DbpString("Measuring antenna characteristics, please wait.");\r
142 memset(BigBuf,0,sizeof(BigBuf));\r
143\r
144/*\r
145 * Sweeps the useful LF range of the proxmark from\r
146 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and\r
147 * read the voltage in the antenna, the result left\r
148 * in the buffer is a graph which should clearly show\r
149 * the resonating frequency of your LF antenna\r
150 * ( hopefully around 95 if it is tuned to 125kHz!)\r
151 */\r
152 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);\r
153 for (i=255; i>19; i--) {\r
154 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);\r
155 SpinDelay(20);\r
156 // Vref = 3.3V, and a 10000:240 voltage divider on the input\r
157 // can measure voltages up to 137500 mV\r
158 adcval = ((137500 * AvgAdc(ADC_CHAN_LF)) >> 10);\r
159 if (i==95) vLf125 = adcval; // voltage at 125Khz\r
160 if (i==89) vLf134 = adcval; // voltage at 134Khz\r
161\r
162 dest[i] = adcval>>8; // scale int to fit in byte for graphing purposes\r
163 if(dest[i] > peak) {\r
164 peakv = adcval;\r
165 peak = dest[i];\r
166 peakf = i;\r
167 ptr = i;\r
168 }\r
169 }\r
170\r
171 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.\r
172 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);\r
173 SpinDelay(20);\r
174 // Vref = 3300mV, and an 10:1 voltage divider on the input\r
175 // can measure voltages up to 33000 mV\r
176 vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;\r
177\r
178 c.cmd = CMD_MEASURED_ANTENNA_TUNING;\r
1dea88f9 179 c.arg[0] = (vLf125 << 0) | (vLf134 << 16);\r
180 c.arg[1] = vHf;\r
181 c.arg[2] = peakf | (peakv << 16);\r
6949aca9 182 UsbSendPacket((BYTE *)&c, sizeof(c));\r
183}\r
184\r
185void SimulateTagHfListen(void)\r
186{\r
187 BYTE *dest = (BYTE *)BigBuf;\r
188 int n = sizeof(BigBuf);\r
189 BYTE v = 0;\r
190 int i;\r
191 int p = 0;\r
192\r
193 // We're using this mode just so that I can test it out; the simulated\r
194 // tag mode would work just as well and be simpler.\r
195 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP);\r
196\r
197 // We need to listen to the high-frequency, peak-detected path.\r
198 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);\r
199\r
200 FpgaSetupSsc();\r
201\r
202 i = 0;\r
203 for(;;) {\r
204 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {\r
205 AT91C_BASE_SSC->SSC_THR = 0xff;\r
206 }\r
207 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {\r
208 BYTE r = (BYTE)AT91C_BASE_SSC->SSC_RHR;\r
209\r
210 v <<= 1;\r
211 if(r & 1) {\r
212 v |= 1;\r
213 }\r
214 p++;\r
215\r
216 if(p >= 8) {\r
217 dest[i] = v;\r
218 v = 0;\r
219 p = 0;\r
220 i++;\r
221\r
222 if(i >= n) {\r
223 break;\r
224 }\r
225 }\r
226 }\r
227 }\r
228 DbpString("simulate tag (now type bitsamples)");\r
229}\r
230\r
231void ReadMem(int addr)\r
232{\r
233 const DWORD *data = ((DWORD *)addr);\r
234 int i;\r
235\r
236 DbpString("Reading memory at address");\r
237 DbpIntegers(0, 0, addr);\r
238 for (i = 0; i < 8; i+= 2)\r
239 DbpIntegers(0, data[i], data[i+1]);\r
240}\r
241\r
242/* osimage version information is linked in */\r
243extern struct version_information version_information;\r
244/* bootrom version information is pointed to from _bootphase1_version_pointer */\r
245extern char *_bootphase1_version_pointer, _flash_start, _flash_end;\r
246void SendVersion(void)\r
247{\r
248 char temp[48]; /* Limited data payload in USB packets */\r
249 DbpString("Prox/RFID mark3 RFID instrument");\r
250 \r
251 /* Try to find the bootrom version information. Expect to find a pointer at \r
252 * symbol _bootphase1_version_pointer, perform slight sanity checks on the\r
253 * pointer, then use it.\r
254 */\r
255 char *bootrom_version = *(char**)&_bootphase1_version_pointer;\r
256 if( bootrom_version < &_flash_start || bootrom_version >= &_flash_end ) {\r
257 DbpString("bootrom version information appears invalid");\r
258 } else {\r
259 FormatVersionInformation(temp, sizeof(temp), "bootrom: ", bootrom_version);\r
260 DbpString(temp);\r
261 }\r
262 \r
263 FormatVersionInformation(temp, sizeof(temp), "os: ", &version_information);\r
264 DbpString(temp);\r
265 \r
266 FpgaGatherVersion(temp, sizeof(temp));\r
267 DbpString(temp);\r
268}\r
269\r
e7014022 270#ifdef WITH_LF\r
6949aca9 271// samy's sniff and repeat routine\r
272void SamyRun()\r
273{\r
274 DbpString("Stand-alone mode! No PC necessary.");\r
275\r
276 // 3 possible options? no just 2 for now\r
277#define OPTS 2\r
278\r
279 int high[OPTS], low[OPTS];\r
280\r
281 // Oooh pretty -- notify user we're in elite samy mode now\r
282 LED(LED_RED, 200);\r
283 LED(LED_ORANGE, 200);\r
284 LED(LED_GREEN, 200);\r
285 LED(LED_ORANGE, 200);\r
286 LED(LED_RED, 200);\r
287 LED(LED_ORANGE, 200);\r
288 LED(LED_GREEN, 200);\r
289 LED(LED_ORANGE, 200);\r
290 LED(LED_RED, 200);\r
291\r
292 int selected = 0;\r
293 int playing = 0;\r
294\r
295 // Turn on selected LED\r
296 LED(selected + 1, 0);\r
297\r
298 for (;;)\r
299 {\r
300 UsbPoll(FALSE);\r
301 WDT_HIT();\r
302\r
303 // Was our button held down or pressed?\r
304 int button_pressed = BUTTON_HELD(1000);\r
305 SpinDelay(300);\r
306\r
307 // Button was held for a second, begin recording\r
308 if (button_pressed > 0)\r
309 {\r
310 LEDsoff();\r
311 LED(selected + 1, 0);\r
312 LED(LED_RED2, 0);\r
313\r
314 // record\r
315 DbpString("Starting recording");\r
316\r
317 // wait for button to be released\r
318 while(BUTTON_PRESS())\r
319 WDT_HIT();\r
320\r
321 /* need this delay to prevent catching some weird data */\r
322 SpinDelay(500);\r
323\r
324 CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);\r
325 DbpString("Recorded");\r
326 DbpIntegers(selected, high[selected], low[selected]);\r
327\r
328 LEDsoff();\r
329 LED(selected + 1, 0);\r
330 // Finished recording\r
331\r
332 // If we were previously playing, set playing off\r
333 // so next button push begins playing what we recorded\r
334 playing = 0;\r
335 }\r
336\r
337 // Change where to record (or begin playing)\r
338 else if (button_pressed)\r
339 {\r
340 // Next option if we were previously playing\r
341 if (playing)\r
342 selected = (selected + 1) % OPTS;\r
343 playing = !playing;\r
344\r
345 LEDsoff();\r
346 LED(selected + 1, 0);\r
347\r
348 // Begin transmitting\r
349 if (playing)\r
350 {\r
351 LED(LED_GREEN, 0);\r
352 DbpString("Playing");\r
353 // wait for button to be released\r
354 while(BUTTON_PRESS())\r
355 WDT_HIT();\r
356 DbpIntegers(selected, high[selected], low[selected]);\r
357 CmdHIDsimTAG(high[selected], low[selected], 0);\r
358 DbpString("Done playing");\r
359 if (BUTTON_HELD(1000) > 0)\r
360 {\r
361 DbpString("Exiting");\r
362 LEDsoff();\r
363 return;\r
364 }\r
365\r
366 /* We pressed a button so ignore it here with a delay */\r
367 SpinDelay(300);\r
368\r
369 // when done, we're done playing, move to next option\r
370 selected = (selected + 1) % OPTS;\r
371 playing = !playing;\r
372 LEDsoff();\r
373 LED(selected + 1, 0);\r
374 }\r
375 else\r
376 while(BUTTON_PRESS())\r
377 WDT_HIT();\r
378 }\r
379 }\r
380}\r
c0d04e95 381#endif\r
6949aca9 382\r
383/*\r
384OBJECTIVE\r
385Listen and detect an external reader. Determine the best location\r
386for the antenna.\r
387\r
388INSTRUCTIONS:\r
389Inside the ListenReaderField() function, there is two mode.\r
390By default, when you call the function, you will enter mode 1.\r
391If you press the PM3 button one time, you will enter mode 2.\r
392If you press the PM3 button a second time, you will exit the function.\r
393\r
394DESCRIPTION OF MODE 1:\r
395This mode just listens for an external reader field and lights up green\r
396for HF and/or red for LF. This is the original mode of the detectreader\r
397function.\r
398\r
399DESCRIPTION OF MODE 2:\r
400This mode will visually represent, using the LEDs, the actual strength of the\r
401current compared to the maximum current detected. Basically, once you know\r
402what kind of external reader is present, it will help you spot the best location to place\r
403your antenna. You will probably not get some good results if there is a LF and a HF reader\r
404at the same place! :-)\r
405\r
406LIGHT SCHEME USED:\r
407*/\r
408static const char LIGHT_SCHEME[] = {\r
409 0x0, /* ---- | No field detected */\r
410 0x1, /* X--- | 14% of maximum current detected */\r
411 0x2, /* -X-- | 29% of maximum current detected */\r
412 0x4, /* --X- | 43% of maximum current detected */\r
413 0x8, /* ---X | 57% of maximum current detected */\r
414 0xC, /* --XX | 71% of maximum current detected */\r
415 0xE, /* -XXX | 86% of maximum current detected */\r
416 0xF, /* XXXX | 100% of maximum current detected */\r
417};\r
418static const int LIGHT_LEN = sizeof(LIGHT_SCHEME)/sizeof(LIGHT_SCHEME[0]);\r
419\r
420void ListenReaderField(int limit)\r
421{\r
422 int lf_av, lf_av_new, lf_baseline= 0, lf_count= 0, lf_max;\r
423 int hf_av, hf_av_new, hf_baseline= 0, hf_count= 0, hf_max;\r
424 int mode=1, display_val, display_max, i;\r
425\r
426#define LF_ONLY 1\r
427#define HF_ONLY 2\r
428\r
429 LEDsoff();\r
430\r
431 lf_av=lf_max=ReadAdc(ADC_CHAN_LF);\r
432\r
433 if(limit != HF_ONLY) {\r
434 DbpString("LF 125/134 Baseline:");\r
435 DbpIntegers(lf_av,0,0);\r
436 lf_baseline= lf_av;\r
437 }\r
438\r
439 hf_av=hf_max=ReadAdc(ADC_CHAN_HF);\r
440\r
441 if (limit != LF_ONLY) {\r
442 DbpString("HF 13.56 Baseline:");\r
443 DbpIntegers(hf_av,0,0);\r
444 hf_baseline= hf_av;\r
445 }\r
446\r
447 for(;;) {\r
448 if (BUTTON_PRESS()) {\r
449 SpinDelay(500);\r
450 switch (mode) {\r
451 case 1:\r
452 mode=2;\r
453 DbpString("Signal Strength Mode");\r
454 break;\r
455 case 2:\r
456 default:\r
457 DbpString("Stopped");\r
458 LEDsoff();\r
459 return;\r
460 break;\r
461 }\r
462 }\r
463 WDT_HIT();\r
464\r
465 if (limit != HF_ONLY) {\r
466 if(mode==1) {\r
467 if (abs(lf_av - lf_baseline) > 10) LED_D_ON();\r
468 else LED_D_OFF();\r
469 }\r
470 \r
471 ++lf_count;\r
472 lf_av_new= ReadAdc(ADC_CHAN_LF);\r
473 // see if there's a significant change\r
474 if(abs(lf_av - lf_av_new) > 10) {\r
475 DbpString("LF 125/134 Field Change:");\r
476 DbpIntegers(lf_av,lf_av_new,lf_count);\r
477 lf_av= lf_av_new;\r
478 if (lf_av > lf_max)\r
479 lf_max = lf_av;\r
480 lf_count= 0;\r
481 }\r
482 }\r
483\r
484 if (limit != LF_ONLY) {\r
485 if (mode == 1){\r
486 if (abs(hf_av - hf_baseline) > 10) LED_B_ON();\r
487 else LED_B_OFF();\r
488 }\r
489 \r
490 ++hf_count;\r
491 hf_av_new= ReadAdc(ADC_CHAN_HF);\r
492 // see if there's a significant change\r
493 if(abs(hf_av - hf_av_new) > 10) {\r
494 DbpString("HF 13.56 Field Change:");\r
495 DbpIntegers(hf_av,hf_av_new,hf_count);\r
496 hf_av= hf_av_new;\r
497 if (hf_av > hf_max)\r
498 hf_max = hf_av;\r
499 hf_count= 0;\r
500 }\r
501 }\r
502 \r
503 if(mode == 2) {\r
504 if (limit == LF_ONLY) {\r
505 display_val = lf_av;\r
506 display_max = lf_max;\r
507 } else if (limit == HF_ONLY) {\r
508 display_val = hf_av;\r
509 display_max = hf_max;\r
510 } else { /* Pick one at random */\r
511 if( (hf_max - hf_baseline) > (lf_max - lf_baseline) ) {\r
512 display_val = hf_av;\r
513 display_max = hf_max;\r
514 } else {\r
515 display_val = lf_av;\r
516 display_max = lf_max;\r
517 }\r
518 }\r
519 for (i=0; i<LIGHT_LEN; i++) {\r
520 if (display_val >= ((display_max/LIGHT_LEN)*i) && display_val <= ((display_max/LIGHT_LEN)*(i+1))) {\r
521 if (LIGHT_SCHEME[i] & 0x1) LED_C_ON(); else LED_C_OFF();\r
522 if (LIGHT_SCHEME[i] & 0x2) LED_A_ON(); else LED_A_OFF();\r
523 if (LIGHT_SCHEME[i] & 0x4) LED_B_ON(); else LED_B_OFF();\r
524 if (LIGHT_SCHEME[i] & 0x8) LED_D_ON(); else LED_D_OFF();\r
525 break;\r
526 }\r
527 }\r
528 }\r
529 }\r
530}\r
531\r
532void UsbPacketReceived(BYTE *packet, int len)\r
533{\r
534 UsbCommand *c = (UsbCommand *)packet;\r
535\r
536 switch(c->cmd) {\r
e7014022 537#ifdef WITH_LF\r
6949aca9 538 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:\r
1dea88f9 539 AcquireRawAdcSamples125k(c->arg[0]);\r
6949aca9 540 break;\r
c0d04e95 541#endif\r
6949aca9 542\r
e7014022 543#ifdef WITH_LF\r
6949aca9 544 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:\r
1dea88f9 545 ModThenAcquireRawAdcSamples125k(c->arg[0],c->arg[1],c->arg[2],c->d.asBytes);\r
6949aca9 546 break;\r
c0d04e95 547#endif\r
6949aca9 548\r
b1083ec9 549#ifdef WITH_ISO15693\r
6949aca9 550 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:\r
551 AcquireRawAdcSamplesIso15693();\r
552 break;\r
b1083ec9 553#endif\r
6949aca9 554\r
555 case CMD_BUFF_CLEAR:\r
556 BufferClear();\r
557 break;\r
558\r
b1083ec9 559#ifdef WITH_ISO15693\r
6949aca9 560 case CMD_READER_ISO_15693:\r
1dea88f9 561 ReaderIso15693(c->arg[0]);\r
6949aca9 562 break;\r
b1083ec9 563#endif\r
6949aca9 564\r
dcc10e5e 565 case CMD_READER_LEGIC_RF:\r
566 LegicRfReader();\r
567 break;\r
568\r
b1083ec9 569#ifdef WITH_ISO15693\r
6949aca9 570 case CMD_SIMTAG_ISO_15693:\r
1dea88f9 571 SimTagIso15693(c->arg[0]);\r
6949aca9 572 break;\r
b1083ec9 573#endif\r
6949aca9 574\r
b1083ec9 575#ifdef WITH_ISO14443b\r
6949aca9 576 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:\r
1dea88f9 577 AcquireRawAdcSamplesIso14443(c->arg[0]);\r
6949aca9 578 break;\r
b1083ec9 579#endif\r
6949aca9 580\r
b1083ec9 581#ifdef WITH_ISO14443b\r
6949aca9 582 case CMD_READ_SRI512_TAG:\r
1dea88f9 583 ReadSRI512Iso14443(c->arg[0]);\r
6949aca9 584 break;\r
1dea88f9 585 case CMD_READ_SRIX4K_TAG:\r
586 ReadSRIX4KIso14443(c->arg[0]);\r
587 break;\r
b1083ec9 588#endif\r
6949aca9 589\r
b1083ec9 590#ifdef WITH_ISO14443a\r
6949aca9 591 case CMD_READER_ISO_14443a:\r
1dea88f9 592 ReaderIso14443a(c->arg[0]);\r
6949aca9 593 break;\r
b1083ec9 594#endif\r
6949aca9 595\r
32cfae43 596#ifdef WITH_ISO14443a\r
597 case CMD_READER_MIFARE:\r
598 ReaderMifare(c->arg[0]);\r
599 break;\r
600#endif\r
601 \r
b1083ec9 602#ifdef WITH_ISO14443b\r
6949aca9 603 case CMD_SNOOP_ISO_14443:\r
604 SnoopIso14443();\r
605 break;\r
b1083ec9 606#endif\r
6949aca9 607\r
b1083ec9 608#ifdef WITH_ISO14443a\r
6949aca9 609 case CMD_SNOOP_ISO_14443a:\r
610 SnoopIso14443a();\r
611 break;\r
b1083ec9 612#endif\r
6949aca9 613\r
614 case CMD_SIMULATE_TAG_HF_LISTEN:\r
615 SimulateTagHfListen();\r
616 break;\r
617\r
b1083ec9 618#ifdef WITH_ISO14443b\r
6949aca9 619 case CMD_SIMULATE_TAG_ISO_14443:\r
620 SimulateIso14443Tag();\r
621 break;\r
b1083ec9 622#endif\r
a7247d85 623 \r
b1083ec9 624#ifdef WITH_ISO14443a\r
6949aca9 625 case CMD_SIMULATE_TAG_ISO_14443a:\r
1dea88f9 626 SimulateIso14443aTag(c->arg[0], c->arg[1]); // ## Simulate iso14443a tag - pass tag type & UID\r
6949aca9 627 break;\r
b1083ec9 628#endif\r
6949aca9 629\r
630 case CMD_MEASURE_ANTENNA_TUNING:\r
631 MeasureAntennaTuning();\r
632 break;\r
633\r
634 case CMD_LISTEN_READER_FIELD:\r
1dea88f9 635 ListenReaderField(c->arg[0]);\r
6949aca9 636 break;\r
637\r
e7014022 638#ifdef WITH_LF\r
6949aca9 639 case CMD_HID_DEMOD_FSK:\r
640 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag\r
641 break;\r
c0d04e95 642#endif\r
6949aca9 643\r
e7014022 644#ifdef WITH_LF\r
6949aca9 645 case CMD_HID_SIM_TAG:\r
1dea88f9 646 CmdHIDsimTAG(c->arg[0], c->arg[1], 1); // Simulate HID tag by ID\r
6949aca9 647 break;\r
c0d04e95 648#endif\r
6949aca9 649\r
650 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control\r
651 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
652 SpinDelay(200);\r
653 LED_D_OFF(); // LED D indicates field ON or OFF\r
654 break;\r
655\r
e7014022 656#ifdef WITH_LF\r
6949aca9 657 case CMD_READ_TI_TYPE:\r
658 ReadTItag();\r
659 break;\r
c0d04e95 660#endif\r
6949aca9 661\r
e7014022 662#ifdef WITH_LF\r
6949aca9 663 case CMD_WRITE_TI_TYPE:\r
1dea88f9 664 WriteTItag(c->arg[0],c->arg[1],c->arg[2]);\r
6949aca9 665 break;\r
c0d04e95 666#endif\r
6949aca9 667\r
668 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K: {\r
669 UsbCommand n;\r
670 if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {\r
671 n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;\r
672 } else {\r
673 n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;\r
674 }\r
1dea88f9 675 n.arg[0] = c->arg[0];\r
676 memcpy(n.d.asDwords, BigBuf+c->arg[0], 12*sizeof(DWORD));\r
6949aca9 677 UsbSendPacket((BYTE *)&n, sizeof(n));\r
678 break;\r
679 }\r
c0d04e95 680\r
6949aca9 681 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {\r
682 BYTE *b = (BYTE *)BigBuf;\r
1dea88f9 683 memcpy(b+c->arg[0], c->d.asBytes, 48);\r
6949aca9 684 break;\r
685 }\r
c0d04e95 686\r
e7014022 687#ifdef WITH_LF\r
6949aca9 688 case CMD_SIMULATE_TAG_125K:\r
689 LED_A_ON();\r
1dea88f9 690 SimulateTagLowFrequency(c->arg[0], 1);\r
6949aca9 691 LED_A_OFF();\r
692 break;\r
c0d04e95 693#endif\r
694\r
6949aca9 695 case CMD_READ_MEM:\r
1dea88f9 696 ReadMem(c->arg[0]);\r
6949aca9 697 break;\r
c0d04e95 698\r
6949aca9 699 case CMD_SET_LF_DIVISOR:\r
1dea88f9 700 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->arg[0]);\r
6949aca9 701 break;\r
c0d04e95 702\r
5fc8250f 703 case CMD_SET_ADC_MUX:\r
1dea88f9 704 switch(c->arg[0]) {\r
c0d04e95 705 case 0: SetAdcMuxFor(GPIO_MUXSEL_LOPKD); break;\r
706 case 1: SetAdcMuxFor(GPIO_MUXSEL_LORAW); break;\r
707 case 2: SetAdcMuxFor(GPIO_MUXSEL_HIPKD); break;\r
708 case 3: SetAdcMuxFor(GPIO_MUXSEL_HIRAW); break;\r
5fc8250f 709 }\r
710 break;\r
c0d04e95 711\r
6949aca9 712 case CMD_VERSION:\r
713 SendVersion();\r
714 break;\r
c0d04e95 715\r
e7014022 716#ifdef WITH_LF\r
6949aca9 717 case CMD_LF_SIMULATE_BIDIR:\r
1dea88f9 718 SimulateTagLowFrequencyBidir(c->arg[0], c->arg[1]);\r
6949aca9 719 break;\r
c0d04e95 720#endif\r
721\r
6949aca9 722#ifdef WITH_LCD\r
723 case CMD_LCD_RESET:\r
724 LCDReset();\r
725 break;\r
726 case CMD_LCD:\r
1dea88f9 727 LCDSend(c->arg[0]);\r
6949aca9 728 break;\r
729#endif\r
730 case CMD_SETUP_WRITE:\r
731 case CMD_FINISH_WRITE:\r
732 case CMD_HARDWARE_RESET:\r
733 USB_D_PLUS_PULLUP_OFF();\r
734 SpinDelay(1000);\r
735 SpinDelay(1000);\r
736 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;\r
737 for(;;) {\r
738 // We're going to reset, and the bootrom will take control.\r
739 }\r
740 break;\r
c0d04e95 741\r
6949aca9 742 case CMD_START_FLASH:\r
743 if(common_area.flags.bootrom_present) {\r
744 common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;\r
745 }\r
746 USB_D_PLUS_PULLUP_OFF();\r
747 AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;\r
748 for(;;);\r
749 break;\r
750 \r
751 case CMD_DEVICE_INFO: {\r
752 UsbCommand c;\r
753 c.cmd = CMD_DEVICE_INFO;\r
1dea88f9 754 c.arg[0] = DEVICE_INFO_FLAG_OSIMAGE_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_OS;\r
755 if(common_area.flags.bootrom_present) c.arg[0] |= DEVICE_INFO_FLAG_BOOTROM_PRESENT;\r
6949aca9 756 UsbSendPacket((BYTE*)&c, sizeof(c));\r
757 }\r
758 break;\r
759 default:\r
760 DbpString("unknown command");\r
761 break;\r
762 }\r
763}\r
764\r
765void __attribute__((noreturn)) AppMain(void)\r
766{\r
767 SpinDelay(100);\r
768 \r
769 if(common_area.magic != COMMON_AREA_MAGIC || common_area.version != 1) {\r
770 /* Initialize common area */\r
771 memset(&common_area, 0, sizeof(common_area));\r
772 common_area.magic = COMMON_AREA_MAGIC;\r
773 common_area.version = 1;\r
774 }\r
775 common_area.flags.osimage_present = 1;\r
776\r
777 LED_D_OFF();\r
778 LED_C_OFF();\r
779 LED_B_OFF();\r
780 LED_A_OFF();\r
781\r
782 UsbStart();\r
783\r
784 // The FPGA gets its clock from us from PCK0 output, so set that up.\r
785 AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;\r
786 AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0;\r
787 AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_PCK0;\r
788 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz\r
789 AT91C_BASE_PMC->PMC_PCKR[0] = AT91C_PMC_CSS_PLL_CLK |\r
790 AT91C_PMC_PRES_CLK_4;\r
791 AT91C_BASE_PIOA->PIO_OER = GPIO_PCK0;\r
792\r
793 // Reset SPI\r
794 AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;\r
795 // Reset SSC\r
796 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;\r
797\r
798 // Load the FPGA image, which we have stored in our flash.\r
799 FpgaDownloadAndGo();\r
800\r
801#ifdef WITH_LCD\r
802\r
803 LCDInit();\r
804\r
805 // test text on different colored backgrounds\r
806 LCDString(" The quick brown fox ", (char *)&FONT6x8,1,1+8*0,WHITE ,BLACK );\r
807 LCDString(" jumped over the ", (char *)&FONT6x8,1,1+8*1,BLACK ,WHITE );\r
808 LCDString(" lazy dog. ", (char *)&FONT6x8,1,1+8*2,YELLOW ,RED );\r
809 LCDString(" AaBbCcDdEeFfGgHhIiJj ", (char *)&FONT6x8,1,1+8*3,RED ,GREEN );\r
810 LCDString(" KkLlMmNnOoPpQqRrSsTt ", (char *)&FONT6x8,1,1+8*4,MAGENTA,BLUE );\r
811 LCDString("UuVvWwXxYyZz0123456789", (char *)&FONT6x8,1,1+8*5,BLUE ,YELLOW);\r
812 LCDString("`-=[]_;',./~!@#$%^&*()", (char *)&FONT6x8,1,1+8*6,BLACK ,CYAN );\r
813 LCDString(" _+{}|:\\\"<>? ",(char *)&FONT6x8,1,1+8*7,BLUE ,MAGENTA);\r
814\r
815 // color bands\r
816 LCDFill(0, 1+8* 8, 132, 8, BLACK);\r
817 LCDFill(0, 1+8* 9, 132, 8, WHITE);\r
818 LCDFill(0, 1+8*10, 132, 8, RED);\r
819 LCDFill(0, 1+8*11, 132, 8, GREEN);\r
820 LCDFill(0, 1+8*12, 132, 8, BLUE);\r
821 LCDFill(0, 1+8*13, 132, 8, YELLOW);\r
822 LCDFill(0, 1+8*14, 132, 8, CYAN);\r
823 LCDFill(0, 1+8*15, 132, 8, MAGENTA);\r
824\r
825#endif\r
826\r
827 for(;;) {\r
828 UsbPoll(FALSE);\r
829 WDT_HIT();\r
830\r
e7014022 831#ifdef WITH_LF\r
6949aca9 832 if (BUTTON_HELD(1000) > 0)\r
833 SamyRun();\r
c0d04e95 834#endif\r
6949aca9 835 }\r
836}\r
Impressum, Datenschutz