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