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