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