]> git.zerfleddert.de Git - proxmark3-svn/blob - armsrc/appmain.c
dec71dcde6d479c97d322bbee41abaac2db7b381
[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 <stdlib.h>
11 #include "apps.h"
12 #ifdef WITH_LCD
13 #include "fonts.h"
14 #include "LCD.h"
15 #endif
16
17 // The large multi-purpose buffer, typically used to hold A/D samples,
18 // maybe pre-processed in some way.
19 DWORD BigBuf[16000];
20 int usbattached = 0;
21
22 //=============================================================================
23 // A buffer where we can queue things up to be sent through the FPGA, for
24 // any purpose (fake tag, as reader, whatever). We go MSB first, since that
25 // is the order in which they go out on the wire.
26 //=============================================================================
27
28 BYTE ToSend[256];
29 int ToSendMax;
30 static int ToSendBit;
31
32
33 void BufferClear(void)
34 {
35 memset(BigBuf,0,sizeof(BigBuf));
36 DbpString("Buffer cleared");
37 }
38
39 void ToSendReset(void)
40 {
41 ToSendMax = -1;
42 ToSendBit = 8;
43 }
44
45 void ToSendStuffBit(int b)
46 {
47 if(ToSendBit >= 8) {
48 ToSendMax++;
49 ToSend[ToSendMax] = 0;
50 ToSendBit = 0;
51 }
52
53 if(b) {
54 ToSend[ToSendMax] |= (1 << (7 - ToSendBit));
55 }
56
57 ToSendBit++;
58
59 if(ToSendBit >= sizeof(ToSend)) {
60 ToSendBit = 0;
61 DbpString("ToSendStuffBit overflowed!");
62 }
63 }
64
65 //=============================================================================
66 // Debug print functions, to go out over USB, to the usual PC-side client.
67 //=============================================================================
68
69 void DbpString(char *str)
70 {
71 /* this holds up stuff unless we're connected to usb */
72 // if (!usbattached)
73 // return;
74
75 UsbCommand c;
76 c.cmd = CMD_DEBUG_PRINT_STRING;
77 c.ext1 = strlen(str);
78 memcpy(c.d.asBytes, str, c.ext1);
79
80 UsbSendPacket((BYTE *)&c, sizeof(c));
81 // TODO fix USB so stupid things like this aren't req'd
82 SpinDelay(50);
83 }
84
85 void DbpIntegers(int x1, int x2, int x3)
86 {
87 /* this holds up stuff unless we're connected to usb */
88 // if (!usbattached)
89 // return;
90
91 UsbCommand c;
92 c.cmd = CMD_DEBUG_PRINT_INTEGERS;
93 c.ext1 = x1;
94 c.ext2 = x2;
95 c.ext3 = x3;
96
97 UsbSendPacket((BYTE *)&c, sizeof(c));
98 // XXX
99 SpinDelay(50);
100 }
101
102 void AcquireRawAdcSamples125k(BOOL at134khz)
103 {
104 if(at134khz) {
105 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
106 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
107 } else {
108 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
109 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
110 }
111
112 // Connect the A/D to the peak-detected low-frequency path.
113 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
114
115 // Give it a bit of time for the resonant antenna to settle.
116 SpinDelay(50);
117
118 // Now set up the SSC to get the ADC samples that are now streaming at us.
119 FpgaSetupSsc();
120
121 // Now call the acquisition routine
122 DoAcquisition125k(at134khz);
123 }
124
125 // split into two routines so we can avoid timing issues after sending commands //
126 void DoAcquisition125k(BOOL at134khz)
127 {
128 BYTE *dest = (BYTE *)BigBuf;
129 int n = sizeof(BigBuf);
130 int i;
131
132 memset(dest,0,n);
133 i = 0;
134 for(;;) {
135 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
136 SSC_TRANSMIT_HOLDING = 0x43;
137 LED_D_ON();
138 }
139 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
140 dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
141 i++;
142 LED_D_OFF();
143 if(i >= n) {
144 break;
145 }
146 }
147 }
148 DbpIntegers(dest[0], dest[1], at134khz);
149 }
150
151 void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,BYTE *command)
152 {
153 BOOL at134khz;
154
155 // see if 'h' was specified
156 if(command[strlen((char *) command) - 1] == 'h')
157 at134khz= TRUE;
158 else
159 at134khz= FALSE;
160
161 if(at134khz) {
162 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
163 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
164 } else {
165 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
166 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
167 }
168
169 // Give it a bit of time for the resonant antenna to settle.
170 SpinDelay(50);
171
172 // Now set up the SSC to get the ADC samples that are now streaming at us.
173 FpgaSetupSsc();
174
175 // now modulate the reader field
176 while(*command != '\0' && *command != ' ')
177 {
178 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
179 LED_D_OFF();
180 SpinDelayUs(delay_off);
181 if(at134khz) {
182 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
183 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
184 } else {
185 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
186 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
187 }
188 LED_D_ON();
189 if(*(command++) == '0')
190 SpinDelayUs(period_0);
191 else
192 SpinDelayUs(period_1);
193 }
194 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
195 LED_D_OFF();
196 SpinDelayUs(delay_off);
197 if(at134khz) {
198 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
199 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
200 } else {
201 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
202 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
203 }
204
205 // now do the read
206 DoAcquisition125k(at134khz);
207 }
208
209 //-----------------------------------------------------------------------------
210 // Read a TI-type tag. We assume that the tag has already been illuminated,
211 // and that the exciting signal has been turned off. That means that we just
212 // acquire the `one-bit DAC' bits from the comparator.
213 //-----------------------------------------------------------------------------
214 void AcquireTiType(void)
215 {
216 int i;
217 int n = sizeof(BigBuf);
218
219 // clear buffer
220 memset(BigBuf,0,sizeof(BigBuf));
221
222 // Set up the synchronous serial port
223 PIO_DISABLE = (1<<GPIO_SSC_DIN);
224 PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN);
225
226 SSC_CONTROL = SSC_CONTROL_RESET;
227 SSC_CONTROL = SSC_CONTROL_RX_ENABLE | SSC_CONTROL_TX_ENABLE;
228
229 // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long
230 // 48/2 = 24 MHz clock must be divided by 12
231 SSC_CLOCK_DIVISOR = 12;
232
233 SSC_RECEIVE_CLOCK_MODE = SSC_CLOCK_MODE_SELECT(0);
234 SSC_RECEIVE_FRAME_MODE = SSC_FRAME_MODE_BITS_IN_WORD(32) | SSC_FRAME_MODE_MSB_FIRST;
235 SSC_TRANSMIT_CLOCK_MODE = 0;
236 SSC_TRANSMIT_FRAME_MODE = 0;
237
238 i = 0;
239 for(;;) {
240 if(SSC_STATUS & SSC_STATUS_RX_READY) {
241 BigBuf[i] = SSC_RECEIVE_HOLDING; // store 32 bit values in buffer
242 i++; if(i >= n) return;
243 }
244 WDT_HIT();
245 }
246 }
247
248 void AcquireRawBitsTI(void)
249 {
250 LED_D_ON();
251 // TI tags charge at 134.2Khz
252 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
253 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
254
255 // Charge TI tag for 50ms.
256 SpinDelay(50);
257 LED_D_OFF();
258
259 LED_A_ON();
260 // Place FPGA in passthrough mode so as to stop driving the LF coil,
261 // in this mode the CROSS_LO line connects to SSP_DIN
262 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
263
264 // get TI tag data into the buffer
265 AcquireTiType();
266
267 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
268 LED_A_OFF();
269 }
270
271 //-----------------------------------------------------------------------------
272 // Read an ADC channel and block till it completes, then return the result
273 // in ADC units (0 to 1023). Also a routine to average 32 samples and
274 // return that.
275 //-----------------------------------------------------------------------------
276 static int ReadAdc(int ch)
277 {
278 DWORD d;
279
280 ADC_CONTROL = ADC_CONTROL_RESET;
281 ADC_MODE = ADC_MODE_PRESCALE(32) | ADC_MODE_STARTUP_TIME(16) |
282 ADC_MODE_SAMPLE_HOLD_TIME(8);
283 ADC_CHANNEL_ENABLE = ADC_CHANNEL(ch);
284
285 ADC_CONTROL = ADC_CONTROL_START;
286 while(!(ADC_STATUS & ADC_END_OF_CONVERSION(ch)))
287 ;
288 d = ADC_CHANNEL_DATA(ch);
289
290 return d;
291 }
292
293 static int AvgAdc(int ch)
294 {
295 int i;
296 int a = 0;
297
298 for(i = 0; i < 32; i++) {
299 a += ReadAdc(ch);
300 }
301
302 return (a + 15) >> 5;
303 }
304
305 void MeasureAntennaTuning(void)
306 {
307 BYTE *dest = (BYTE *)BigBuf;
308 int i, ptr = 0, adcval = 0, peak = 0, peakv = 0, peakf = 0;;
309 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
310
311 UsbCommand c;
312
313 DbpString("Measuring antenna characteristics, please wait.");
314 memset(BigBuf,0,sizeof(BigBuf));
315
316 /*
317 * Sweeps the useful LF range of the proxmark from
318 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
319 * read the voltage in the antenna, the result left
320 * in the buffer is a graph which should clearly show
321 * the resonating frequency of your LF antenna
322 * ( hopefully around 95 if it is tuned to 125kHz!)
323 */
324 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
325 for (i=255; i>19; i--) {
326 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
327 SpinDelay(20);
328 // Vref = 3.3V, and a 10000:240 voltage divider on the input
329 // can measure voltages up to 137500 mV
330 adcval = ((137500 * AvgAdc(ADC_CHAN_LF)) >> 10);
331 if (i==95) vLf125 = adcval; // voltage at 125Khz
332 if (i==89) vLf134 = adcval; // voltage at 134Khz
333
334 dest[i] = adcval>>8; // scale int to fit in byte for graphing purposes
335 if(dest[i] > peak) {
336 peakv = adcval;
337 peak = dest[i];
338 peakf = i;
339 ptr = i;
340 }
341 }
342
343 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
344 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
345 SpinDelay(20);
346 // Vref = 3300mV, and an 10:1 voltage divider on the input
347 // can measure voltages up to 33000 mV
348 vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
349
350 c.cmd = CMD_MEASURED_ANTENNA_TUNING;
351 c.ext1 = (vLf125 << 0) | (vLf134 << 16);
352 c.ext2 = vHf;
353 c.ext3 = peakf | (peakv << 16);
354 UsbSendPacket((BYTE *)&c, sizeof(c));
355 }
356
357 void SimulateTagLowFrequency(int period, int ledcontrol)
358 {
359 int i;
360 BYTE *tab = (BYTE *)BigBuf;
361
362 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_SIMULATOR);
363
364 PIO_ENABLE = (1 << GPIO_SSC_DOUT) | (1 << GPIO_SSC_CLK);
365
366 PIO_OUTPUT_ENABLE = (1 << GPIO_SSC_DOUT);
367 PIO_OUTPUT_DISABLE = (1 << GPIO_SSC_CLK);
368
369 #define SHORT_COIL() LOW(GPIO_SSC_DOUT)
370 #define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
371
372 i = 0;
373 for(;;) {
374 while(!(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK))) {
375 if(BUTTON_PRESS()) {
376 DbpString("Stopped");
377 return;
378 }
379 WDT_HIT();
380 }
381
382 if (ledcontrol)
383 LED_D_ON();
384
385 if(tab[i])
386 OPEN_COIL();
387 else
388 SHORT_COIL();
389
390 if (ledcontrol)
391 LED_D_OFF();
392
393 while(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK)) {
394 if(BUTTON_PRESS()) {
395 DbpString("Stopped");
396 return;
397 }
398 WDT_HIT();
399 }
400
401 i++;
402 if(i == period) i = 0;
403 }
404 }
405
406 // compose fc/8 fc/10 waveform
407 static void fc(int c, int *n) {
408 BYTE *dest = (BYTE *)BigBuf;
409 int idx;
410
411 // for when we want an fc8 pattern every 4 logical bits
412 if(c==0) {
413 dest[((*n)++)]=1;
414 dest[((*n)++)]=1;
415 dest[((*n)++)]=0;
416 dest[((*n)++)]=0;
417 dest[((*n)++)]=0;
418 dest[((*n)++)]=0;
419 dest[((*n)++)]=0;
420 dest[((*n)++)]=0;
421 }
422 // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples
423 if(c==8) {
424 for (idx=0; idx<6; idx++) {
425 dest[((*n)++)]=1;
426 dest[((*n)++)]=1;
427 dest[((*n)++)]=0;
428 dest[((*n)++)]=0;
429 dest[((*n)++)]=0;
430 dest[((*n)++)]=0;
431 dest[((*n)++)]=0;
432 dest[((*n)++)]=0;
433 }
434 }
435
436 // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
437 if(c==10) {
438 for (idx=0; idx<5; idx++) {
439 dest[((*n)++)]=1;
440 dest[((*n)++)]=1;
441 dest[((*n)++)]=1;
442 dest[((*n)++)]=0;
443 dest[((*n)++)]=0;
444 dest[((*n)++)]=0;
445 dest[((*n)++)]=0;
446 dest[((*n)++)]=0;
447 dest[((*n)++)]=0;
448 dest[((*n)++)]=0;
449 }
450 }
451 }
452
453 // prepare a waveform pattern in the buffer based on the ID given then
454 // simulate a HID tag until the button is pressed
455 static void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
456 {
457 int n=0, i=0;
458 /*
459 HID tag bitstream format
460 The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
461 A 1 bit is represented as 6 fc8 and 5 fc10 patterns
462 A 0 bit is represented as 5 fc10 and 6 fc8 patterns
463 A fc8 is inserted before every 4 bits
464 A special start of frame pattern is used consisting a0b0 where a and b are neither 0
465 nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10)
466 */
467
468 if (hi>0xFFF) {
469 DbpString("Tags can only have 44 bits.");
470 return;
471 }
472 fc(0,&n);
473 // special start of frame marker containing invalid bit sequences
474 fc(8, &n); fc(8, &n); // invalid
475 fc(8, &n); fc(10, &n); // logical 0
476 fc(10, &n); fc(10, &n); // invalid
477 fc(8, &n); fc(10, &n); // logical 0
478
479 WDT_HIT();
480 // manchester encode bits 43 to 32
481 for (i=11; i>=0; i--) {
482 if ((i%4)==3) fc(0,&n);
483 if ((hi>>i)&1) {
484 fc(10, &n); fc(8, &n); // low-high transition
485 } else {
486 fc(8, &n); fc(10, &n); // high-low transition
487 }
488 }
489
490 WDT_HIT();
491 // manchester encode bits 31 to 0
492 for (i=31; i>=0; i--) {
493 if ((i%4)==3) fc(0,&n);
494 if ((lo>>i)&1) {
495 fc(10, &n); fc(8, &n); // low-high transition
496 } else {
497 fc(8, &n); fc(10, &n); // high-low transition
498 }
499 }
500
501 if (ledcontrol)
502 LED_A_ON();
503 SimulateTagLowFrequency(n, ledcontrol);
504
505 if (ledcontrol)
506 LED_A_OFF();
507 }
508
509 // loop to capture raw HID waveform then FSK demodulate the TAG ID from it
510 static void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
511 {
512 BYTE *dest = (BYTE *)BigBuf;
513 int m=0, n=0, i=0, idx=0, found=0, lastval=0;
514 DWORD hi=0, lo=0;
515
516 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
517 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
518
519 // Connect the A/D to the peak-detected low-frequency path.
520 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
521
522 // Give it a bit of time for the resonant antenna to settle.
523 SpinDelay(50);
524
525 // Now set up the SSC to get the ADC samples that are now streaming at us.
526 FpgaSetupSsc();
527
528 for(;;) {
529 WDT_HIT();
530 if (ledcontrol)
531 LED_A_ON();
532 if(BUTTON_PRESS()) {
533 DbpString("Stopped");
534 if (ledcontrol)
535 LED_A_OFF();
536 return;
537 }
538
539 i = 0;
540 m = sizeof(BigBuf);
541 memset(dest,128,m);
542 for(;;) {
543 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
544 SSC_TRANSMIT_HOLDING = 0x43;
545 if (ledcontrol)
546 LED_D_ON();
547 }
548 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
549 dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
550 // we don't care about actual value, only if it's more or less than a
551 // threshold essentially we capture zero crossings for later analysis
552 if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
553 i++;
554 if (ledcontrol)
555 LED_D_OFF();
556 if(i >= m) {
557 break;
558 }
559 }
560 }
561
562 // FSK demodulator
563
564 // sync to first lo-hi transition
565 for( idx=1; idx<m; idx++) {
566 if (dest[idx-1]<dest[idx])
567 lastval=idx;
568 break;
569 }
570 WDT_HIT();
571
572 // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
573 // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
574 // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
575 for( i=0; idx<m; idx++) {
576 if (dest[idx-1]<dest[idx]) {
577 dest[i]=idx-lastval;
578 if (dest[i] <= 8) {
579 dest[i]=1;
580 } else {
581 dest[i]=0;
582 }
583
584 lastval=idx;
585 i++;
586 }
587 }
588 m=i;
589 WDT_HIT();
590
591 // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
592 lastval=dest[0];
593 idx=0;
594 i=0;
595 n=0;
596 for( idx=0; idx<m; idx++) {
597 if (dest[idx]==lastval) {
598 n++;
599 } else {
600 // a bit time is five fc/10 or six fc/8 cycles so figure out how many bits a pattern width represents,
601 // an extra fc/8 pattern preceeds every 4 bits (about 200 cycles) just to complicate things but it gets
602 // swallowed up by rounding
603 // expected results are 1 or 2 bits, any more and it's an invalid manchester encoding
604 // special start of frame markers use invalid manchester states (no transitions) by using sequences
605 // like 111000
606 if (dest[idx-1]) {
607 n=(n+1)/6; // fc/8 in sets of 6
608 } else {
609 n=(n+1)/5; // fc/10 in sets of 5
610 }
611 switch (n) { // stuff appropriate bits in buffer
612 case 0:
613 case 1: // one bit
614 dest[i++]=dest[idx-1];
615 break;
616 case 2: // two bits
617 dest[i++]=dest[idx-1];
618 dest[i++]=dest[idx-1];
619 break;
620 case 3: // 3 bit start of frame markers
621 dest[i++]=dest[idx-1];
622 dest[i++]=dest[idx-1];
623 dest[i++]=dest[idx-1];
624 break;
625 // When a logic 0 is immediately followed by the start of the next transmisson
626 // (special pattern) a pattern of 4 bit duration lengths is created.
627 case 4:
628 dest[i++]=dest[idx-1];
629 dest[i++]=dest[idx-1];
630 dest[i++]=dest[idx-1];
631 dest[i++]=dest[idx-1];
632 break;
633 default: // this shouldn't happen, don't stuff any bits
634 break;
635 }
636 n=0;
637 lastval=dest[idx];
638 }
639 }
640 m=i;
641 WDT_HIT();
642
643 // final loop, go over previously decoded manchester data and decode into usable tag ID
644 // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
645 for( idx=0; idx<m-6; idx++) {
646 // search for a start of frame marker
647 if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) )
648 {
649 found=1;
650 idx+=6;
651 if (found && (hi|lo)) {
652 DbpString("TAG ID");
653 DbpIntegers(hi, lo, (lo>>1)&0xffff);
654 /* if we're only looking for one tag */
655 if (findone)
656 {
657 *high = hi;
658 *low = lo;
659 return;
660 }
661 hi=0;
662 lo=0;
663 found=0;
664 }
665 }
666 if (found) {
667 if (dest[idx] && (!dest[idx+1]) ) {
668 hi=(hi<<1)|(lo>>31);
669 lo=(lo<<1)|0;
670 } else if ( (!dest[idx]) && dest[idx+1]) {
671 hi=(hi<<1)|(lo>>31);
672 lo=(lo<<1)|1;
673 } else {
674 found=0;
675 hi=0;
676 lo=0;
677 }
678 idx++;
679 }
680 if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) )
681 {
682 found=1;
683 idx+=6;
684 if (found && (hi|lo)) {
685 DbpString("TAG ID");
686 DbpIntegers(hi, lo, (lo>>1)&0xffff);
687 /* if we're only looking for one tag */
688 if (findone)
689 {
690 *high = hi;
691 *low = lo;
692 return;
693 }
694 hi=0;
695 lo=0;
696 found=0;
697 }
698 }
699 }
700 WDT_HIT();
701 }
702 }
703
704 void SimulateTagHfListen(void)
705 {
706 BYTE *dest = (BYTE *)BigBuf;
707 int n = sizeof(BigBuf);
708 BYTE v = 0;
709 int i;
710 int p = 0;
711
712 // We're using this mode just so that I can test it out; the simulated
713 // tag mode would work just as well and be simpler.
714 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP);
715
716 // We need to listen to the high-frequency, peak-detected path.
717 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
718
719 FpgaSetupSsc();
720
721 i = 0;
722 for(;;) {
723 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
724 SSC_TRANSMIT_HOLDING = 0xff;
725 }
726 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
727 BYTE r = (BYTE)SSC_RECEIVE_HOLDING;
728
729 v <<= 1;
730 if(r & 1) {
731 v |= 1;
732 }
733 p++;
734
735 if(p >= 8) {
736 dest[i] = v;
737 v = 0;
738 p = 0;
739 i++;
740
741 if(i >= n) {
742 break;
743 }
744 }
745 }
746 }
747 DbpString("simulate tag (now type bitsamples)");
748 }
749
750 void UsbPacketReceived(BYTE *packet, int len)
751 {
752 UsbCommand *c = (UsbCommand *)packet;
753
754 switch(c->cmd) {
755 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
756 AcquireRawAdcSamples125k(c->ext1);
757 break;
758
759 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
760 ModThenAcquireRawAdcSamples125k(c->ext1,c->ext2,c->ext3,c->d.asBytes);
761 break;
762
763 case CMD_ACQUIRE_RAW_BITS_TI_TYPE:
764 AcquireRawBitsTI();
765 break;
766
767 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
768 AcquireRawAdcSamplesIso15693();
769 break;
770
771 case CMD_BUFF_CLEAR:
772 BufferClear();
773 break;
774
775 case CMD_READER_ISO_15693:
776 ReaderIso15693(c->ext1);
777 break;
778
779 case CMD_SIMTAG_ISO_15693:
780 SimTagIso15693(c->ext1);
781 break;
782
783 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:
784 AcquireRawAdcSamplesIso14443(c->ext1);
785 break;
786
787 case CMD_READ_SRI512_TAG:
788 ReadSRI512Iso14443(c->ext1);
789 break;
790
791 case CMD_READER_ISO_14443a:
792 ReaderIso14443a(c->ext1);
793 break;
794
795 case CMD_SNOOP_ISO_14443:
796 SnoopIso14443();
797 break;
798
799 case CMD_SNOOP_ISO_14443a:
800 SnoopIso14443a();
801 break;
802
803 case CMD_SIMULATE_TAG_HF_LISTEN:
804 SimulateTagHfListen();
805 break;
806
807 case CMD_SIMULATE_TAG_ISO_14443:
808 SimulateIso14443Tag();
809 break;
810
811 case CMD_SIMULATE_TAG_ISO_14443a:
812 SimulateIso14443aTag(c->ext1, c->ext2); // ## Simulate iso14443a tag - pass tag type & UID
813 break;
814
815 case CMD_MEASURE_ANTENNA_TUNING:
816 MeasureAntennaTuning();
817 break;
818
819 case CMD_LISTEN_READER_FIELD:
820 ListenReaderField(c->ext1);
821 break;
822
823 case CMD_HID_DEMOD_FSK:
824 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
825 break;
826
827 case CMD_HID_SIM_TAG:
828 CmdHIDsimTAG(c->ext1, c->ext2, 1); // Simulate HID tag by ID
829 break;
830
831 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
832 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
833 SpinDelay(200);
834 LED_D_OFF(); // LED D indicates field ON or OFF
835 break;
836
837 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
838 case CMD_DOWNLOAD_RAW_BITS_TI_TYPE: {
839 UsbCommand n;
840 if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {
841 n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;
842 } else {
843 n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;
844 }
845 n.ext1 = c->ext1;
846 memcpy(n.d.asDwords, BigBuf+c->ext1, 12*sizeof(DWORD));
847 UsbSendPacket((BYTE *)&n, sizeof(n));
848 break;
849 }
850 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
851 BYTE *b = (BYTE *)BigBuf;
852 memcpy(b+c->ext1, c->d.asBytes, 48);
853 break;
854 }
855 case CMD_SIMULATE_TAG_125K:
856 LED_A_ON();
857 SimulateTagLowFrequency(c->ext1, 1);
858 LED_A_OFF();
859 break;
860 #ifdef WITH_LCD
861 case CMD_LCD_RESET:
862 LCDReset();
863 break;
864 #endif
865 case CMD_READ_MEM:
866 ReadMem(c->ext1);
867 break;
868 case CMD_SET_LF_DIVISOR:
869 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->ext1);
870 break;
871 #ifdef WITH_LCD
872 case CMD_LCD:
873 LCDSend(c->ext1);
874 break;
875 #endif
876 case CMD_SETUP_WRITE:
877 case CMD_FINISH_WRITE:
878 case CMD_HARDWARE_RESET:
879 USB_D_PLUS_PULLUP_OFF();
880 SpinDelay(1000);
881 SpinDelay(1000);
882 RSTC_CONTROL = RST_CONTROL_KEY | RST_CONTROL_PROCESSOR_RESET;
883 for(;;) {
884 // We're going to reset, and the bootrom will take control.
885 }
886 break;
887
888
889 default:
890 DbpString("unknown command");
891 break;
892 }
893 }
894
895 void ReadMem(int addr)
896 {
897 const DWORD *data = ((DWORD *)addr);
898 int i;
899
900 DbpString("Reading memory at address");
901 DbpIntegers(0, 0, addr);
902 for (i = 0; i < 8; i+= 2)
903 DbpIntegers(0, data[i], data[i+1]);
904 }
905
906 void AppMain(void)
907 {
908 memset(BigBuf,0,sizeof(BigBuf));
909 SpinDelay(100);
910
911 LED_D_OFF();
912 LED_C_OFF();
913 LED_B_OFF();
914 LED_A_OFF();
915
916 UsbStart();
917
918 // The FPGA gets its clock from us from PCK0 output, so set that up.
919 PIO_PERIPHERAL_B_SEL = (1 << GPIO_PCK0);
920 PIO_DISABLE = (1 << GPIO_PCK0);
921 PMC_SYS_CLK_ENABLE = PMC_SYS_CLK_PROGRAMMABLE_CLK_0;
922 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
923 PMC_PROGRAMMABLE_CLK_0 = PMC_CLK_SELECTION_PLL_CLOCK |
924 PMC_CLK_PRESCALE_DIV_4;
925 PIO_OUTPUT_ENABLE = (1 << GPIO_PCK0);
926
927 // Reset SPI
928 SPI_CONTROL = SPI_CONTROL_RESET;
929 // Reset SSC
930 SSC_CONTROL = SSC_CONTROL_RESET;
931
932 // Load the FPGA image, which we have stored in our flash.
933 FpgaDownloadAndGo();
934
935 #ifdef WITH_LCD
936
937 LCDInit();
938
939 // test text on different colored backgrounds
940 LCDString(" The quick brown fox ", &FONT6x8,1,1+8*0,WHITE ,BLACK );
941 LCDString(" jumped over the ", &FONT6x8,1,1+8*1,BLACK ,WHITE );
942 LCDString(" lazy dog. ", &FONT6x8,1,1+8*2,YELLOW ,RED );
943 LCDString(" AaBbCcDdEeFfGgHhIiJj ", &FONT6x8,1,1+8*3,RED ,GREEN );
944 LCDString(" KkLlMmNnOoPpQqRrSsTt ", &FONT6x8,1,1+8*4,MAGENTA,BLUE );
945 LCDString("UuVvWwXxYyZz0123456789", &FONT6x8,1,1+8*5,BLUE ,YELLOW);
946 LCDString("`-=[]_;',./~!@#$%^&*()", &FONT6x8,1,1+8*6,BLACK ,CYAN );
947 LCDString(" _+{}|:\\\"<>? ",&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
948
949 // color bands
950 LCDFill(0, 1+8* 8, 132, 8, BLACK);
951 LCDFill(0, 1+8* 9, 132, 8, WHITE);
952 LCDFill(0, 1+8*10, 132, 8, RED);
953 LCDFill(0, 1+8*11, 132, 8, GREEN);
954 LCDFill(0, 1+8*12, 132, 8, BLUE);
955 LCDFill(0, 1+8*13, 132, 8, YELLOW);
956 LCDFill(0, 1+8*14, 132, 8, CYAN);
957 LCDFill(0, 1+8*15, 132, 8, MAGENTA);
958
959 #endif
960
961 for(;;) {
962 usbattached = UsbPoll(FALSE);
963 WDT_HIT();
964
965 if (BUTTON_HELD(1000) > 0)
966 SamyRun();
967 }
968 }
969
970
971 // samy's sniff and repeat routine
972 void SamyRun()
973 {
974 DbpString("Stand-alone mode! No PC necessary.");
975
976 // 3 possible options? no just 2 for now
977 #define OPTS 2
978
979 int high[OPTS], low[OPTS];
980
981 // Oooh pretty -- notify user we're in elite samy mode now
982 LED(LED_RED, 200);
983 LED(LED_ORANGE, 200);
984 LED(LED_GREEN, 200);
985 LED(LED_ORANGE, 200);
986 LED(LED_RED, 200);
987 LED(LED_ORANGE, 200);
988 LED(LED_GREEN, 200);
989 LED(LED_ORANGE, 200);
990 LED(LED_RED, 200);
991
992 int selected = 0;
993 int playing = 0;
994
995 // Turn on selected LED
996 LED(selected + 1, 0);
997
998 for (;;)
999 {
1000 usbattached = UsbPoll(FALSE);
1001 WDT_HIT();
1002
1003 // Was our button held down or pressed?
1004 int button_pressed = BUTTON_HELD(1000);
1005 SpinDelay(300);
1006
1007 // Button was held for a second, begin recording
1008 if (button_pressed > 0)
1009 {
1010 LEDsoff();
1011 LED(selected + 1, 0);
1012 LED(LED_RED2, 0);
1013
1014 // record
1015 DbpString("Starting recording");
1016
1017 // wait for button to be released
1018 while(BUTTON_PRESS())
1019 WDT_HIT();
1020
1021 /* need this delay to prevent catching some weird data */
1022 SpinDelay(500);
1023
1024 CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
1025 DbpString("Recorded");
1026 DbpIntegers(selected, high[selected], low[selected]);
1027
1028 LEDsoff();
1029 LED(selected + 1, 0);
1030 // Finished recording
1031
1032 // If we were previously playing, set playing off
1033 // so next button push begins playing what we recorded
1034 playing = 0;
1035 }
1036
1037 // Change where to record (or begin playing)
1038 else if (button_pressed)
1039 {
1040 // Next option if we were previously playing
1041 if (playing)
1042 selected = (selected + 1) % OPTS;
1043 playing = !playing;
1044
1045 LEDsoff();
1046 LED(selected + 1, 0);
1047
1048 // Begin transmitting
1049 if (playing)
1050 {
1051 LED(LED_GREEN, 0);
1052 DbpString("Playing");
1053 // wait for button to be released
1054 while(BUTTON_PRESS())
1055 WDT_HIT();
1056 DbpIntegers(selected, high[selected], low[selected]);
1057 CmdHIDsimTAG(high[selected], low[selected], 0);
1058 DbpString("Done playing");
1059 if (BUTTON_HELD(1000) > 0)
1060 {
1061 DbpString("Exiting");
1062 LEDsoff();
1063 return;
1064 }
1065
1066 /* We pressed a button so ignore it here with a delay */
1067 SpinDelay(300);
1068
1069 // when done, we're done playing, move to next option
1070 selected = (selected + 1) % OPTS;
1071 playing = !playing;
1072 LEDsoff();
1073 LED(selected + 1, 0);
1074 }
1075 else
1076 while(BUTTON_PRESS())
1077 WDT_HIT();
1078 }
1079 }
1080 }
1081
1082
1083 // listen for external reader
1084 void ListenReaderField(int limit)
1085 {
1086 int lf_av, lf_av_new, lf_baseline= 0, lf_count= 0;
1087 int hf_av, hf_av_new, hf_baseline= 0, hf_count= 0;
1088
1089 #define LF_ONLY 1
1090 #define HF_ONLY 2
1091
1092 LED_A_OFF();
1093 LED_B_OFF();
1094 LED_C_OFF();
1095 LED_D_OFF();
1096
1097 lf_av= ReadAdc(ADC_CHAN_LF);
1098
1099 if(limit != HF_ONLY)
1100 {
1101 DbpString("LF 125/134 Baseline:");
1102 DbpIntegers(lf_av,0,0);
1103 lf_baseline= lf_av;
1104 }
1105
1106 hf_av= ReadAdc(ADC_CHAN_HF);
1107
1108
1109 if (limit != LF_ONLY)
1110 {
1111 DbpString("HF 13.56 Baseline:");
1112 DbpIntegers(hf_av,0,0);
1113 hf_baseline= hf_av;
1114 }
1115
1116 for(;;)
1117 {
1118 if(BUTTON_PRESS())
1119 {
1120 DbpString("Stopped");
1121 LED_B_OFF();
1122 LED_D_OFF();
1123 return;
1124 }
1125 WDT_HIT();
1126
1127
1128 if (limit != HF_ONLY)
1129 {
1130 if (abs(lf_av - lf_baseline) > 10)
1131 LED_D_ON();
1132 else
1133 LED_D_OFF();
1134 ++lf_count;
1135 lf_av_new= ReadAdc(ADC_CHAN_LF);
1136 // see if there's a significant change
1137 if(abs(lf_av - lf_av_new) > 10)
1138 {
1139 DbpString("LF 125/134 Field Change:");
1140 DbpIntegers(lf_av,lf_av_new,lf_count);
1141 lf_av= lf_av_new;
1142 lf_count= 0;
1143 }
1144 }
1145
1146 if (limit != LF_ONLY)
1147 {
1148 if (abs(hf_av - hf_baseline) > 10)
1149 LED_B_ON();
1150 else
1151 LED_B_OFF();
1152 ++hf_count;
1153 hf_av_new= ReadAdc(ADC_CHAN_HF);
1154 // see if there's a significant change
1155 if(abs(hf_av - hf_av_new) > 10)
1156 {
1157 DbpString("HF 13.56 Field Change:");
1158 DbpIntegers(hf_av,hf_av_new,hf_count);
1159 hf_av= hf_av_new;
1160 hf_count= 0;
1161 }
1162 }
1163 }
1164 }
Impressum, Datenschutz