]> cvs.zerfleddert.de Git - proxmark3-svn/blob - armsrc/appmain.c
make grid function linux friendly
[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 void AcquireTiType(void)
210 {
211 int i;
212 int n = 5000;
213
214 // clear buffer
215 memset(BigBuf,0,sizeof(BigBuf));
216
217 // Set up the synchronous serial port
218 PIO_DISABLE = (1<<GPIO_SSC_DIN);
219 PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN);
220
221 // steal this pin from the SSP and use it to control the modulation
222 PIO_ENABLE = (1<<GPIO_SSC_DOUT);
223 PIO_OUTPUT_ENABLE = (1<<GPIO_SSC_DOUT);
224
225 SSC_CONTROL = SSC_CONTROL_RESET;
226 SSC_CONTROL = SSC_CONTROL_RX_ENABLE | SSC_CONTROL_TX_ENABLE;
227
228 // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long
229 // 48/2 = 24 MHz clock must be divided by 12
230 SSC_CLOCK_DIVISOR = 12;
231
232 SSC_RECEIVE_CLOCK_MODE = SSC_CLOCK_MODE_SELECT(0);
233 SSC_RECEIVE_FRAME_MODE = SSC_FRAME_MODE_BITS_IN_WORD(32) | SSC_FRAME_MODE_MSB_FIRST;
234 SSC_TRANSMIT_CLOCK_MODE = 0;
235 SSC_TRANSMIT_FRAME_MODE = 0;
236
237 LED_D_ON();
238
239 // modulate antenna
240 PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
241
242 // Charge TI tag for 50ms.
243 SpinDelay(50);
244
245 // stop modulating antenna and listen
246 PIO_OUTPUT_DATA_CLEAR = (1<<GPIO_SSC_DOUT);
247
248 LED_D_OFF();
249
250 i = 0;
251 for(;;) {
252 if(SSC_STATUS & SSC_STATUS_RX_READY) {
253 BigBuf[i] = SSC_RECEIVE_HOLDING; // store 32 bit values in buffer
254 i++; if(i >= n) return;
255 }
256 WDT_HIT();
257 }
258
259 // return stolen pin ro SSP
260 PIO_DISABLE = (1<<GPIO_SSC_DOUT);
261 PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN) | (1<<GPIO_SSC_DOUT);
262 }
263
264 void AcquireRawBitsTI(void)
265 {
266 LED_D_ON();
267 // TI tags charge at 134.2Khz
268 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
269 // Place FPGA in passthrough mode, in this mode the CROSS_LO line
270 // connects to SSP_DIN and the SSP_DOUT logic level controls
271 // whether we're modulating the antenna (high)
272 // or listening to the antenna (low)
273 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
274
275 // get TI tag data into the buffer
276 AcquireTiType();
277
278 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
279 }
280
281 //-----------------------------------------------------------------------------
282 // Read an ADC channel and block till it completes, then return the result
283 // in ADC units (0 to 1023). Also a routine to average 32 samples and
284 // return that.
285 //-----------------------------------------------------------------------------
286 static int ReadAdc(int ch)
287 {
288 DWORD d;
289
290 ADC_CONTROL = ADC_CONTROL_RESET;
291 ADC_MODE = ADC_MODE_PRESCALE(32) | ADC_MODE_STARTUP_TIME(16) |
292 ADC_MODE_SAMPLE_HOLD_TIME(8);
293 ADC_CHANNEL_ENABLE = ADC_CHANNEL(ch);
294
295 ADC_CONTROL = ADC_CONTROL_START;
296 while(!(ADC_STATUS & ADC_END_OF_CONVERSION(ch)))
297 ;
298 d = ADC_CHANNEL_DATA(ch);
299
300 return d;
301 }
302
303 static int AvgAdc(int ch)
304 {
305 int i;
306 int a = 0;
307
308 for(i = 0; i < 32; i++) {
309 a += ReadAdc(ch);
310 }
311
312 return (a + 15) >> 5;
313 }
314
315 void MeasureAntennaTuning(void)
316 {
317 BYTE *dest = (BYTE *)BigBuf;
318 int i, ptr = 0, adcval = 0, peak = 0, peakv = 0, peakf = 0;;
319 int vLf125 = 0, vLf134 = 0, vHf = 0; // in mV
320
321 UsbCommand c;
322
323 DbpString("Measuring antenna characteristics, please wait.");
324 memset(BigBuf,0,sizeof(BigBuf));
325
326 /*
327 * Sweeps the useful LF range of the proxmark from
328 * 46.8kHz (divisor=255) to 600kHz (divisor=19) and
329 * read the voltage in the antenna, the result left
330 * in the buffer is a graph which should clearly show
331 * the resonating frequency of your LF antenna
332 * ( hopefully around 95 if it is tuned to 125kHz!)
333 */
334 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
335 for (i=255; i>19; i--) {
336 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, i);
337 SpinDelay(20);
338 // Vref = 3.3V, and a 10000:240 voltage divider on the input
339 // can measure voltages up to 137500 mV
340 adcval = ((137500 * AvgAdc(ADC_CHAN_LF)) >> 10);
341 if (i==95) vLf125 = adcval; // voltage at 125Khz
342 if (i==89) vLf134 = adcval; // voltage at 134Khz
343
344 dest[i] = adcval>>8; // scale int to fit in byte for graphing purposes
345 if(dest[i] > peak) {
346 peakv = adcval;
347 peak = dest[i];
348 peakf = i;
349 ptr = i;
350 }
351 }
352
353 // Let the FPGA drive the high-frequency antenna around 13.56 MHz.
354 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR);
355 SpinDelay(20);
356 // Vref = 3300mV, and an 10:1 voltage divider on the input
357 // can measure voltages up to 33000 mV
358 vHf = (33000 * AvgAdc(ADC_CHAN_HF)) >> 10;
359
360 c.cmd = CMD_MEASURED_ANTENNA_TUNING;
361 c.ext1 = (vLf125 << 0) | (vLf134 << 16);
362 c.ext2 = vHf;
363 c.ext3 = peakf | (peakv << 16);
364 UsbSendPacket((BYTE *)&c, sizeof(c));
365 }
366
367 void SimulateTagLowFrequency(int period, int ledcontrol)
368 {
369 int i;
370 BYTE *tab = (BYTE *)BigBuf;
371
372 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_SIMULATOR);
373
374 PIO_ENABLE = (1 << GPIO_SSC_DOUT) | (1 << GPIO_SSC_CLK);
375
376 PIO_OUTPUT_ENABLE = (1 << GPIO_SSC_DOUT);
377 PIO_OUTPUT_DISABLE = (1 << GPIO_SSC_CLK);
378
379 #define SHORT_COIL() LOW(GPIO_SSC_DOUT)
380 #define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
381
382 i = 0;
383 for(;;) {
384 while(!(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK))) {
385 if(BUTTON_PRESS()) {
386 DbpString("Stopped");
387 return;
388 }
389 WDT_HIT();
390 }
391
392 if (ledcontrol)
393 LED_D_ON();
394
395 if(tab[i])
396 OPEN_COIL();
397 else
398 SHORT_COIL();
399
400 if (ledcontrol)
401 LED_D_OFF();
402
403 while(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK)) {
404 if(BUTTON_PRESS()) {
405 DbpString("Stopped");
406 return;
407 }
408 WDT_HIT();
409 }
410
411 i++;
412 if(i == period) i = 0;
413 }
414 }
415
416 // compose fc/8 fc/10 waveform
417 static void fc(int c, int *n) {
418 BYTE *dest = (BYTE *)BigBuf;
419 int idx;
420
421 // for when we want an fc8 pattern every 4 logical bits
422 if(c==0) {
423 dest[((*n)++)]=1;
424 dest[((*n)++)]=1;
425 dest[((*n)++)]=0;
426 dest[((*n)++)]=0;
427 dest[((*n)++)]=0;
428 dest[((*n)++)]=0;
429 dest[((*n)++)]=0;
430 dest[((*n)++)]=0;
431 }
432 // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples
433 if(c==8) {
434 for (idx=0; idx<6; idx++) {
435 dest[((*n)++)]=1;
436 dest[((*n)++)]=1;
437 dest[((*n)++)]=0;
438 dest[((*n)++)]=0;
439 dest[((*n)++)]=0;
440 dest[((*n)++)]=0;
441 dest[((*n)++)]=0;
442 dest[((*n)++)]=0;
443 }
444 }
445
446 // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
447 if(c==10) {
448 for (idx=0; idx<5; idx++) {
449 dest[((*n)++)]=1;
450 dest[((*n)++)]=1;
451 dest[((*n)++)]=1;
452 dest[((*n)++)]=0;
453 dest[((*n)++)]=0;
454 dest[((*n)++)]=0;
455 dest[((*n)++)]=0;
456 dest[((*n)++)]=0;
457 dest[((*n)++)]=0;
458 dest[((*n)++)]=0;
459 }
460 }
461 }
462
463 // prepare a waveform pattern in the buffer based on the ID given then
464 // simulate a HID tag until the button is pressed
465 static void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
466 {
467 int n=0, i=0;
468 /*
469 HID tag bitstream format
470 The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
471 A 1 bit is represented as 6 fc8 and 5 fc10 patterns
472 A 0 bit is represented as 5 fc10 and 6 fc8 patterns
473 A fc8 is inserted before every 4 bits
474 A special start of frame pattern is used consisting a0b0 where a and b are neither 0
475 nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10)
476 */
477
478 if (hi>0xFFF) {
479 DbpString("Tags can only have 44 bits.");
480 return;
481 }
482 fc(0,&n);
483 // special start of frame marker containing invalid bit sequences
484 fc(8, &n); fc(8, &n); // invalid
485 fc(8, &n); fc(10, &n); // logical 0
486 fc(10, &n); fc(10, &n); // invalid
487 fc(8, &n); fc(10, &n); // logical 0
488
489 WDT_HIT();
490 // manchester encode bits 43 to 32
491 for (i=11; i>=0; i--) {
492 if ((i%4)==3) fc(0,&n);
493 if ((hi>>i)&1) {
494 fc(10, &n); fc(8, &n); // low-high transition
495 } else {
496 fc(8, &n); fc(10, &n); // high-low transition
497 }
498 }
499
500 WDT_HIT();
501 // manchester encode bits 31 to 0
502 for (i=31; i>=0; i--) {
503 if ((i%4)==3) fc(0,&n);
504 if ((lo>>i)&1) {
505 fc(10, &n); fc(8, &n); // low-high transition
506 } else {
507 fc(8, &n); fc(10, &n); // high-low transition
508 }
509 }
510
511 if (ledcontrol)
512 LED_A_ON();
513 SimulateTagLowFrequency(n, ledcontrol);
514
515 if (ledcontrol)
516 LED_A_OFF();
517 }
518
519 // loop to capture raw HID waveform then FSK demodulate the TAG ID from it
520 static void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
521 {
522 BYTE *dest = (BYTE *)BigBuf;
523 int m=0, n=0, i=0, idx=0, found=0, lastval=0;
524 DWORD hi=0, lo=0;
525
526 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
527 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
528
529 // Connect the A/D to the peak-detected low-frequency path.
530 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
531
532 // Give it a bit of time for the resonant antenna to settle.
533 SpinDelay(50);
534
535 // Now set up the SSC to get the ADC samples that are now streaming at us.
536 FpgaSetupSsc();
537
538 for(;;) {
539 WDT_HIT();
540 if (ledcontrol)
541 LED_A_ON();
542 if(BUTTON_PRESS()) {
543 DbpString("Stopped");
544 if (ledcontrol)
545 LED_A_OFF();
546 return;
547 }
548
549 i = 0;
550 m = sizeof(BigBuf);
551 memset(dest,128,m);
552 for(;;) {
553 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
554 SSC_TRANSMIT_HOLDING = 0x43;
555 if (ledcontrol)
556 LED_D_ON();
557 }
558 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
559 dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
560 // we don't care about actual value, only if it's more or less than a
561 // threshold essentially we capture zero crossings for later analysis
562 if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
563 i++;
564 if (ledcontrol)
565 LED_D_OFF();
566 if(i >= m) {
567 break;
568 }
569 }
570 }
571
572 // FSK demodulator
573
574 // sync to first lo-hi transition
575 for( idx=1; idx<m; idx++) {
576 if (dest[idx-1]<dest[idx])
577 lastval=idx;
578 break;
579 }
580 WDT_HIT();
581
582 // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
583 // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
584 // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
585 for( i=0; idx<m; idx++) {
586 if (dest[idx-1]<dest[idx]) {
587 dest[i]=idx-lastval;
588 if (dest[i] <= 8) {
589 dest[i]=1;
590 } else {
591 dest[i]=0;
592 }
593
594 lastval=idx;
595 i++;
596 }
597 }
598 m=i;
599 WDT_HIT();
600
601 // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
602 lastval=dest[0];
603 idx=0;
604 i=0;
605 n=0;
606 for( idx=0; idx<m; idx++) {
607 if (dest[idx]==lastval) {
608 n++;
609 } else {
610 // a bit time is five fc/10 or six fc/8 cycles so figure out how many bits a pattern width represents,
611 // an extra fc/8 pattern preceeds every 4 bits (about 200 cycles) just to complicate things but it gets
612 // swallowed up by rounding
613 // expected results are 1 or 2 bits, any more and it's an invalid manchester encoding
614 // special start of frame markers use invalid manchester states (no transitions) by using sequences
615 // like 111000
616 if (dest[idx-1]) {
617 n=(n+1)/6; // fc/8 in sets of 6
618 } else {
619 n=(n+1)/5; // fc/10 in sets of 5
620 }
621 switch (n) { // stuff appropriate bits in buffer
622 case 0:
623 case 1: // one bit
624 dest[i++]=dest[idx-1];
625 break;
626 case 2: // two bits
627 dest[i++]=dest[idx-1];
628 dest[i++]=dest[idx-1];
629 break;
630 case 3: // 3 bit start of frame markers
631 dest[i++]=dest[idx-1];
632 dest[i++]=dest[idx-1];
633 dest[i++]=dest[idx-1];
634 break;
635 // When a logic 0 is immediately followed by the start of the next transmisson
636 // (special pattern) a pattern of 4 bit duration lengths is created.
637 case 4:
638 dest[i++]=dest[idx-1];
639 dest[i++]=dest[idx-1];
640 dest[i++]=dest[idx-1];
641 dest[i++]=dest[idx-1];
642 break;
643 default: // this shouldn't happen, don't stuff any bits
644 break;
645 }
646 n=0;
647 lastval=dest[idx];
648 }
649 }
650 m=i;
651 WDT_HIT();
652
653 // final loop, go over previously decoded manchester data and decode into usable tag ID
654 // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
655 for( idx=0; idx<m-6; idx++) {
656 // search for a start of frame marker
657 if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) )
658 {
659 found=1;
660 idx+=6;
661 if (found && (hi|lo)) {
662 DbpString("TAG ID");
663 DbpIntegers(hi, lo, (lo>>1)&0xffff);
664 /* if we're only looking for one tag */
665 if (findone)
666 {
667 *high = hi;
668 *low = lo;
669 return;
670 }
671 hi=0;
672 lo=0;
673 found=0;
674 }
675 }
676 if (found) {
677 if (dest[idx] && (!dest[idx+1]) ) {
678 hi=(hi<<1)|(lo>>31);
679 lo=(lo<<1)|0;
680 } else if ( (!dest[idx]) && dest[idx+1]) {
681 hi=(hi<<1)|(lo>>31);
682 lo=(lo<<1)|1;
683 } else {
684 found=0;
685 hi=0;
686 lo=0;
687 }
688 idx++;
689 }
690 if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) )
691 {
692 found=1;
693 idx+=6;
694 if (found && (hi|lo)) {
695 DbpString("TAG ID");
696 DbpIntegers(hi, lo, (lo>>1)&0xffff);
697 /* if we're only looking for one tag */
698 if (findone)
699 {
700 *high = hi;
701 *low = lo;
702 return;
703 }
704 hi=0;
705 lo=0;
706 found=0;
707 }
708 }
709 }
710 WDT_HIT();
711 }
712 }
713
714 void SimulateTagHfListen(void)
715 {
716 BYTE *dest = (BYTE *)BigBuf;
717 int n = sizeof(BigBuf);
718 BYTE v = 0;
719 int i;
720 int p = 0;
721
722 // We're using this mode just so that I can test it out; the simulated
723 // tag mode would work just as well and be simpler.
724 FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER_RX_XCORR | FPGA_HF_READER_RX_XCORR_848_KHZ | FPGA_HF_READER_RX_XCORR_SNOOP);
725
726 // We need to listen to the high-frequency, peak-detected path.
727 SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
728
729 FpgaSetupSsc();
730
731 i = 0;
732 for(;;) {
733 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
734 SSC_TRANSMIT_HOLDING = 0xff;
735 }
736 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
737 BYTE r = (BYTE)SSC_RECEIVE_HOLDING;
738
739 v <<= 1;
740 if(r & 1) {
741 v |= 1;
742 }
743 p++;
744
745 if(p >= 8) {
746 dest[i] = v;
747 v = 0;
748 p = 0;
749 i++;
750
751 if(i >= n) {
752 break;
753 }
754 }
755 }
756 }
757 DbpString("simulate tag (now type bitsamples)");
758 }
759
760 void UsbPacketReceived(BYTE *packet, int len)
761 {
762 UsbCommand *c = (UsbCommand *)packet;
763
764 switch(c->cmd) {
765 case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
766 AcquireRawAdcSamples125k(c->ext1);
767 break;
768
769 case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
770 ModThenAcquireRawAdcSamples125k(c->ext1,c->ext2,c->ext3,c->d.asBytes);
771 break;
772
773 case CMD_ACQUIRE_RAW_BITS_TI_TYPE:
774 AcquireRawBitsTI();
775 break;
776
777 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
778 AcquireRawAdcSamplesIso15693();
779 break;
780
781 case CMD_BUFF_CLEAR:
782 BufferClear();
783 break;
784
785 case CMD_READER_ISO_15693:
786 ReaderIso15693(c->ext1);
787 break;
788
789 case CMD_SIMTAG_ISO_15693:
790 SimTagIso15693(c->ext1);
791 break;
792
793 case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443:
794 AcquireRawAdcSamplesIso14443(c->ext1);
795 break;
796
797 case CMD_READ_SRI512_TAG:
798 ReadSRI512Iso14443(c->ext1);
799 break;
800
801 case CMD_READER_ISO_14443a:
802 ReaderIso14443a(c->ext1);
803 break;
804
805 case CMD_SNOOP_ISO_14443:
806 SnoopIso14443();
807 break;
808
809 case CMD_SNOOP_ISO_14443a:
810 SnoopIso14443a();
811 break;
812
813 case CMD_SIMULATE_TAG_HF_LISTEN:
814 SimulateTagHfListen();
815 break;
816
817 case CMD_SIMULATE_TAG_ISO_14443:
818 SimulateIso14443Tag();
819 break;
820
821 case CMD_SIMULATE_TAG_ISO_14443a:
822 SimulateIso14443aTag(c->ext1, c->ext2); // ## Simulate iso14443a tag - pass tag type & UID
823 break;
824
825 case CMD_MEASURE_ANTENNA_TUNING:
826 MeasureAntennaTuning();
827 break;
828
829 case CMD_LISTEN_READER_FIELD:
830 ListenReaderField(c->ext1);
831 break;
832
833 case CMD_HID_DEMOD_FSK:
834 CmdHIDdemodFSK(0, 0, 0, 1); // Demodulate HID tag
835 break;
836
837 case CMD_HID_SIM_TAG:
838 CmdHIDsimTAG(c->ext1, c->ext2, 1); // Simulate HID tag by ID
839 break;
840
841 case CMD_FPGA_MAJOR_MODE_OFF: // ## FPGA Control
842 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
843 SpinDelay(200);
844 LED_D_OFF(); // LED D indicates field ON or OFF
845 break;
846
847 case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
848 case CMD_DOWNLOAD_RAW_BITS_TI_TYPE: {
849 UsbCommand n;
850 if(c->cmd == CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K) {
851 n.cmd = CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K;
852 } else {
853 n.cmd = CMD_DOWNLOADED_RAW_BITS_TI_TYPE;
854 }
855 n.ext1 = c->ext1;
856 memcpy(n.d.asDwords, BigBuf+c->ext1, 12*sizeof(DWORD));
857 UsbSendPacket((BYTE *)&n, sizeof(n));
858 break;
859 }
860 case CMD_DOWNLOADED_SIM_SAMPLES_125K: {
861 BYTE *b = (BYTE *)BigBuf;
862 memcpy(b+c->ext1, c->d.asBytes, 48);
863 break;
864 }
865 case CMD_SIMULATE_TAG_125K:
866 LED_A_ON();
867 SimulateTagLowFrequency(c->ext1, 1);
868 LED_A_OFF();
869 break;
870 #ifdef WITH_LCD
871 case CMD_LCD_RESET:
872 LCDReset();
873 break;
874 #endif
875 case CMD_READ_MEM:
876 ReadMem(c->ext1);
877 break;
878 case CMD_SET_LF_DIVISOR:
879 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, c->ext1);
880 break;
881 #ifdef WITH_LCD
882 case CMD_LCD:
883 LCDSend(c->ext1);
884 break;
885 #endif
886 case CMD_SETUP_WRITE:
887 case CMD_FINISH_WRITE:
888 case CMD_HARDWARE_RESET:
889 USB_D_PLUS_PULLUP_OFF();
890 SpinDelay(1000);
891 SpinDelay(1000);
892 RSTC_CONTROL = RST_CONTROL_KEY | RST_CONTROL_PROCESSOR_RESET;
893 for(;;) {
894 // We're going to reset, and the bootrom will take control.
895 }
896 break;
897
898
899 default:
900 DbpString("unknown command");
901 break;
902 }
903 }
904
905 void ReadMem(int addr)
906 {
907 const DWORD *data = ((DWORD *)addr);
908 int i;
909
910 DbpString("Reading memory at address");
911 DbpIntegers(0, 0, addr);
912 for (i = 0; i < 8; i+= 2)
913 DbpIntegers(0, data[i], data[i+1]);
914 }
915
916 void AppMain(void)
917 {
918 memset(BigBuf,0,sizeof(BigBuf));
919 SpinDelay(100);
920
921 LED_D_OFF();
922 LED_C_OFF();
923 LED_B_OFF();
924 LED_A_OFF();
925
926 UsbStart();
927
928 // The FPGA gets its clock from us from PCK0 output, so set that up.
929 PIO_PERIPHERAL_B_SEL = (1 << GPIO_PCK0);
930 PIO_DISABLE = (1 << GPIO_PCK0);
931 PMC_SYS_CLK_ENABLE = PMC_SYS_CLK_PROGRAMMABLE_CLK_0;
932 // PCK0 is PLL clock / 4 = 96Mhz / 4 = 24Mhz
933 PMC_PROGRAMMABLE_CLK_0 = PMC_CLK_SELECTION_PLL_CLOCK |
934 PMC_CLK_PRESCALE_DIV_4;
935 PIO_OUTPUT_ENABLE = (1 << GPIO_PCK0);
936
937 // Reset SPI
938 SPI_CONTROL = SPI_CONTROL_RESET;
939 // Reset SSC
940 SSC_CONTROL = SSC_CONTROL_RESET;
941
942 // Load the FPGA image, which we have stored in our flash.
943 FpgaDownloadAndGo();
944
945 #ifdef WITH_LCD
946
947 LCDInit();
948
949 // test text on different colored backgrounds
950 LCDString(" The quick brown fox ", &FONT6x8,1,1+8*0,WHITE ,BLACK );
951 LCDString(" jumped over the ", &FONT6x8,1,1+8*1,BLACK ,WHITE );
952 LCDString(" lazy dog. ", &FONT6x8,1,1+8*2,YELLOW ,RED );
953 LCDString(" AaBbCcDdEeFfGgHhIiJj ", &FONT6x8,1,1+8*3,RED ,GREEN );
954 LCDString(" KkLlMmNnOoPpQqRrSsTt ", &FONT6x8,1,1+8*4,MAGENTA,BLUE );
955 LCDString("UuVvWwXxYyZz0123456789", &FONT6x8,1,1+8*5,BLUE ,YELLOW);
956 LCDString("`-=[]_;',./~!@#$%^&*()", &FONT6x8,1,1+8*6,BLACK ,CYAN );
957 LCDString(" _+{}|:\\\"<>? ",&FONT6x8,1,1+8*7,BLUE ,MAGENTA);
958
959 // color bands
960 LCDFill(0, 1+8* 8, 132, 8, BLACK);
961 LCDFill(0, 1+8* 9, 132, 8, WHITE);
962 LCDFill(0, 1+8*10, 132, 8, RED);
963 LCDFill(0, 1+8*11, 132, 8, GREEN);
964 LCDFill(0, 1+8*12, 132, 8, BLUE);
965 LCDFill(0, 1+8*13, 132, 8, YELLOW);
966 LCDFill(0, 1+8*14, 132, 8, CYAN);
967 LCDFill(0, 1+8*15, 132, 8, MAGENTA);
968
969 #endif
970
971 for(;;) {
972 usbattached = UsbPoll(FALSE);
973 WDT_HIT();
974
975 if (BUTTON_HELD(1000) > 0)
976 SamyRun();
977 }
978 }
979
980
981 // samy's sniff and repeat routine
982 void SamyRun()
983 {
984 DbpString("Stand-alone mode! No PC necessary.");
985
986 // 3 possible options? no just 2 for now
987 #define OPTS 2
988
989 int high[OPTS], low[OPTS];
990
991 // Oooh pretty -- notify user we're in elite samy mode now
992 LED(LED_RED, 200);
993 LED(LED_ORANGE, 200);
994 LED(LED_GREEN, 200);
995 LED(LED_ORANGE, 200);
996 LED(LED_RED, 200);
997 LED(LED_ORANGE, 200);
998 LED(LED_GREEN, 200);
999 LED(LED_ORANGE, 200);
1000 LED(LED_RED, 200);
1001
1002 int selected = 0;
1003 int playing = 0;
1004
1005 // Turn on selected LED
1006 LED(selected + 1, 0);
1007
1008 for (;;)
1009 {
1010 usbattached = UsbPoll(FALSE);
1011 WDT_HIT();
1012
1013 // Was our button held down or pressed?
1014 int button_pressed = BUTTON_HELD(1000);
1015 SpinDelay(300);
1016
1017 // Button was held for a second, begin recording
1018 if (button_pressed > 0)
1019 {
1020 LEDsoff();
1021 LED(selected + 1, 0);
1022 LED(LED_RED2, 0);
1023
1024 // record
1025 DbpString("Starting recording");
1026
1027 // wait for button to be released
1028 while(BUTTON_PRESS())
1029 WDT_HIT();
1030
1031 /* need this delay to prevent catching some weird data */
1032 SpinDelay(500);
1033
1034 CmdHIDdemodFSK(1, &high[selected], &low[selected], 0);
1035 DbpString("Recorded");
1036 DbpIntegers(selected, high[selected], low[selected]);
1037
1038 LEDsoff();
1039 LED(selected + 1, 0);
1040 // Finished recording
1041
1042 // If we were previously playing, set playing off
1043 // so next button push begins playing what we recorded
1044 playing = 0;
1045 }
1046
1047 // Change where to record (or begin playing)
1048 else if (button_pressed)
1049 {
1050 // Next option if we were previously playing
1051 if (playing)
1052 selected = (selected + 1) % OPTS;
1053 playing = !playing;
1054
1055 LEDsoff();
1056 LED(selected + 1, 0);
1057
1058 // Begin transmitting
1059 if (playing)
1060 {
1061 LED(LED_GREEN, 0);
1062 DbpString("Playing");
1063 // wait for button to be released
1064 while(BUTTON_PRESS())
1065 WDT_HIT();
1066 DbpIntegers(selected, high[selected], low[selected]);
1067 CmdHIDsimTAG(high[selected], low[selected], 0);
1068 DbpString("Done playing");
1069 if (BUTTON_HELD(1000) > 0)
1070 {
1071 DbpString("Exiting");
1072 LEDsoff();
1073 return;
1074 }
1075
1076 /* We pressed a button so ignore it here with a delay */
1077 SpinDelay(300);
1078
1079 // when done, we're done playing, move to next option
1080 selected = (selected + 1) % OPTS;
1081 playing = !playing;
1082 LEDsoff();
1083 LED(selected + 1, 0);
1084 }
1085 else
1086 while(BUTTON_PRESS())
1087 WDT_HIT();
1088 }
1089 }
1090 }
1091
1092
1093 /*
1094 OBJECTIVE
1095 Listen and detect an external reader. Determine the best location
1096 for the antenna.
1097
1098 INSTRUCTIONS:
1099 Inside the ListenReaderField() function, there is two mode.
1100 By default, when you call the function, you will enter mode 1.
1101 If you press the PM3 button one time, you will enter mode 2.
1102 If you press the PM3 button a second time, you will exit the function.
1103
1104 DESCRIPTION OF MODE 1:
1105 This mode just listens for an external reader field and lights up green
1106 for HF and/or red for LF. This is the original mode of the detectreader
1107 function.
1108
1109 DESCRIPTION OF MODE 2:
1110 This mode will visually represent, using the LEDs, the actual strength of the
1111 current compared to the maximum current detected. Basically, once you know
1112 what kind of external reader is present, it will help you spot the best location to place
1113 your antenna. You will probably not get some good results if there is a LF and a HF reader
1114 at the same place! :-)
1115
1116 LIGHT SCHEME USED:
1117
1118 Light scheme | Descriptiong
1119 ----------------------------------------------------
1120 ---- | No field detected
1121 X--- | 14% of maximum current detected
1122 -X-- | 29% of maximum current detected
1123 --X- | 43% of maximum current detected
1124 ---X | 57% of maximum current detected
1125 --XX | 71% of maximum current detected
1126 -XXX | 86% of maximum current detected
1127 XXXX | 100% of maximum current detected
1128
1129 TODO:
1130 Add the LF part for MODE 2
1131
1132 */
1133 void ListenReaderField(int limit)
1134 {
1135 int lf_av, lf_av_new, lf_baseline= 0, lf_count= 0;
1136 int hf_av, hf_av_new, hf_baseline= 0, hf_count= 0, hf_max;
1137 int mode=1;
1138
1139 #define LF_ONLY 1
1140 #define HF_ONLY 2
1141
1142 LED_A_OFF();
1143 LED_B_OFF();
1144 LED_C_OFF();
1145 LED_D_OFF();
1146
1147 lf_av= ReadAdc(ADC_CHAN_LF);
1148
1149 if(limit != HF_ONLY)
1150 {
1151 DbpString("LF 125/134 Baseline:");
1152 DbpIntegers(lf_av,0,0);
1153 lf_baseline= lf_av;
1154 }
1155
1156 hf_av=hf_max=ReadAdc(ADC_CHAN_HF);
1157
1158 if (limit != LF_ONLY)
1159 {
1160 DbpString("HF 13.56 Baseline:");
1161 DbpIntegers(hf_av,0,0);
1162 hf_baseline= hf_av;
1163 }
1164
1165 for(;;)
1166 {
1167 if (BUTTON_PRESS()) {
1168 SpinDelay(500);
1169 switch (mode) {
1170 case 1:
1171 mode=2;
1172 DbpString("Signal Strength Mode");
1173 break;
1174 case 2:
1175 default:
1176 DbpString("Stopped");
1177 LED_A_OFF();
1178 LED_B_OFF();
1179 LED_C_OFF();
1180 LED_D_OFF();
1181 return;
1182 break;
1183 }
1184 }
1185 WDT_HIT();
1186
1187 if (limit != HF_ONLY)
1188 {
1189 if (abs(lf_av - lf_baseline) > 10)
1190 LED_D_ON();
1191 else
1192 LED_D_OFF();
1193 ++lf_count;
1194 lf_av_new= ReadAdc(ADC_CHAN_LF);
1195 // see if there's a significant change
1196 if(abs(lf_av - lf_av_new) > 10)
1197 {
1198 DbpString("LF 125/134 Field Change:");
1199 DbpIntegers(lf_av,lf_av_new,lf_count);
1200 lf_av= lf_av_new;
1201 lf_count= 0;
1202 }
1203 }
1204
1205 if (limit != LF_ONLY)
1206 {
1207 if (abs(hf_av - hf_baseline) > 10) {
1208 if (mode == 1)
1209 LED_B_ON();
1210 if (mode == 2) {
1211 if ( hf_av>(hf_max/7)*6) {
1212 LED_A_ON(); LED_B_ON(); LED_C_ON(); LED_D_ON();
1213 }
1214 if ( (hf_av>(hf_max/7)*5) && (hf_av<=(hf_max/7)*6) ) {
1215 LED_A_ON(); LED_B_ON(); LED_C_OFF(); LED_D_ON();
1216 }
1217 if ( (hf_av>(hf_max/7)*4) && (hf_av<=(hf_max/7)*5) ) {
1218 LED_A_OFF(); LED_B_ON(); LED_C_OFF(); LED_D_ON();
1219 }
1220 if ( (hf_av>(hf_max/7)*3) && (hf_av<=(hf_max/7)*4) ) {
1221 LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); LED_D_ON();
1222 }
1223 if ( (hf_av>(hf_max/7)*2) && (hf_av<=(hf_max/7)*3) ) {
1224 LED_A_OFF(); LED_B_ON(); LED_C_OFF(); LED_D_OFF();
1225 }
1226 if ( (hf_av>(hf_max/7)*1) && (hf_av<=(hf_max/7)*2) ) {
1227 LED_A_ON(); LED_B_OFF(); LED_C_OFF(); LED_D_OFF();
1228 }
1229 if ( (hf_av>(hf_max/7)*0) && (hf_av<=(hf_max/7)*1) ) {
1230 LED_A_OFF(); LED_B_OFF(); LED_C_ON(); LED_D_OFF();
1231 }
1232 }
1233 } else {
1234 if (mode == 1) {
1235 LED_B_OFF();
1236 }
1237 if (mode == 2) {
1238 LED_A_OFF(); LED_B_OFF(); LED_C_OFF(); LED_D_OFF();
1239 }
1240 }
1241
1242 ++hf_count;
1243 hf_av_new= ReadAdc(ADC_CHAN_HF);
1244 // see if there's a significant change
1245 if(abs(hf_av - hf_av_new) > 10)
1246 {
1247 DbpString("HF 13.56 Field Change:");
1248 DbpIntegers(hf_av,hf_av_new,hf_count);
1249 hf_av= hf_av_new;
1250 if (hf_av > hf_max)
1251 hf_max = hf_av;
1252 hf_count= 0;
1253 }
1254 }
1255 }
1256 }
1257
Impressum, Datenschutz