]> git.zerfleddert.de Git - proxmark3-svn/blob - armsrc/lfops.c
Added tiread command to demod TI tags on the PM3
[proxmark3-svn] / armsrc / lfops.c
1 //-----------------------------------------------------------------------------
2 // Miscellaneous routines for low frequency tag operations.
3 // Tags supported here so far are Texas Instruments (TI), HID
4 // Also routines for raw mode reading/simulating of LF waveform
5 //
6 //-----------------------------------------------------------------------------
7 #include <proxmark3.h>
8 #include "apps.h"
9 #include "../common/crc16.c"
10
11 void AcquireRawAdcSamples125k(BOOL at134khz)
12 {
13 if(at134khz) {
14 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
15 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
16 } else {
17 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
18 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
19 }
20
21 // Connect the A/D to the peak-detected low-frequency path.
22 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
23
24 // Give it a bit of time for the resonant antenna to settle.
25 SpinDelay(50);
26
27 // Now set up the SSC to get the ADC samples that are now streaming at us.
28 FpgaSetupSsc();
29
30 // Now call the acquisition routine
31 DoAcquisition125k(at134khz);
32 }
33
34 // split into two routines so we can avoid timing issues after sending commands //
35 void DoAcquisition125k(BOOL at134khz)
36 {
37 BYTE *dest = (BYTE *)BigBuf;
38 int n = sizeof(BigBuf);
39 int i;
40
41 memset(dest,0,n);
42 i = 0;
43 for(;;) {
44 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
45 SSC_TRANSMIT_HOLDING = 0x43;
46 LED_D_ON();
47 }
48 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
49 dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
50 i++;
51 LED_D_OFF();
52 if(i >= n) {
53 break;
54 }
55 }
56 }
57 DbpIntegers(dest[0], dest[1], at134khz);
58 }
59
60 void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,BYTE *command)
61 {
62 BOOL at134khz;
63
64 // see if 'h' was specified
65 if(command[strlen((char *) command) - 1] == 'h')
66 at134khz= TRUE;
67 else
68 at134khz= FALSE;
69
70 if(at134khz) {
71 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
72 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
73 } else {
74 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
75 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
76 }
77
78 // Give it a bit of time for the resonant antenna to settle.
79 SpinDelay(50);
80
81 // Now set up the SSC to get the ADC samples that are now streaming at us.
82 FpgaSetupSsc();
83
84 // now modulate the reader field
85 while(*command != '\0' && *command != ' ')
86 {
87 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
88 LED_D_OFF();
89 SpinDelayUs(delay_off);
90 if(at134khz) {
91 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
92 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
93 } else {
94 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
95 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
96 }
97 LED_D_ON();
98 if(*(command++) == '0')
99 SpinDelayUs(period_0);
100 else
101 SpinDelayUs(period_1);
102 }
103 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
104 LED_D_OFF();
105 SpinDelayUs(delay_off);
106 if(at134khz) {
107 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
108 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
109 } else {
110 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
111 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
112 }
113
114 // now do the read
115 DoAcquisition125k(at134khz);
116 }
117
118 /* blank r/w tag data stream
119 ...0000000000000000 01111111
120 1010101010101010101010101010101010101010101010101010101010101010
121 0011010010100001
122 01111111
123 101010101010101[0]000...
124
125 [5555fe852c5555555555555555fe0000]
126 */
127 void ReadTItag()
128 {
129 // some hardcoded initial params
130 // when we read a TI tag we sample the zerocross line at 2Mhz
131 // TI tags modulate a 1 as 16 cycles of 123.2Khz
132 // TI tags modulate a 0 as 16 cycles of 134.2Khz
133 #define FSAMPLE 2000000
134 #define FREQLO 123200
135 #define FREQHI 134200
136
137 signed char *dest = (signed char *)BigBuf;
138 int n = sizeof(BigBuf);
139 // int *dest = GraphBuffer;
140 // int n = GraphTraceLen;
141
142 // 128 bit shift register [shift3:shift2:shift1:shift0]
143 DWORD shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0;
144
145 int i, cycles=0, samples=0;
146 // how many sample points fit in 16 cycles of each frequency
147 DWORD sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI;
148 // when to tell if we're close enough to one freq or another
149 DWORD threshold = (sampleslo - sampleshi + 1)>>1;
150
151 // TI tags charge at 134.2Khz
152 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
153
154 // Place FPGA in passthrough mode, in this mode the CROSS_LO line
155 // connects to SSP_DIN and the SSP_DOUT logic level controls
156 // whether we're modulating the antenna (high)
157 // or listening to the antenna (low)
158 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
159
160 // get TI tag data into the buffer
161 AcquireTiType();
162
163 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
164
165 for (i=0; i<n-1; i++) {
166 // count cycles by looking for lo to hi zero crossings
167 if ( (dest[i]<0) && (dest[i+1]>0) ) {
168 cycles++;
169 // after 16 cycles, measure the frequency
170 if (cycles>15) {
171 cycles=0;
172 samples=i-samples; // number of samples in these 16 cycles
173
174 // TI bits are coming to us lsb first so shift them
175 // right through our 128 bit right shift register
176 shift0 = (shift0>>1) | (shift1 << 31);
177 shift1 = (shift1>>1) | (shift2 << 31);
178 shift2 = (shift2>>1) | (shift3 << 31);
179 shift3 >>= 1;
180
181 // check if the cycles fall close to the number
182 // expected for either the low or high frequency
183 if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) {
184 // low frequency represents a 1
185 shift3 |= (1<<31);
186 } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) {
187 // high frequency represents a 0
188 } else {
189 // probably detected a gay waveform or noise
190 // use this as gaydar or discard shift register and start again
191 shift3 = shift2 = shift1 = shift0 = 0;
192 }
193 samples = i;
194
195 // for each bit we receive, test if we've detected a valid tag
196
197 // if we see 17 zeroes followed by 6 ones, we might have a tag
198 // remember the bits are backwards
199 if ( ((shift0 & 0x7fffff) == 0x7e0000) ) {
200 // if start and end bytes match, we have a tag so break out of the loop
201 if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) {
202 cycles = 0xF0B; //use this as a flag (ugly but whatever)
203 break;
204 }
205 }
206 }
207 }
208 }
209
210 // if flag is set we have a tag
211 if (cycles!=0xF0B) {
212 DbpString("Info: No valid tag detected.");
213 } else {
214 // put 64 bit data into shift1 and shift0
215 shift0 = (shift0>>24) | (shift1 << 8);
216 shift1 = (shift1>>24) | (shift2 << 8);
217
218 // align 16 bit crc into lower half of shift2
219 shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff;
220
221 // if r/w tag, check ident match
222 if ( shift3&(1<<15) ) {
223 DbpString("Info: TI tag is rewriteable");
224 // only 15 bits compare, last bit of ident is not valid
225 if ( ((shift3>>16)^shift0)&0x7fff ) {
226 DbpString("Error: Ident mismatch!");
227 } else {
228 DbpString("Info: TI tag ident is valid");
229 }
230 } else {
231 DbpString("Info: TI tag is readonly");
232 }
233
234 // WARNING the order of the bytes in which we calc crc below needs checking
235 // i'm 99% sure the crc algorithm is correct, but it may need to eat the
236 // bytes in reverse or something
237 // calculate CRC
238 DWORD crc=0;
239
240 crc = update_crc16(crc, (shift0)&0xff);
241 crc = update_crc16(crc, (shift0>>8)&0xff);
242 crc = update_crc16(crc, (shift0>>16)&0xff);
243 crc = update_crc16(crc, (shift0>>24)&0xff);
244 crc = update_crc16(crc, (shift1)&0xff);
245 crc = update_crc16(crc, (shift1>>8)&0xff);
246 crc = update_crc16(crc, (shift1>>16)&0xff);
247 crc = update_crc16(crc, (shift1>>24)&0xff);
248
249 DbpString("Info: Tag data_hi, data_lo, crc = ");
250 DbpIntegers(shift1, shift0, shift2&0xffff);
251 if (crc != (shift2&0xffff)) {
252 DbpString("Error: CRC mismatch, expected");
253 DbpIntegers(0, 0, crc);
254 } else {
255 DbpString("Info: CRC is good");
256 }
257 }
258 }
259
260 void WriteTIbyte(BYTE b)
261 {
262 int i = 0;
263
264 // modulate 8 bits out to the antenna
265 for (i=0; i<8; i++)
266 {
267 if (b&(1<<i)) {
268 // stop modulating antenna
269 PIO_OUTPUT_DATA_CLEAR = (1<<GPIO_SSC_DOUT);
270 SpinDelayUs(1000);
271 // modulate antenna
272 PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
273 SpinDelayUs(1000);
274 } else {
275 // stop modulating antenna
276 PIO_OUTPUT_DATA_CLEAR = (1<<GPIO_SSC_DOUT);
277 SpinDelayUs(300);
278 // modulate antenna
279 PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
280 SpinDelayUs(1700);
281 }
282 }
283 }
284
285 void AcquireTiType(void)
286 {
287 int i, j, n;
288 // tag transmission is <20ms, sampling at 2M gives us 40K samples max
289 // each sample is 1 bit stuffed into a DWORD so we need 1250 DWORDS
290 #define TIBUFLEN 1250
291
292 // clear buffer
293 memset(BigBuf,0,sizeof(BigBuf));
294
295 // Set up the synchronous serial port
296 PIO_DISABLE = (1<<GPIO_SSC_DIN);
297 PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN);
298
299 // steal this pin from the SSP and use it to control the modulation
300 PIO_ENABLE = (1<<GPIO_SSC_DOUT);
301 PIO_OUTPUT_ENABLE = (1<<GPIO_SSC_DOUT);
302
303 SSC_CONTROL = SSC_CONTROL_RESET;
304 SSC_CONTROL = SSC_CONTROL_RX_ENABLE | SSC_CONTROL_TX_ENABLE;
305
306 // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long
307 // 48/2 = 24 MHz clock must be divided by 12
308 SSC_CLOCK_DIVISOR = 12;
309
310 SSC_RECEIVE_CLOCK_MODE = SSC_CLOCK_MODE_SELECT(0);
311 SSC_RECEIVE_FRAME_MODE = SSC_FRAME_MODE_BITS_IN_WORD(32) | SSC_FRAME_MODE_MSB_FIRST;
312 SSC_TRANSMIT_CLOCK_MODE = 0;
313 SSC_TRANSMIT_FRAME_MODE = 0;
314
315 LED_D_ON();
316
317 // modulate antenna
318 PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
319
320 // Charge TI tag for 50ms.
321 SpinDelay(50);
322
323 // stop modulating antenna and listen
324 PIO_OUTPUT_DATA_CLEAR = (1<<GPIO_SSC_DOUT);
325
326 LED_D_OFF();
327
328 i = 0;
329 for(;;) {
330 if(SSC_STATUS & SSC_STATUS_RX_READY) {
331 BigBuf[i] = SSC_RECEIVE_HOLDING; // store 32 bit values in buffer
332 i++; if(i >= TIBUFLEN) break;
333 }
334 WDT_HIT();
335 }
336
337 // return stolen pin to SSP
338 PIO_DISABLE = (1<<GPIO_SSC_DOUT);
339 PIO_PERIPHERAL_A_SEL = (1<<GPIO_SSC_DIN) | (1<<GPIO_SSC_DOUT);
340
341 char *dest = (char *)BigBuf;
342 n = TIBUFLEN*32;
343 // unpack buffer
344 for (i=TIBUFLEN-1; i>=0; i--) {
345 // DbpIntegers(0, 0, BigBuf[i]);
346 for (j=0; j<32; j++) {
347 if(BigBuf[i] & (1 << j)) {
348 dest[--n] = 1;
349 } else {
350 dest[--n] = -1;
351 }
352 }
353 }
354 }
355
356 // arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc
357 // if crc provided, it will be written with the data verbatim (even if bogus)
358 // if not provided a valid crc will be computed from the data and written.
359 void WriteTItag(DWORD idhi, DWORD idlo, WORD crc)
360 {
361
362 // WARNING the order of the bytes in which we calc crc below needs checking
363 // i'm 99% sure the crc algorithm is correct, but it may need to eat the
364 // bytes in reverse or something
365
366 if(crc == 0) {
367 crc = update_crc16(crc, (idlo)&0xff);
368 crc = update_crc16(crc, (idlo>>8)&0xff);
369 crc = update_crc16(crc, (idlo>>16)&0xff);
370 crc = update_crc16(crc, (idlo>>24)&0xff);
371 crc = update_crc16(crc, (idhi)&0xff);
372 crc = update_crc16(crc, (idhi>>8)&0xff);
373 crc = update_crc16(crc, (idhi>>16)&0xff);
374 crc = update_crc16(crc, (idhi>>24)&0xff);
375 }
376 DbpString("Writing the following data to tag:");
377 DbpIntegers(idhi, idlo, crc);
378
379 // TI tags charge at 134.2Khz
380 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
381 // Place FPGA in passthrough mode, in this mode the CROSS_LO line
382 // connects to SSP_DIN and the SSP_DOUT logic level controls
383 // whether we're modulating the antenna (high)
384 // or listening to the antenna (low)
385 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
386 LED_A_ON();
387
388 // steal this pin from the SSP and use it to control the modulation
389 PIO_ENABLE = (1<<GPIO_SSC_DOUT);
390 PIO_OUTPUT_ENABLE = (1<<GPIO_SSC_DOUT);
391
392 // writing algorithm:
393 // a high bit consists of a field off for 1ms and field on for 1ms
394 // a low bit consists of a field off for 0.3ms and field on for 1.7ms
395 // initiate a charge time of 50ms (field on) then immediately start writing bits
396 // start by writing 0xBB (keyword) and 0xEB (password)
397 // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer)
398 // finally end with 0x0300 (write frame)
399 // all data is sent lsb firts
400 // finish with 15ms programming time
401
402 // modulate antenna
403 PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
404 SpinDelay(50); // charge time
405
406 WriteTIbyte(0xbb); // keyword
407 WriteTIbyte(0xeb); // password
408 WriteTIbyte( (idlo )&0xff );
409 WriteTIbyte( (idlo>>8 )&0xff );
410 WriteTIbyte( (idlo>>16)&0xff );
411 WriteTIbyte( (idlo>>24)&0xff );
412 WriteTIbyte( (idhi )&0xff );
413 WriteTIbyte( (idhi>>8 )&0xff );
414 WriteTIbyte( (idhi>>16)&0xff );
415 WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo
416 WriteTIbyte( (crc )&0xff ); // crc lo
417 WriteTIbyte( (crc>>8 )&0xff ); // crc hi
418 WriteTIbyte(0x00); // write frame lo
419 WriteTIbyte(0x03); // write frame hi
420 PIO_OUTPUT_DATA_SET = (1<<GPIO_SSC_DOUT);
421 SpinDelay(50); // programming time
422
423 LED_A_OFF();
424
425 // get TI tag data into the buffer
426 AcquireTiType();
427
428 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
429 DbpString("Now use tiread to check");
430 }
431
432 void SimulateTagLowFrequency(int period, int ledcontrol)
433 {
434 int i;
435 BYTE *tab = (BYTE *)BigBuf;
436
437 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_SIMULATOR);
438
439 PIO_ENABLE = (1 << GPIO_SSC_DOUT) | (1 << GPIO_SSC_CLK);
440
441 PIO_OUTPUT_ENABLE = (1 << GPIO_SSC_DOUT);
442 PIO_OUTPUT_DISABLE = (1 << GPIO_SSC_CLK);
443
444 #define SHORT_COIL() LOW(GPIO_SSC_DOUT)
445 #define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
446
447 i = 0;
448 for(;;) {
449 while(!(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK))) {
450 if(BUTTON_PRESS()) {
451 DbpString("Stopped");
452 return;
453 }
454 WDT_HIT();
455 }
456
457 if (ledcontrol)
458 LED_D_ON();
459
460 if(tab[i])
461 OPEN_COIL();
462 else
463 SHORT_COIL();
464
465 if (ledcontrol)
466 LED_D_OFF();
467
468 while(PIO_PIN_DATA_STATUS & (1<<GPIO_SSC_CLK)) {
469 if(BUTTON_PRESS()) {
470 DbpString("Stopped");
471 return;
472 }
473 WDT_HIT();
474 }
475
476 i++;
477 if(i == period) i = 0;
478 }
479 }
480
481 // compose fc/8 fc/10 waveform
482 static void fc(int c, int *n) {
483 BYTE *dest = (BYTE *)BigBuf;
484 int idx;
485
486 // for when we want an fc8 pattern every 4 logical bits
487 if(c==0) {
488 dest[((*n)++)]=1;
489 dest[((*n)++)]=1;
490 dest[((*n)++)]=0;
491 dest[((*n)++)]=0;
492 dest[((*n)++)]=0;
493 dest[((*n)++)]=0;
494 dest[((*n)++)]=0;
495 dest[((*n)++)]=0;
496 }
497 // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples
498 if(c==8) {
499 for (idx=0; idx<6; idx++) {
500 dest[((*n)++)]=1;
501 dest[((*n)++)]=1;
502 dest[((*n)++)]=0;
503 dest[((*n)++)]=0;
504 dest[((*n)++)]=0;
505 dest[((*n)++)]=0;
506 dest[((*n)++)]=0;
507 dest[((*n)++)]=0;
508 }
509 }
510
511 // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
512 if(c==10) {
513 for (idx=0; idx<5; idx++) {
514 dest[((*n)++)]=1;
515 dest[((*n)++)]=1;
516 dest[((*n)++)]=1;
517 dest[((*n)++)]=0;
518 dest[((*n)++)]=0;
519 dest[((*n)++)]=0;
520 dest[((*n)++)]=0;
521 dest[((*n)++)]=0;
522 dest[((*n)++)]=0;
523 dest[((*n)++)]=0;
524 }
525 }
526 }
527
528 // prepare a waveform pattern in the buffer based on the ID given then
529 // simulate a HID tag until the button is pressed
530 void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
531 {
532 int n=0, i=0;
533 /*
534 HID tag bitstream format
535 The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
536 A 1 bit is represented as 6 fc8 and 5 fc10 patterns
537 A 0 bit is represented as 5 fc10 and 6 fc8 patterns
538 A fc8 is inserted before every 4 bits
539 A special start of frame pattern is used consisting a0b0 where a and b are neither 0
540 nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10)
541 */
542
543 if (hi>0xFFF) {
544 DbpString("Tags can only have 44 bits.");
545 return;
546 }
547 fc(0,&n);
548 // special start of frame marker containing invalid bit sequences
549 fc(8, &n); fc(8, &n); // invalid
550 fc(8, &n); fc(10, &n); // logical 0
551 fc(10, &n); fc(10, &n); // invalid
552 fc(8, &n); fc(10, &n); // logical 0
553
554 WDT_HIT();
555 // manchester encode bits 43 to 32
556 for (i=11; i>=0; i--) {
557 if ((i%4)==3) fc(0,&n);
558 if ((hi>>i)&1) {
559 fc(10, &n); fc(8, &n); // low-high transition
560 } else {
561 fc(8, &n); fc(10, &n); // high-low transition
562 }
563 }
564
565 WDT_HIT();
566 // manchester encode bits 31 to 0
567 for (i=31; i>=0; i--) {
568 if ((i%4)==3) fc(0,&n);
569 if ((lo>>i)&1) {
570 fc(10, &n); fc(8, &n); // low-high transition
571 } else {
572 fc(8, &n); fc(10, &n); // high-low transition
573 }
574 }
575
576 if (ledcontrol)
577 LED_A_ON();
578 SimulateTagLowFrequency(n, ledcontrol);
579
580 if (ledcontrol)
581 LED_A_OFF();
582 }
583
584
585 // loop to capture raw HID waveform then FSK demodulate the TAG ID from it
586 void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
587 {
588 BYTE *dest = (BYTE *)BigBuf;
589 int m=0, n=0, i=0, idx=0, found=0, lastval=0;
590 DWORD hi=0, lo=0;
591
592 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
593 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER);
594
595 // Connect the A/D to the peak-detected low-frequency path.
596 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
597
598 // Give it a bit of time for the resonant antenna to settle.
599 SpinDelay(50);
600
601 // Now set up the SSC to get the ADC samples that are now streaming at us.
602 FpgaSetupSsc();
603
604 for(;;) {
605 WDT_HIT();
606 if (ledcontrol)
607 LED_A_ON();
608 if(BUTTON_PRESS()) {
609 DbpString("Stopped");
610 if (ledcontrol)
611 LED_A_OFF();
612 return;
613 }
614
615 i = 0;
616 m = sizeof(BigBuf);
617 memset(dest,128,m);
618 for(;;) {
619 if(SSC_STATUS & (SSC_STATUS_TX_READY)) {
620 SSC_TRANSMIT_HOLDING = 0x43;
621 if (ledcontrol)
622 LED_D_ON();
623 }
624 if(SSC_STATUS & (SSC_STATUS_RX_READY)) {
625 dest[i] = (BYTE)SSC_RECEIVE_HOLDING;
626 // we don't care about actual value, only if it's more or less than a
627 // threshold essentially we capture zero crossings for later analysis
628 if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
629 i++;
630 if (ledcontrol)
631 LED_D_OFF();
632 if(i >= m) {
633 break;
634 }
635 }
636 }
637
638 // FSK demodulator
639
640 // sync to first lo-hi transition
641 for( idx=1; idx<m; idx++) {
642 if (dest[idx-1]<dest[idx])
643 lastval=idx;
644 break;
645 }
646 WDT_HIT();
647
648 // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
649 // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
650 // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
651 for( i=0; idx<m; idx++) {
652 if (dest[idx-1]<dest[idx]) {
653 dest[i]=idx-lastval;
654 if (dest[i] <= 8) {
655 dest[i]=1;
656 } else {
657 dest[i]=0;
658 }
659
660 lastval=idx;
661 i++;
662 }
663 }
664 m=i;
665 WDT_HIT();
666
667 // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
668 lastval=dest[0];
669 idx=0;
670 i=0;
671 n=0;
672 for( idx=0; idx<m; idx++) {
673 if (dest[idx]==lastval) {
674 n++;
675 } else {
676 // a bit time is five fc/10 or six fc/8 cycles so figure out how many bits a pattern width represents,
677 // an extra fc/8 pattern preceeds every 4 bits (about 200 cycles) just to complicate things but it gets
678 // swallowed up by rounding
679 // expected results are 1 or 2 bits, any more and it's an invalid manchester encoding
680 // special start of frame markers use invalid manchester states (no transitions) by using sequences
681 // like 111000
682 if (dest[idx-1]) {
683 n=(n+1)/6; // fc/8 in sets of 6
684 } else {
685 n=(n+1)/5; // fc/10 in sets of 5
686 }
687 switch (n) { // stuff appropriate bits in buffer
688 case 0:
689 case 1: // one bit
690 dest[i++]=dest[idx-1];
691 break;
692 case 2: // two bits
693 dest[i++]=dest[idx-1];
694 dest[i++]=dest[idx-1];
695 break;
696 case 3: // 3 bit start of frame markers
697 dest[i++]=dest[idx-1];
698 dest[i++]=dest[idx-1];
699 dest[i++]=dest[idx-1];
700 break;
701 // When a logic 0 is immediately followed by the start of the next transmisson
702 // (special pattern) a pattern of 4 bit duration lengths is created.
703 case 4:
704 dest[i++]=dest[idx-1];
705 dest[i++]=dest[idx-1];
706 dest[i++]=dest[idx-1];
707 dest[i++]=dest[idx-1];
708 break;
709 default: // this shouldn't happen, don't stuff any bits
710 break;
711 }
712 n=0;
713 lastval=dest[idx];
714 }
715 }
716 m=i;
717 WDT_HIT();
718
719 // final loop, go over previously decoded manchester data and decode into usable tag ID
720 // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
721 for( idx=0; idx<m-6; idx++) {
722 // search for a start of frame marker
723 if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) )
724 {
725 found=1;
726 idx+=6;
727 if (found && (hi|lo)) {
728 DbpString("TAG ID");
729 DbpIntegers(hi, lo, (lo>>1)&0xffff);
730 /* if we're only looking for one tag */
731 if (findone)
732 {
733 *high = hi;
734 *low = lo;
735 return;
736 }
737 hi=0;
738 lo=0;
739 found=0;
740 }
741 }
742 if (found) {
743 if (dest[idx] && (!dest[idx+1]) ) {
744 hi=(hi<<1)|(lo>>31);
745 lo=(lo<<1)|0;
746 } else if ( (!dest[idx]) && dest[idx+1]) {
747 hi=(hi<<1)|(lo>>31);
748 lo=(lo<<1)|1;
749 } else {
750 found=0;
751 hi=0;
752 lo=0;
753 }
754 idx++;
755 }
756 if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) )
757 {
758 found=1;
759 idx+=6;
760 if (found && (hi|lo)) {
761 DbpString("TAG ID");
762 DbpIntegers(hi, lo, (lo>>1)&0xffff);
763 /* if we're only looking for one tag */
764 if (findone)
765 {
766 *high = hi;
767 *low = lo;
768 return;
769 }
770 hi=0;
771 lo=0;
772 found=0;
773 }
774 }
775 }
776 WDT_HIT();
777 }
778 }
Impressum, Datenschutz