]> git.zerfleddert.de Git - proxmark3-svn/blob - armsrc/appmain.c
added 'buffclear' - when you absolutely positivley must clear every bit in the room
[proxmark3-svn] / armsrc / appmain.c
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
8
9 #include <proxmark3.h>
10 #include "apps.h"
11 #ifdef WITH_LCD
12 #include "fonts.h"
13 #include "LCD.h"
14 #endif
15
16 // The large multi-purpose buffer, typically used to hold A/D samples,
17 // maybe pre-processed in some way.
18 DWORD BigBuf[16000];
19
20 //=============================================================================
21 // A buffer where we can queue things up to be sent through the FPGA, for
22 // any purpose (fake tag, as reader, whatever). We go MSB first, since that
23 // is the order in which they go out on the wire.
24 //=============================================================================
25
26 BYTE ToSend[256];
27 int ToSendMax;
28 static int ToSendBit;
29
30
31 void BufferClear(void)
32 {
33 memset(BigBuf,0,sizeof(BigBuf));
34 DbpString("Buffer cleared");
35 }
36
37 void ToSendReset(void)
38 {
39 ToSendMax = -1;
40 ToSendBit = 8;
41 }
42
43 void ToSendStuffBit(int b)
44 {
45 if(ToSendBit >= 8) {
46 ToSendMax++;
47 ToSend[ToSendMax] = 0;
48 ToSendBit = 0;
49 }
50
51 if(b) {
52 ToSend[ToSendMax] |= (1 << (7 - ToSendBit));
53 }
54
55 ToSendBit++;
56
57 if(ToSendBit >= sizeof(ToSend)) {
58 ToSendBit = 0;
59 DbpString("ToSendStuffBit overflowed!");
60 }
61 }
62
63 //=============================================================================
64 // Debug print functions, to go out over USB, to the usual PC-side client.
65 //=============================================================================
66
67 void DbpString(char *str)
68 {
69 UsbCommand c;
70 c.cmd = CMD_DEBUG_PRINT_STRING;
71 c.ext1 = strlen(str);
72 memcpy(c.d.asBytes, str, c.ext1);
73
74 UsbSendPacket((BYTE *)&c, sizeof(c));
75 // TODO fix USB so stupid things like this aren't req'd
76 SpinDelay(50);
77 }
78
79 void DbpIntegers(int x1, int x2, int x3)
80 {
81 UsbCommand c;
82 c.cmd = CMD_DEBUG_PRINT_INTEGERS;
83 c.ext1 = x1;
84 c.ext2 = x2;
85 c.ext3 = x3;
86
87 UsbSendPacket((BYTE *)&c, sizeof(c));
88 // XXX
89 SpinDelay(50);
90 }
91
92 void AcquireRawAdcSamples125k(BOOL at134khz)
93 {
94 BYTE *dest = (BYTE *)BigBuf;
95 int n = sizeof(BigBuf);
96 int i;
97
98 memset(dest,0,n);
99
100 if(at134khz) {
101 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
102 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
103 } else {
104 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
105 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
106 }
107
108 // Connect the A/D to the peak-detected low-frequency path.
109 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
110
111 // Give it a bit of time for the resonant antenna to settle.
112 SpinDelay(50);
113
114 // Now set up the SSC to get the ADC samples that are now streaming at us.
115 FpgaSetupSsc();
116
117 i = 0;
118 for(;;) {
119 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
120 SSC_TRANSMIT_HOLDING = 0x43;
121 LED_D_ON();
122 }
123 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
124 dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
125 i++;
126 LED_D_OFF();
127 if(i >= n) {
128 break;
129 }
130 }
131 }
132 DbpIntegers(dest[0], dest[1], at134khz);
133 }
134
135 //-----------------------------------------------------------------------------
136 // Read an ADC channel and block till it completes, then return the result
137 // in ADC units (0 to 1023). Also a routine to average 32 samples and
138 // return that.
139 //-----------------------------------------------------------------------------
140 static int ReadAdc(int ch)
141 {
142 DWORD d;
143
144 ADC_CONTROL = ADC_CONTROL_RESET;
145 ADC_MODE = ADC_MODE_PRESCALE(32) | ADC_MODE_STARTUP_TIME(16) |
146 ADC_MODE_SAMPLE_HOLD_TIME(8);
147 ADC_CHANNEL_ENABLE = ADC_CHANNEL(ch);
148
149 ADC_CONTROL = ADC_CONTROL_START;
150 while(!(ADC_STATUS & ADC_END_OF_CONVERSION(ch)))
151 ;
152 d = ADC_CHANNEL_DATA(ch);
153
154 return d;
155 }
156
157 static int AvgAdc(int ch)
158 {
159 int i;
160 int a = 0;
161
162 for(i = 0; i < 32; i++) {
163 a += ReadAdc(ch);
164 }
165
166 return (a + 15) >> 5;
167 }
168
169 /*
170 * Sweeps the useful LF range of the proxmark from
171 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
172 * reads the voltage in the antenna: the result is a graph
173 * which should clearly show the resonating frequency of your
174 * LF antenna ( hopefully around 90 if it is tuned to 125kHz!)
175 */
176 void SweepLFrange()
177 {
178 BYTE *dest = (BYTE *)BigBuf;
179 int i;
180
181 // clear buffer
182 memset(BigBuf,0,sizeof(BigBuf));
183
184 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
185 for (i=255; i>19; i--) {
186 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
187 SpinDelay(20);
188 dest[i] = (137500 * AvgAdc(4)) >> 18;
189 }
190 }
191
192 void MeasureAntennaTuning(void)
193 {
194 // Impedances are Zc = 1/(j*omega*C), in ohms
195 #define LF_TUNING_CAP_Z 1273 // 1 nF @ 125 kHz
196 #define HF_TUNING_CAP_Z 235 // 50 pF @ 13.56 MHz
197
198 int vLf125, vLf134, vHf; // in mV
199
200 UsbCommand c;
201
202 // Let the FPGA drive the low-frequency antenna around 125 kHz.
203 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
204 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
205 SpinDelay(20);
206 vLf125 = AvgAdc(4);
207 // Vref = 3.3V, and a 10000:240 voltage divider on the input
208 // can measure voltages up to 137500 mV
209 vLf125 = (137500 * vLf125) >> 10;
210
211 // Let the FPGA drive the low-frequency antenna around 134 kHz.
212 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
213 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_134_KHZ);
214 SpinDelay(20);
215 vLf134 = AvgAdc(4);
216 // Vref = 3.3V, and a 10000:240 voltage divider on the input
217 // can measure voltages up to 137500 mV
218 vLf134 = (137500 * vLf134) >> 10;
219
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 vHf = AvgAdc(5);
224 // Vref = 3300mV, and an 10:1 voltage divider on the input
225 // can measure voltages up to 33000 mV
226 vHf = (33000 * vHf) >> 10;
227
228 c.cmd = CMD_MEASURED_ANTENNA_TUNING;
229 c.ext1 = (vLf125 << 0) | (vLf134 << 16);
230 c.ext2 = vHf;
231 c.ext3 = (LF_TUNING_CAP_Z << 0) | (HF_TUNING_CAP_Z << 16);
232 UsbSendPacket((BYTE *)&c, sizeof(c));
233 }
234
235 void SimulateTagLowFrequency(int period)
236 {
237 int i;
238 BYTE *tab = (BYTE *)BigBuf;
239
240 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_SIMULATOR);
241
242 PIO_ENABLE = (1 << GPIO_SSC_DOUT) | (1 << GPIO_SSC_CLK);
243
244 PIO_OUTPUT_ENABLE = (1 << GPIO_SSC_DOUT);
245 PIO_OUTPUT_DISABLE = (1 << GPIO_SSC_CLK);
246
247 #define SHORT_COIL() LOW(GPIO_SSC_DOUT)
248 #define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
249
250 i = 0;
251 for(;;) {
252 while(!(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK))) {
253 if(BUTTON_PRESS()) {
254 return;
255 }
256 WDT_HIT();
257 }
258
259 LED_D_ON();
260 if(tab[i]) {
261 OPEN_COIL();
262 } else {
263 SHORT_COIL();
264 }
265 LED_D_OFF();
266
267 while(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK)) {
268 if(BUTTON_PRESS()) {
269 return;
270 }
271 WDT_HIT();
272 }
273
274 i++;
275 if(i == period) i = 0;
276 }
277 }
278
279 // compose fc/8 fc/10 waveform
280 static void fc(int c, int *n) {
281 BYTE *dest = (BYTE *)BigBuf;
282 int idx;
283
284 // for when we want an fc8 pattern every 4 logical bits
285 if(c==0) {
286 dest[((*n)++)]=1;
287 dest[((*n)++)]=1;
288 dest[((*n)++)]=0;
289 dest[((*n)++)]=0;
290 dest[((*n)++)]=0;
291 dest[((*n)++)]=0;
292 dest[((*n)++)]=0;
293 dest[((*n)++)]=0;
294 }
295 // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples
296 if(c==8) {
297 for (idx=0; idx<6; idx++) {
298 dest[((*n)++)]=1;
299 dest[((*n)++)]=1;
300 dest[((*n)++)]=0;
301 dest[((*n)++)]=0;
302 dest[((*n)++)]=0;
303 dest[((*n)++)]=0;
304 dest[((*n)++)]=0;
305 dest[((*n)++)]=0;
306 }
307 }
308
309 // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
310 if(c==10) {
311 for (idx=0; idx<5; idx++) {
312 dest[((*n)++)]=1;
313 dest[((*n)++)]=1;
314 dest[((*n)++)]=1;
315 dest[((*n)++)]=0;
316 dest[((*n)++)]=0;
317 dest[((*n)++)]=0;
318 dest[((*n)++)]=0;
319 dest[((*n)++)]=0;
320 dest[((*n)++)]=0;
321 dest[((*n)++)]=0;
322 }
323 }
324 }
325
326 // prepare a waveform pattern in the buffer based on the ID given then
327 // simulate a HID tag until the button is pressed
328 static void CmdHIDsimTAG(int hi, int lo)
329 {
330 int n=0, i=0;
331 /*
332 HID tag bitstream format
333 The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
334 A 1 bit is represented as 6 fc8 and 5 fc10 patterns
335 A 0 bit is represented as 5 fc10 and 6 fc8 patterns
336 A fc8 is inserted before every 4 bits
337 A special start of frame pattern is used consisting a0b0 where a and b are neither 0
338 nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10)
339 */
340
341 if (hi>0xFFF) {
342 DbpString("Tags can only have 44 bits.");
343 return;
344 }
345 fc(0,&n);
346 // special start of frame marker containing invalid bit sequences
347 fc(8, &n); fc(8, &n); // invalid
348 fc(8, &n); fc(10, &n); // logical 0
349 fc(10, &n); fc(10, &n); // invalid
350 fc(8, &n); fc(10, &n); // logical 0
351
352 WDT_HIT();
353 // manchester encode bits 43 to 32
354 for (i=11; i>=0; i--) {
355 if ((i%4)==3) fc(0,&n);
356 if ((hi>>i)&1) {
357 fc(10, &n); fc(8, &n); // low-high transition
358 } else {
359 fc(8, &n); fc(10, &n); // high-low transition
360 }
361 }
362
363 WDT_HIT();
364 // manchester encode bits 31 to 0
365 for (i=31; i>=0; i--) {
366 if ((i%4)==3) fc(0,&n);
367 if ((lo>>i)&1) {
368 fc(10, &n); fc(8, &n); // low-high transition
369 } else {
370 fc(8, &n); fc(10, &n); // high-low transition
371 }
372 }
373
374 LED_A_ON();
375 SimulateTagLowFrequency(n);
376 LED_A_OFF();
377 }
378
379 // loop to capture raw HID waveform then FSK demodulate the TAG ID from it
380 static void CmdHIDdemodFSK(void)
381 {
382 BYTE *dest = (BYTE *)BigBuf;
383 int m=0, n=0, i=0, idx=0, found=0, lastval=0;
384 DWORD hi=0, lo=0;
385
386 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
387 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_READER_USE_125_KHZ);
388
389 // Connect the A/D to the peak-detected low-frequency path.
390 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
391
392 // Give it a bit of time for the resonant antenna to settle.
393 SpinDelay(50);
394
395 // Now set up the SSC to get the ADC samples that are now streaming at us.
396 FpgaSetupSsc();
397
398 for(;;) {
399 WDT_HIT();
400 LED_A_ON();
401 if(BUTTON_PRESS()) {
402 LED_A_OFF();
403 return;
404 }
405
406 i = 0;
407 m = sizeof(BigBuf);
408 memset(dest,128,m);
409 for(;;) {
410 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
411 SSC_TRANSMIT_HOLDING = 0x43;
412 LED_D_ON();
413 }
414 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
415 dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
416 // we don't care about actual value, only if it's more or less than a
417 // threshold essentially we capture zero crossings for later analysis
418 if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
419 i++;
420 LED_D_OFF();
421 if(i >= m) {
422 break;
423 }
424 }
425 }
426
427 // FSK demodulator
428
429 // sync to first lo-hi transition
430 for( idx=1; idx<m; idx++) {
431 if (dest[idx-1]<dest[idx])
432 lastval=idx;
433 break;
434 }
435 WDT_HIT();
436
437 // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
438 // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
439 // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
440 for( i=0; idx<m; idx++) {
441 if (dest[idx-1]<dest[idx]) {
442 dest[i]=idx-lastval;
443 if (dest[i] <= 8) {
444 dest[i]=1;
445 } else {
446 dest[i]=0;
447 }
448
449 lastval=idx;
450 i++;
451 }
452 }
453 m=i;
454 WDT_HIT();
455
456 // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
457 lastval=dest[0];
458 idx=0;
459 i=0;
460 n=0;
461 for( idx=0; idx<m; idx++) {
462 if (dest[idx]==lastval) {
463 n++;
464 } else {
465 // a bit time is five fc/10 or six fc/8 cycles so figure out how many bits a pattern width represents,
466 // an extra fc/8 pattern preceeds every 4 bits (about 200 cycles) just to complicate things but it gets
467 // swallowed up by rounding
468 // expected results are 1 or 2 bits, any more and it's an invalid manchester encoding
469 // special start of frame markers use invalid manchester states (no transitions) by using sequences
470 // like 111000
471 if (dest[idx-1]) {
472 n=(n+1)/6; // fc/8 in sets of 6
473 } else {
474 n=(n+1)/5; // fc/10 in sets of 5
475 }
476 switch (n) { // stuff appropriate bits in buffer
477 case 0:
478 case 1: // one bit
479 dest[i++]=dest[idx-1];
480 break;
481 case 2: // two bits
482 dest[i++]=dest[idx-1];
483 dest[i++]=dest[idx-1];
484 break;
485 case 3: // 3 bit start of frame markers
486 dest[i++]=dest[idx-1];
487 dest[i++]=dest[idx-1];
488 dest[i++]=dest[idx-1];
489 break;
490 // When a logic 0 is immediately followed by the start of the next transmisson
491 // (special pattern) a pattern of 4 bit duration lengths is created.
492 case 4:
493 dest[i++]=dest[idx-1];
494 dest[i++]=dest[idx-1];
495 dest[i++]=dest[idx-1];
496 dest[i++]=dest[idx-1];
497 break;
498 default: // this shouldn't happen, don't stuff any bits
499 break;
500 }
501 n=0;
502 lastval=dest[idx];
503 }
504 }
505 m=i;
506 WDT_HIT();
507
508 // final loop, go over previously decoded manchester data and decode into usable tag ID
509 // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
510 for( idx=0; idx<m-6; idx++) {
511 // search for a start of frame marker
512 if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) )
513 {
514 found=1;
515 idx+=6;
516 if (found && (hi|lo)) {
517 DbpString("TAG ID");
518 DbpIntegers(hi, lo, (lo>>1)&0xffff);
519 hi=0;
520 lo=0;
521 found=0;
522 }
523 }
524 if (found) {
525 if (dest[idx] && (!dest[idx+1]) ) {
526 hi=(hi<<1)|(lo>>31);
527 lo=(lo<<1)|0;
528 } else if ( (!dest[idx]) && dest[idx+1]) {
529 hi=(hi<<1)|(lo>>31);
530 lo=(lo<<1)|1;
531 } else {
532 found=0;
533 hi=0;
534 lo=0;
535 }
536 idx++;
537 }
538 if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) )
539 {
540 found=1;
541 idx+=6;
542 if (found && (hi|lo)) {
543 DbpString("TAG ID");
544 DbpIntegers(hi, lo, (lo>>1)&0xffff);
545 hi=0;
546 lo=0;
547 found=0;
548 }
549 }
550 }
551 WDT_HIT();
552 }
553 }
554
555 void SimulateTagHfListen(void)
556 {
557 BYTE *dest = (BYTE *)BigBuf;
558 int n = sizeof(BigBuf);
559 BYTE v = 0;
560 int i;
561 int p = 0;
562
563 // We're using this mode just so that I can test it out; the simulated
564 // tag mode would work just as well and be simpler.
565 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP);
566
567 // We need to listen to the high-frequency, peak-detected path.
568 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
569
570 FpgaSetupSsc();
571
572 i = 0;
573 for(;;) {
574 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
575 SSC_TRANSMIT_HOLDING = 0xff;
576 }
577 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
578 BYTE r = (BYTE)SSC_RECEIVE_HOLDING;
579
580 v <<= 1;
581 if(r & 1) {
582 v |= 1;
583 }
584 p++;
585
586 if(p >= 8) {
587 dest[i] = v;
588 v = 0;
589 p = 0;
590 i++;
591
592 if(i >= n) {
593 break;
594 }
595 }
596 }
597 }
598 DbpString("simulate tag (now type bitsamples)");
599 }
600
601 void UsbPacketReceived(BYTE *packet, int len)
602 {
603 UsbCommand *c = (UsbCommand *)packet;
604
605 switch(c->cmd) {
606 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
607 AcquireRawAdcSamples125k(c->ext1);
608 break;
609
610 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
611 AcquireRawAdcSamplesIso15693();
612 break;
613
614 case CMD_BUFF_CLEAR:
615 BufferClear();
616 break;
617
618 case CMD_READER_ISO_15693:
619 ReaderIso15693(c->ext1);
620 break;
621
622 case CMD_SIMTAG_ISO_15693:
623 SimTagIso15693(c->ext1);
624 break;
625
626 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:
627 AcquireRawAdcSamplesIso14443(c->ext1);
628 break;
629
630 case CMD_READ_SRI512_TAG:
631 ReadSRI512Iso14443(c->ext1);
632 break;
633
634 case CMD_READER_ISO_14443a:
635 ReaderIso14443a(c->ext1);
636 break;
637
638 case CMD_SNOOP_ISO_14443:
639 SnoopIso14443();
640 break;
641
642 case CMD_SNOOP_ISO_14443a:
643 SnoopIso14443a();
644 break;
645
646 case CMD_SIMULATE_TAG_HF_LISTEN:
647 SimulateTagHfListen();
648 break;
649
650 case CMD_SIMULATE_TAG_ISO_14443:
651 SimulateIso14443Tag();
652 break;
653
654 case CMD_SIMULATE_TAG_ISO_14443a:
655 SimulateIso14443aTag(c->ext1, c->ext2); // ## Simulate iso14443a tag - pass tag type & UID
656 break;
657
658 case CMD_MEASURE_ANTENNA_TUNING:
659 MeasureAntennaTuning();
660 break;
661
662 case CMD_HID_DEMOD_FSK:
663 CmdHIDdemodFSK(); // Demodulate HID tag
664 break;
665
666 case CMD_HID_SIM_TAG:
667 CmdHIDsimTAG(c->ext1, c->ext2); // Simulate HID tag by ID
668 break;
669
670 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
671 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
672 SpinDelay(200);
673 LED_D_OFF(); // LED D indicates field ON or OFF
674 break;
675
676 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
677 case CMD_DOWNLOAD_RAW_BITS_TI_TYPE: {
678 UsbCommand n;
679 if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {
680 n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;
681 } else {
682 n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;
683 }
684 n.ext1 = c->ext1;
685 memcpy(n.d.asDwords, BigBuf+c->ext1, 12*sizeof(DWORD));
686 UsbSendPacket((BYTE *)&n, sizeof(n));
687 break;
688 }
689 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
690 BYTE *b = (BYTE *)BigBuf;
691 memcpy(b+c->ext1, c->d.asBytes, 48);
692 break;
693 }
694 case CMD_SIMULATE_TAG_125K:
695 LED_A_ON();
696 SimulateTagLowFrequency(c->ext1);
697 LED_A_OFF();
698 break;
699 #ifdef WITH_LCD
700 case CMD_LCD_RESET:
701 LCDReset();
702 break;
703 #endif
704 case CMD_SWEEP_LF:
705 SweepLFrange();
706 break;
707
708 case CMD_SET_LF_DIVISOR:
709 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->ext1);
710 break;
711 #ifdef WITH_LCD
712 case CMD_LCD:
713 LCDSend(c->ext1);
714 break;
715 #endif
716 case CMD_SETUP_WRITE:
717 case CMD_FINISH_WRITE:
718 case CMD_HARDWARE_RESET:
719 USB_D_PLUS_PULLUP_OFF();
720 SpinDelay(1000);
721 SpinDelay(1000);
722 RSTC_CONTROL = RST_CONTROL_KEY | RST_CONTROL_PROCESSOR_RESET;
723 for(;;) {
724 // We're going to reset, and the bootrom will take control.
725 }
726 break;
727
728
729 default:
730 DbpString("unknown command");
731 break;
732 }
733 }
734
735 void AppMain(void)
736 {
737 memset(BigBuf,0,sizeof(BigBuf));
738 SpinDelay(100);
739
740 LED_D_OFF();
741 LED_C_OFF();
742 LED_B_OFF();
743 LED_A_OFF();
744
745 UsbStart();
746
747 // The FPGA gets its clock from us from PCK0 output, so set that up.
748 PIO_PERIPHERAL_B_SEL = (1 << GPIO_PCK0);
749 PIO_DISABLE = (1 << GPIO_PCK0);
750 PMC_SYS_CLK_ENABLE = PMC_SYS_CLK_PROGRAMMABLE_CLK_0;
751 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
752 PMC_PROGRAMMABLE_CLK_0 = PMC_CLK_SELECTION_PLL_CLOCK |
753 PMC_CLK_PRESCALE_DIV_4;
754 PIO_OUTPUT_ENABLE = (1 << GPIO_PCK0);
755
756 // Reset SPI
757 SPI_CONTROL = SPI_CONTROL_RESET;
758 // Reset SSC
759 SSC_CONTROL = SSC_CONTROL_RESET;
760
761 // Load the FPGA image, which we have stored in our flash.
762 FpgaDownloadAndGo();
763
764 #ifdef WITH_LCD
765
766 LCDInit();
767
768 // test text on different colored backgrounds
769 LCDString(" The quick brown fox ", &FONT6x8,1,1+8*0,WHITE ,BLACK );
770 LCDString(" jumped over the ", &FONT6x8,1,1+8*1,BLACK ,WHITE );
771 LCDString(" lazy dog. ", &FONT6x8,1,1+8*2,YELLOW ,RED );
772 LCDString(" AaBbCcDdEeFfGgHhIiJj ", &FONT6x8,1,1+8*3,RED ,GREEN );
773 LCDString(" KkLlMmNnOoPpQqRrSsTt ", &FONT6x8,1,1+8*4,MAGENTA,BLUE );
774 LCDString("UuVvWwXxYyZz0123456789", &FONT6x8,1,1+8*5,BLUE ,YELLOW);
775 LCDString("`-=[]_;',./~!@#$%^&*()", &FONT6x8,1,1+8*6,BLACK ,CYAN );
776 LCDString(" _+{}|:\\\"<>? ",&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
777
778 // color bands
779 LCDFill(0, 1+8* 8, 132, 8, BLACK);
780 LCDFill(0, 1+8* 9, 132, 8, WHITE);
781 LCDFill(0, 1+8*10, 132, 8, RED);
782 LCDFill(0, 1+8*11, 132, 8, GREEN);
783 LCDFill(0, 1+8*12, 132, 8, BLUE);
784 LCDFill(0, 1+8*13, 132, 8, YELLOW);
785 LCDFill(0, 1+8*14, 132, 8, CYAN);
786 LCDFill(0, 1+8*15, 132, 8, MAGENTA);
787
788 #endif
789
790 for(;;) {
791 UsbPoll(FALSE);
792 WDT_HIT();
793 }
794 }
795
796 void SpinDelay(int ms)
797 {
798 int ticks = (48000*ms) >> 10;
799
800 // Borrow a PWM unit for my real-time clock
801 PWM_ENABLE = PWM_CHANNEL(0);
802 // 48 MHz / 1024 gives 46.875 kHz
803 PWM_CH_MODE(0) = PWM_CH_MODE_PRESCALER(10);
804 PWM_CH_DUTY_CYCLE(0) = 0;
805 PWM_CH_PERIOD(0) = 0xffff;
806
807 WORD start = (WORD)PWM_CH_COUNTER(0);
808
809 for(;;) {
810 WORD now = (WORD)PWM_CH_COUNTER(0);
811 if(now == (WORD)(start + ticks)) {
812 return;
813 }
814 WDT_HIT();
815 }
816 }
Impressum, Datenschutz