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