]> cvs.zerfleddert.de Git - proxmark3-svn/blame - armsrc/lfops.c
Merge remote-tracking branch 'origin/master' into PenturaLabs-iclass-research
[proxmark3-svn] / armsrc / lfops.c
CommitLineData
15c4dc5a 1//-----------------------------------------------------------------------------
bd20f8f4 2// This code is licensed to you under the terms of the GNU GPL, version 2 or,
3// at your option, any later version. See the LICENSE.txt file for the text of
4// the license.
5//-----------------------------------------------------------------------------
15c4dc5a 6// Miscellaneous routines for low frequency tag operations.
7// Tags supported here so far are Texas Instruments (TI), HID
8// Also routines for raw mode reading/simulating of LF waveform
15c4dc5a 9//-----------------------------------------------------------------------------
bd20f8f4 10
e30c654b 11#include "proxmark3.h"
15c4dc5a 12#include "apps.h"
f7e3ed82 13#include "util.h"
15c4dc5a 14#include "hitag2.h"
15#include "crc16.h"
9ab7a6c7 16#include "string.h"
15c4dc5a 17
b014c96d 18void LFSetupFPGAForADC(int divisor, bool lf_field)
15c4dc5a 19{
7cc204bf 20 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
bf7163bd 21 if ( (divisor == 1) || (divisor < 0) || (divisor > 255) )
15c4dc5a 22 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
bf7163bd 23 else if (divisor == 0)
15c4dc5a 24 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
bf7163bd 25 else
26 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, divisor);
15c4dc5a 27
b014c96d 28 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | (lf_field ? FPGA_LF_ADC_READER_FIELD : 0));
15c4dc5a 29
30 // Connect the A/D to the peak-detected low-frequency path.
31 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
15c4dc5a 32 // Give it a bit of time for the resonant antenna to settle.
33 SpinDelay(50);
15c4dc5a 34 // Now set up the SSC to get the ADC samples that are now streaming at us.
35 FpgaSetupSsc();
b014c96d 36}
37
38void AcquireRawAdcSamples125k(int divisor)
39{
40 LFSetupFPGAForADC(divisor, true);
41 DoAcquisition125k(-1);
42}
15c4dc5a 43
b014c96d 44void SnoopLFRawAdcSamples(int divisor, int trigger_threshold)
45{
46 LFSetupFPGAForADC(divisor, false);
47 DoAcquisition125k(trigger_threshold);
15c4dc5a 48}
49
50// split into two routines so we can avoid timing issues after sending commands //
b014c96d 51void DoAcquisition125k(int trigger_threshold)
15c4dc5a 52{
f7e3ed82 53 uint8_t *dest = (uint8_t *)BigBuf;
15c4dc5a 54 int n = sizeof(BigBuf);
55 int i;
e30c654b 56
15c4dc5a 57 memset(dest, 0, n);
58 i = 0;
59 for(;;) {
60 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
61 AT91C_BASE_SSC->SSC_THR = 0x43;
62 LED_D_ON();
63 }
64 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
f7e3ed82 65 dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
15c4dc5a 66 LED_D_OFF();
b014c96d 67 if (trigger_threshold != -1 && dest[i] < trigger_threshold)
68 continue;
69 else
70 trigger_threshold = -1;
71 if (++i >= n) break;
15c4dc5a 72 }
73 }
74 Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
75 dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
76}
77
f7e3ed82 78void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
15c4dc5a 79{
f7e3ed82 80 int at134khz;
15c4dc5a 81
82 /* Make sure the tag is reset */
7cc204bf 83 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
15c4dc5a 84 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
85 SpinDelay(2500);
e30c654b 86
15c4dc5a 87 // see if 'h' was specified
88 if (command[strlen((char *) command) - 1] == 'h')
89 at134khz = TRUE;
90 else
91 at134khz = FALSE;
92
93 if (at134khz)
94 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
95 else
96 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
97
b014c96d 98 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
15c4dc5a 99
100 // Give it a bit of time for the resonant antenna to settle.
101 SpinDelay(50);
102 // And a little more time for the tag to fully power up
103 SpinDelay(2000);
104
105 // Now set up the SSC to get the ADC samples that are now streaming at us.
106 FpgaSetupSsc();
107
108 // now modulate the reader field
109 while(*command != '\0' && *command != ' ') {
110 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
111 LED_D_OFF();
112 SpinDelayUs(delay_off);
113 if (at134khz)
114 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
115 else
116 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
117
b014c96d 118 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
15c4dc5a 119 LED_D_ON();
120 if(*(command++) == '0')
121 SpinDelayUs(period_0);
122 else
123 SpinDelayUs(period_1);
124 }
125 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
126 LED_D_OFF();
127 SpinDelayUs(delay_off);
128 if (at134khz)
129 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
130 else
131 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
132
b014c96d 133 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
15c4dc5a 134
135 // now do the read
b014c96d 136 DoAcquisition125k(-1);
15c4dc5a 137}
138
139/* blank r/w tag data stream
140...0000000000000000 01111111
1411010101010101010101010101010101010101010101010101010101010101010
1420011010010100001
14301111111
144101010101010101[0]000...
145
146[5555fe852c5555555555555555fe0000]
147*/
148void ReadTItag(void)
149{
150 // some hardcoded initial params
151 // when we read a TI tag we sample the zerocross line at 2Mhz
152 // TI tags modulate a 1 as 16 cycles of 123.2Khz
153 // TI tags modulate a 0 as 16 cycles of 134.2Khz
154 #define FSAMPLE 2000000
155 #define FREQLO 123200
156 #define FREQHI 134200
157
158 signed char *dest = (signed char *)BigBuf;
159 int n = sizeof(BigBuf);
160// int *dest = GraphBuffer;
161// int n = GraphTraceLen;
162
163 // 128 bit shift register [shift3:shift2:shift1:shift0]
f7e3ed82 164 uint32_t shift3 = 0, shift2 = 0, shift1 = 0, shift0 = 0;
15c4dc5a 165
166 int i, cycles=0, samples=0;
167 // how many sample points fit in 16 cycles of each frequency
f7e3ed82 168 uint32_t sampleslo = (FSAMPLE<<4)/FREQLO, sampleshi = (FSAMPLE<<4)/FREQHI;
15c4dc5a 169 // when to tell if we're close enough to one freq or another
f7e3ed82 170 uint32_t threshold = (sampleslo - sampleshi + 1)>>1;
15c4dc5a 171
172 // TI tags charge at 134.2Khz
7cc204bf 173 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
15c4dc5a 174 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
175
176 // Place FPGA in passthrough mode, in this mode the CROSS_LO line
177 // connects to SSP_DIN and the SSP_DOUT logic level controls
178 // whether we're modulating the antenna (high)
179 // or listening to the antenna (low)
180 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
181
182 // get TI tag data into the buffer
183 AcquireTiType();
184
185 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
186
187 for (i=0; i<n-1; i++) {
188 // count cycles by looking for lo to hi zero crossings
189 if ( (dest[i]<0) && (dest[i+1]>0) ) {
190 cycles++;
191 // after 16 cycles, measure the frequency
192 if (cycles>15) {
193 cycles=0;
194 samples=i-samples; // number of samples in these 16 cycles
195
196 // TI bits are coming to us lsb first so shift them
197 // right through our 128 bit right shift register
198 shift0 = (shift0>>1) | (shift1 << 31);
199 shift1 = (shift1>>1) | (shift2 << 31);
200 shift2 = (shift2>>1) | (shift3 << 31);
201 shift3 >>= 1;
202
203 // check if the cycles fall close to the number
204 // expected for either the low or high frequency
205 if ( (samples>(sampleslo-threshold)) && (samples<(sampleslo+threshold)) ) {
206 // low frequency represents a 1
207 shift3 |= (1<<31);
208 } else if ( (samples>(sampleshi-threshold)) && (samples<(sampleshi+threshold)) ) {
209 // high frequency represents a 0
210 } else {
211 // probably detected a gay waveform or noise
212 // use this as gaydar or discard shift register and start again
213 shift3 = shift2 = shift1 = shift0 = 0;
214 }
215 samples = i;
216
217 // for each bit we receive, test if we've detected a valid tag
218
219 // if we see 17 zeroes followed by 6 ones, we might have a tag
220 // remember the bits are backwards
221 if ( ((shift0 & 0x7fffff) == 0x7e0000) ) {
222 // if start and end bytes match, we have a tag so break out of the loop
223 if ( ((shift0>>16)&0xff) == ((shift3>>8)&0xff) ) {
224 cycles = 0xF0B; //use this as a flag (ugly but whatever)
225 break;
226 }
227 }
228 }
229 }
230 }
231
232 // if flag is set we have a tag
233 if (cycles!=0xF0B) {
234 DbpString("Info: No valid tag detected.");
235 } else {
236 // put 64 bit data into shift1 and shift0
237 shift0 = (shift0>>24) | (shift1 << 8);
238 shift1 = (shift1>>24) | (shift2 << 8);
239
240 // align 16 bit crc into lower half of shift2
241 shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff;
242
243 // if r/w tag, check ident match
244 if ( shift3&(1<<15) ) {
245 DbpString("Info: TI tag is rewriteable");
246 // only 15 bits compare, last bit of ident is not valid
247 if ( ((shift3>>16)^shift0)&0x7fff ) {
248 DbpString("Error: Ident mismatch!");
249 } else {
250 DbpString("Info: TI tag ident is valid");
251 }
252 } else {
253 DbpString("Info: TI tag is readonly");
254 }
255
256 // WARNING the order of the bytes in which we calc crc below needs checking
257 // i'm 99% sure the crc algorithm is correct, but it may need to eat the
258 // bytes in reverse or something
259 // calculate CRC
f7e3ed82 260 uint32_t crc=0;
15c4dc5a 261
262 crc = update_crc16(crc, (shift0)&0xff);
263 crc = update_crc16(crc, (shift0>>8)&0xff);
264 crc = update_crc16(crc, (shift0>>16)&0xff);
265 crc = update_crc16(crc, (shift0>>24)&0xff);
266 crc = update_crc16(crc, (shift1)&0xff);
267 crc = update_crc16(crc, (shift1>>8)&0xff);
268 crc = update_crc16(crc, (shift1>>16)&0xff);
269 crc = update_crc16(crc, (shift1>>24)&0xff);
270
271 Dbprintf("Info: Tag data: %x%08x, crc=%x",
272 (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF);
273 if (crc != (shift2&0xffff)) {
274 Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc);
275 } else {
276 DbpString("Info: CRC is good");
277 }
278 }
279}
280
f7e3ed82 281void WriteTIbyte(uint8_t b)
15c4dc5a 282{
283 int i = 0;
284
285 // modulate 8 bits out to the antenna
286 for (i=0; i<8; i++)
287 {
288 if (b&(1<<i)) {
289 // stop modulating antenna
290 LOW(GPIO_SSC_DOUT);
291 SpinDelayUs(1000);
292 // modulate antenna
293 HIGH(GPIO_SSC_DOUT);
294 SpinDelayUs(1000);
295 } else {
296 // stop modulating antenna
297 LOW(GPIO_SSC_DOUT);
298 SpinDelayUs(300);
299 // modulate antenna
300 HIGH(GPIO_SSC_DOUT);
301 SpinDelayUs(1700);
302 }
303 }
304}
305
306void AcquireTiType(void)
307{
308 int i, j, n;
309 // tag transmission is <20ms, sampling at 2M gives us 40K samples max
f7e3ed82 310 // each sample is 1 bit stuffed into a uint32_t so we need 1250 uint32_t
15c4dc5a 311 #define TIBUFLEN 1250
312
313 // clear buffer
314 memset(BigBuf,0,sizeof(BigBuf));
315
316 // Set up the synchronous serial port
317 AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DIN;
318 AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN;
319
320 // steal this pin from the SSP and use it to control the modulation
321 AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
322 AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
323
324 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_SWRST;
325 AT91C_BASE_SSC->SSC_CR = AT91C_SSC_RXEN | AT91C_SSC_TXEN;
326
327 // Sample at 2 Mbit/s, so TI tags are 16.2 vs. 14.9 clocks long
328 // 48/2 = 24 MHz clock must be divided by 12
329 AT91C_BASE_SSC->SSC_CMR = 12;
330
331 AT91C_BASE_SSC->SSC_RCMR = SSC_CLOCK_MODE_SELECT(0);
332 AT91C_BASE_SSC->SSC_RFMR = SSC_FRAME_MODE_BITS_IN_WORD(32) | AT91C_SSC_MSBF;
333 AT91C_BASE_SSC->SSC_TCMR = 0;
334 AT91C_BASE_SSC->SSC_TFMR = 0;
335
336 LED_D_ON();
337
338 // modulate antenna
339 HIGH(GPIO_SSC_DOUT);
340
341 // Charge TI tag for 50ms.
342 SpinDelay(50);
343
344 // stop modulating antenna and listen
345 LOW(GPIO_SSC_DOUT);
346
347 LED_D_OFF();
348
349 i = 0;
350 for(;;) {
351 if(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
352 BigBuf[i] = AT91C_BASE_SSC->SSC_RHR; // store 32 bit values in buffer
353 i++; if(i >= TIBUFLEN) break;
354 }
355 WDT_HIT();
356 }
357
358 // return stolen pin to SSP
359 AT91C_BASE_PIOA->PIO_PDR = GPIO_SSC_DOUT;
360 AT91C_BASE_PIOA->PIO_ASR = GPIO_SSC_DIN | GPIO_SSC_DOUT;
361
362 char *dest = (char *)BigBuf;
363 n = TIBUFLEN*32;
364 // unpack buffer
365 for (i=TIBUFLEN-1; i>=0; i--) {
366 for (j=0; j<32; j++) {
367 if(BigBuf[i] & (1 << j)) {
368 dest[--n] = 1;
369 } else {
370 dest[--n] = -1;
371 }
372 }
373 }
374}
375
376// arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc
377// if crc provided, it will be written with the data verbatim (even if bogus)
378// if not provided a valid crc will be computed from the data and written.
f7e3ed82 379void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
15c4dc5a 380{
7cc204bf 381 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
15c4dc5a 382 if(crc == 0) {
383 crc = update_crc16(crc, (idlo)&0xff);
384 crc = update_crc16(crc, (idlo>>8)&0xff);
385 crc = update_crc16(crc, (idlo>>16)&0xff);
386 crc = update_crc16(crc, (idlo>>24)&0xff);
387 crc = update_crc16(crc, (idhi)&0xff);
388 crc = update_crc16(crc, (idhi>>8)&0xff);
389 crc = update_crc16(crc, (idhi>>16)&0xff);
390 crc = update_crc16(crc, (idhi>>24)&0xff);
391 }
392 Dbprintf("Writing to tag: %x%08x, crc=%x",
393 (unsigned int) idhi, (unsigned int) idlo, crc);
394
395 // TI tags charge at 134.2Khz
396 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 88); //134.8Khz
397 // Place FPGA in passthrough mode, in this mode the CROSS_LO line
398 // connects to SSP_DIN and the SSP_DOUT logic level controls
399 // whether we're modulating the antenna (high)
400 // or listening to the antenna (low)
401 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU);
402 LED_A_ON();
403
404 // steal this pin from the SSP and use it to control the modulation
405 AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
406 AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
407
408 // writing algorithm:
409 // a high bit consists of a field off for 1ms and field on for 1ms
410 // a low bit consists of a field off for 0.3ms and field on for 1.7ms
411 // initiate a charge time of 50ms (field on) then immediately start writing bits
412 // start by writing 0xBB (keyword) and 0xEB (password)
413 // then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer)
414 // finally end with 0x0300 (write frame)
415 // all data is sent lsb firts
416 // finish with 15ms programming time
417
418 // modulate antenna
419 HIGH(GPIO_SSC_DOUT);
420 SpinDelay(50); // charge time
421
422 WriteTIbyte(0xbb); // keyword
423 WriteTIbyte(0xeb); // password
424 WriteTIbyte( (idlo )&0xff );
425 WriteTIbyte( (idlo>>8 )&0xff );
426 WriteTIbyte( (idlo>>16)&0xff );
427 WriteTIbyte( (idlo>>24)&0xff );
428 WriteTIbyte( (idhi )&0xff );
429 WriteTIbyte( (idhi>>8 )&0xff );
430 WriteTIbyte( (idhi>>16)&0xff );
431 WriteTIbyte( (idhi>>24)&0xff ); // data hi to lo
432 WriteTIbyte( (crc )&0xff ); // crc lo
433 WriteTIbyte( (crc>>8 )&0xff ); // crc hi
434 WriteTIbyte(0x00); // write frame lo
435 WriteTIbyte(0x03); // write frame hi
436 HIGH(GPIO_SSC_DOUT);
437 SpinDelay(50); // programming time
438
439 LED_A_OFF();
440
441 // get TI tag data into the buffer
442 AcquireTiType();
443
444 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
445 DbpString("Now use tiread to check");
446}
447
448void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
449{
450 int i;
f7e3ed82 451 uint8_t *tab = (uint8_t *)BigBuf;
d19929cb 452
7cc204bf 453 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
d19929cb 454 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_EDGE_DETECT);
455
15c4dc5a 456 AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT | GPIO_SSC_CLK;
d19929cb 457
15c4dc5a 458 AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
459 AT91C_BASE_PIOA->PIO_ODR = GPIO_SSC_CLK;
d19929cb 460
15c4dc5a 461#define SHORT_COIL() LOW(GPIO_SSC_DOUT)
462#define OPEN_COIL() HIGH(GPIO_SSC_DOUT)
d19929cb 463
15c4dc5a 464 i = 0;
465 for(;;) {
466 while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
467 if(BUTTON_PRESS()) {
468 DbpString("Stopped");
469 return;
470 }
471 WDT_HIT();
472 }
d19929cb 473
15c4dc5a 474 if (ledcontrol)
475 LED_D_ON();
d19929cb 476
15c4dc5a 477 if(tab[i])
478 OPEN_COIL();
479 else
480 SHORT_COIL();
d19929cb 481
15c4dc5a 482 if (ledcontrol)
483 LED_D_OFF();
d19929cb 484
15c4dc5a 485 while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
486 if(BUTTON_PRESS()) {
487 DbpString("Stopped");
488 return;
489 }
490 WDT_HIT();
491 }
d19929cb 492
15c4dc5a 493 i++;
494 if(i == period) {
495 i = 0;
e30c654b 496 if (gap) {
15c4dc5a 497 SHORT_COIL();
498 SpinDelayUs(gap);
499 }
500 }
501 }
502}
503
15c4dc5a 504#define DEBUG_FRAME_CONTENTS 1
505void SimulateTagLowFrequencyBidir(int divisor, int t0)
506{
15c4dc5a 507}
508
509// compose fc/8 fc/10 waveform
510static void fc(int c, int *n) {
f7e3ed82 511 uint8_t *dest = (uint8_t *)BigBuf;
15c4dc5a 512 int idx;
513
514 // for when we want an fc8 pattern every 4 logical bits
515 if(c==0) {
516 dest[((*n)++)]=1;
517 dest[((*n)++)]=1;
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 // an fc/8 encoded bit is a bit pattern of 11000000 x6 = 48 samples
526 if(c==8) {
527 for (idx=0; idx<6; idx++) {
528 dest[((*n)++)]=1;
529 dest[((*n)++)]=1;
530 dest[((*n)++)]=0;
531 dest[((*n)++)]=0;
532 dest[((*n)++)]=0;
533 dest[((*n)++)]=0;
534 dest[((*n)++)]=0;
535 dest[((*n)++)]=0;
536 }
537 }
538
539 // an fc/10 encoded bit is a bit pattern of 1110000000 x5 = 50 samples
540 if(c==10) {
541 for (idx=0; idx<5; idx++) {
542 dest[((*n)++)]=1;
543 dest[((*n)++)]=1;
544 dest[((*n)++)]=1;
545 dest[((*n)++)]=0;
546 dest[((*n)++)]=0;
547 dest[((*n)++)]=0;
548 dest[((*n)++)]=0;
549 dest[((*n)++)]=0;
550 dest[((*n)++)]=0;
551 dest[((*n)++)]=0;
552 }
553 }
554}
555
556// prepare a waveform pattern in the buffer based on the ID given then
557// simulate a HID tag until the button is pressed
558void CmdHIDsimTAG(int hi, int lo, int ledcontrol)
559{
560 int n=0, i=0;
561 /*
562 HID tag bitstream format
563 The tag contains a 44bit unique code. This is sent out MSB first in sets of 4 bits
564 A 1 bit is represented as 6 fc8 and 5 fc10 patterns
565 A 0 bit is represented as 5 fc10 and 6 fc8 patterns
566 A fc8 is inserted before every 4 bits
567 A special start of frame pattern is used consisting a0b0 where a and b are neither 0
568 nor 1 bits, they are special patterns (a = set of 12 fc8 and b = set of 10 fc10)
569 */
570
571 if (hi>0xFFF) {
572 DbpString("Tags can only have 44 bits.");
573 return;
574 }
575 fc(0,&n);
576 // special start of frame marker containing invalid bit sequences
577 fc(8, &n); fc(8, &n); // invalid
578 fc(8, &n); fc(10, &n); // logical 0
579 fc(10, &n); fc(10, &n); // invalid
580 fc(8, &n); fc(10, &n); // logical 0
581
582 WDT_HIT();
583 // manchester encode bits 43 to 32
584 for (i=11; i>=0; i--) {
585 if ((i%4)==3) fc(0,&n);
586 if ((hi>>i)&1) {
587 fc(10, &n); fc(8, &n); // low-high transition
588 } else {
589 fc(8, &n); fc(10, &n); // high-low transition
590 }
591 }
592
593 WDT_HIT();
594 // manchester encode bits 31 to 0
595 for (i=31; i>=0; i--) {
596 if ((i%4)==3) fc(0,&n);
597 if ((lo>>i)&1) {
598 fc(10, &n); fc(8, &n); // low-high transition
599 } else {
600 fc(8, &n); fc(10, &n); // high-low transition
601 }
602 }
603
604 if (ledcontrol)
605 LED_A_ON();
606 SimulateTagLowFrequency(n, 0, ledcontrol);
607
608 if (ledcontrol)
609 LED_A_OFF();
610}
611
612
613// loop to capture raw HID waveform then FSK demodulate the TAG ID from it
614void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
615{
f7e3ed82 616 uint8_t *dest = (uint8_t *)BigBuf;
15c4dc5a 617 int m=0, n=0, i=0, idx=0, found=0, lastval=0;
54a942b0 618 uint32_t hi2=0, hi=0, lo=0;
15c4dc5a 619
7cc204bf 620 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
15c4dc5a 621 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 622 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
15c4dc5a 623
624 // Connect the A/D to the peak-detected low-frequency path.
625 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
626
627 // Give it a bit of time for the resonant antenna to settle.
628 SpinDelay(50);
629
630 // Now set up the SSC to get the ADC samples that are now streaming at us.
631 FpgaSetupSsc();
632
633 for(;;) {
634 WDT_HIT();
635 if (ledcontrol)
636 LED_A_ON();
637 if(BUTTON_PRESS()) {
638 DbpString("Stopped");
639 if (ledcontrol)
640 LED_A_OFF();
641 return;
642 }
643
644 i = 0;
645 m = sizeof(BigBuf);
646 memset(dest,128,m);
647 for(;;) {
648 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
649 AT91C_BASE_SSC->SSC_THR = 0x43;
650 if (ledcontrol)
651 LED_D_ON();
652 }
653 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
f7e3ed82 654 dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
15c4dc5a 655 // we don't care about actual value, only if it's more or less than a
656 // threshold essentially we capture zero crossings for later analysis
657 if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
658 i++;
659 if (ledcontrol)
660 LED_D_OFF();
661 if(i >= m) {
662 break;
663 }
664 }
665 }
666
667 // FSK demodulator
668
669 // sync to first lo-hi transition
670 for( idx=1; idx<m; idx++) {
671 if (dest[idx-1]<dest[idx])
672 lastval=idx;
673 break;
674 }
675 WDT_HIT();
676
677 // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
678 // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
679 // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
680 for( i=0; idx<m; idx++) {
681 if (dest[idx-1]<dest[idx]) {
682 dest[i]=idx-lastval;
683 if (dest[i] <= 8) {
684 dest[i]=1;
685 } else {
686 dest[i]=0;
687 }
688
689 lastval=idx;
690 i++;
691 }
692 }
693 m=i;
694 WDT_HIT();
695
696 // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
697 lastval=dest[0];
698 idx=0;
699 i=0;
700 n=0;
701 for( idx=0; idx<m; idx++) {
702 if (dest[idx]==lastval) {
703 n++;
704 } else {
705 // a bit time is five fc/10 or six fc/8 cycles so figure out how many bits a pattern width represents,
706 // an extra fc/8 pattern preceeds every 4 bits (about 200 cycles) just to complicate things but it gets
707 // swallowed up by rounding
708 // expected results are 1 or 2 bits, any more and it's an invalid manchester encoding
709 // special start of frame markers use invalid manchester states (no transitions) by using sequences
710 // like 111000
711 if (dest[idx-1]) {
712 n=(n+1)/6; // fc/8 in sets of 6
713 } else {
714 n=(n+1)/5; // fc/10 in sets of 5
715 }
716 switch (n) { // stuff appropriate bits in buffer
717 case 0:
718 case 1: // one bit
719 dest[i++]=dest[idx-1];
720 break;
721 case 2: // two bits
722 dest[i++]=dest[idx-1];
723 dest[i++]=dest[idx-1];
724 break;
725 case 3: // 3 bit start of frame markers
726 dest[i++]=dest[idx-1];
727 dest[i++]=dest[idx-1];
728 dest[i++]=dest[idx-1];
729 break;
730 // When a logic 0 is immediately followed by the start of the next transmisson
731 // (special pattern) a pattern of 4 bit duration lengths is created.
732 case 4:
733 dest[i++]=dest[idx-1];
734 dest[i++]=dest[idx-1];
735 dest[i++]=dest[idx-1];
736 dest[i++]=dest[idx-1];
737 break;
738 default: // this shouldn't happen, don't stuff any bits
739 break;
740 }
741 n=0;
742 lastval=dest[idx];
743 }
744 }
745 m=i;
746 WDT_HIT();
747
748 // final loop, go over previously decoded manchester data and decode into usable tag ID
749 // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
750 for( idx=0; idx<m-6; idx++) {
751 // search for a start of frame marker
752 if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) )
753 {
754 found=1;
755 idx+=6;
54a942b0 756 if (found && (hi2|hi|lo)) {
757 if (hi2 != 0){
758 Dbprintf("TAG ID: %x%08x%08x (%d)",
759 (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
760 }
761 else {
762 Dbprintf("TAG ID: %x%08x (%d)",
763 (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
764 }
15c4dc5a 765 /* if we're only looking for one tag */
766 if (findone)
767 {
768 *high = hi;
769 *low = lo;
770 return;
771 }
54a942b0 772 hi2=0;
15c4dc5a 773 hi=0;
774 lo=0;
775 found=0;
776 }
777 }
778 if (found) {
779 if (dest[idx] && (!dest[idx+1]) ) {
54a942b0 780 hi2=(hi2<<1)|(hi>>31);
15c4dc5a 781 hi=(hi<<1)|(lo>>31);
782 lo=(lo<<1)|0;
783 } else if ( (!dest[idx]) && dest[idx+1]) {
54a942b0 784 hi2=(hi2<<1)|(hi>>31);
15c4dc5a 785 hi=(hi<<1)|(lo>>31);
786 lo=(lo<<1)|1;
787 } else {
788 found=0;
54a942b0 789 hi2=0;
15c4dc5a 790 hi=0;
791 lo=0;
792 }
793 idx++;
794 }
795 if ( dest[idx] && dest[idx+1] && dest[idx+2] && (!dest[idx+3]) && (!dest[idx+4]) && (!dest[idx+5]) )
796 {
797 found=1;
798 idx+=6;
799 if (found && (hi|lo)) {
54a942b0 800 if (hi2 != 0){
801 Dbprintf("TAG ID: %x%08x%08x (%d)",
802 (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
803 }
804 else {
805 Dbprintf("TAG ID: %x%08x (%d)",
806 (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
807 }
15c4dc5a 808 /* if we're only looking for one tag */
809 if (findone)
810 {
811 *high = hi;
812 *low = lo;
813 return;
814 }
54a942b0 815 hi2=0;
15c4dc5a 816 hi=0;
817 lo=0;
818 found=0;
819 }
820 }
821 }
822 WDT_HIT();
823 }
824}
ec09b62d 825
a1f3bb12 826void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
827{
828 uint8_t *dest = (uint8_t *)BigBuf;
829 int m=0, n=0, i=0, idx=0, lastval=0;
830 int found=0;
831 uint32_t code=0, code2=0;
832 //uint32_t hi2=0, hi=0, lo=0;
833
7cc204bf 834 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
a1f3bb12 835 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 836 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
a1f3bb12 837
838 // Connect the A/D to the peak-detected low-frequency path.
839 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
840
841 // Give it a bit of time for the resonant antenna to settle.
842 SpinDelay(50);
843
844 // Now set up the SSC to get the ADC samples that are now streaming at us.
845 FpgaSetupSsc();
846
847 for(;;) {
848 WDT_HIT();
849 if (ledcontrol)
850 LED_A_ON();
851 if(BUTTON_PRESS()) {
852 DbpString("Stopped");
853 if (ledcontrol)
854 LED_A_OFF();
855 return;
856 }
857
858 i = 0;
859 m = sizeof(BigBuf);
860 memset(dest,128,m);
861 for(;;) {
862 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
863 AT91C_BASE_SSC->SSC_THR = 0x43;
864 if (ledcontrol)
865 LED_D_ON();
866 }
867 if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
868 dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
869 // we don't care about actual value, only if it's more or less than a
870 // threshold essentially we capture zero crossings for later analysis
871 if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
872 i++;
873 if (ledcontrol)
874 LED_D_OFF();
875 if(i >= m) {
876 break;
877 }
878 }
879 }
880
881 // FSK demodulator
882
883 // sync to first lo-hi transition
884 for( idx=1; idx<m; idx++) {
885 if (dest[idx-1]<dest[idx])
886 lastval=idx;
887 break;
888 }
889 WDT_HIT();
890
891 // count cycles between consecutive lo-hi transitions, there should be either 8 (fc/8)
892 // or 10 (fc/10) cycles but in practice due to noise etc we may end up with with anywhere
893 // between 7 to 11 cycles so fuzz it by treat anything <9 as 8 and anything else as 10
894 for( i=0; idx<m; idx++) {
895 if (dest[idx-1]<dest[idx]) {
896 dest[i]=idx-lastval;
897 if (dest[i] <= 8) {
898 dest[i]=1;
899 } else {
900 dest[i]=0;
901 }
902
903 lastval=idx;
904 i++;
905 }
906 }
907 m=i;
908 WDT_HIT();
909
910 // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
911 lastval=dest[0];
912 idx=0;
913 i=0;
914 n=0;
915 for( idx=0; idx<m; idx++) {
916 if (dest[idx]==lastval) {
917 n++;
918 } else {
919 // a bit time is five fc/10 or six fc/8 cycles so figure out how many bits a pattern width represents,
920 // an extra fc/8 pattern preceeds every 4 bits (about 200 cycles) just to complicate things but it gets
921 // swallowed up by rounding
922 // expected results are 1 or 2 bits, any more and it's an invalid manchester encoding
923 // special start of frame markers use invalid manchester states (no transitions) by using sequences
924 // like 111000
925 if (dest[idx-1]) {
926 n=(n+1)/7; // fc/8 in sets of 7
927 } else {
928 n=(n+1)/6; // fc/10 in sets of 6
929 }
930 switch (n) { // stuff appropriate bits in buffer
931 case 0:
932 case 1: // one bit
933 dest[i++]=dest[idx-1]^1;
934 //Dbprintf("%d",dest[idx-1]);
935 break;
936 case 2: // two bits
937 dest[i++]=dest[idx-1]^1;
938 dest[i++]=dest[idx-1]^1;
939 //Dbprintf("%d",dest[idx-1]);
940 //Dbprintf("%d",dest[idx-1]);
941 break;
942 case 3: // 3 bit start of frame markers
943 for(int j=0; j<3; j++){
944 dest[i++]=dest[idx-1]^1;
945 // Dbprintf("%d",dest[idx-1]);
946 }
947 break;
948 case 4:
949 for(int j=0; j<4; j++){
950 dest[i++]=dest[idx-1]^1;
951 // Dbprintf("%d",dest[idx-1]);
952 }
953 break;
954 case 5:
955 for(int j=0; j<5; j++){
956 dest[i++]=dest[idx-1]^1;
957 // Dbprintf("%d",dest[idx-1]);
958 }
959 break;
960 case 6:
961 for(int j=0; j<6; j++){
962 dest[i++]=dest[idx-1]^1;
963 // Dbprintf("%d",dest[idx-1]);
964 }
965 break;
966 case 7:
967 for(int j=0; j<7; j++){
968 dest[i++]=dest[idx-1]^1;
969 // Dbprintf("%d",dest[idx-1]);
970 }
971 break;
972 case 8:
973 for(int j=0; j<8; j++){
974 dest[i++]=dest[idx-1]^1;
975 // Dbprintf("%d",dest[idx-1]);
976 }
977 break;
978 case 9:
979 for(int j=0; j<9; j++){
980 dest[i++]=dest[idx-1]^1;
981 // Dbprintf("%d",dest[idx-1]);
982 }
983 break;
984 case 10:
985 for(int j=0; j<10; j++){
986 dest[i++]=dest[idx-1]^1;
987 // Dbprintf("%d",dest[idx-1]);
988 }
989 break;
990 case 11:
991 for(int j=0; j<11; j++){
992 dest[i++]=dest[idx-1]^1;
993 // Dbprintf("%d",dest[idx-1]);
994 }
995 break;
996 case 12:
997 for(int j=0; j<12; j++){
998 dest[i++]=dest[idx-1]^1;
999 // Dbprintf("%d",dest[idx-1]);
1000 }
1001 break;
1002 default: // this shouldn't happen, don't stuff any bits
1003 //Dbprintf("%d",dest[idx-1]);
1004 break;
1005 }
1006 n=0;
1007 lastval=dest[idx];
1008 }
1009 }//end for
1010 /*for(int j=0; j<64;j+=8){
1011 Dbprintf("%d%d%d%d%d%d%d%d",dest[j],dest[j+1],dest[j+2],dest[j+3],dest[j+4],dest[j+5],dest[j+6],dest[j+7]);
1012 }
1013 Dbprintf("\n");*/
1014 m=i;
1015 WDT_HIT();
1016
1017 for( idx=0; idx<m-9; idx++) {
1018 if ( !(dest[idx]) && !(dest[idx+1]) && !(dest[idx+2]) && !(dest[idx+3]) && !(dest[idx+4]) && !(dest[idx+5]) && !(dest[idx+6]) && !(dest[idx+7]) && !(dest[idx+8])&& (dest[idx+9])){
1019 found=1;
1020 //idx+=9;
1021 if (found) {
1022 Dbprintf("%d%d%d%d%d%d%d%d",dest[idx], dest[idx+1], dest[idx+2],dest[idx+3],dest[idx+4],dest[idx+5],dest[idx+6],dest[idx+7]);
1023 Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+8], dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15]);
1024 Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+16],dest[idx+17],dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23]);
1025 Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+24],dest[idx+25],dest[idx+26],dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31]);
1026 Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35],dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39]);
1027 Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44],dest[idx+45],dest[idx+46],dest[idx+47]);
1028 Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53],dest[idx+54],dest[idx+55]);
1029 Dbprintf("%d%d%d%d%d%d%d%d",dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
1030
1031 short version='\x00';
1032 char unknown='\x00';
1033 uint16_t number=0;
1034 for(int j=14;j<18;j++){
1035 //Dbprintf("%d",dest[idx+j]);
1036 version <<=1;
1037 if (dest[idx+j]) version |= 1;
1038 }
1039 for(int j=19;j<27;j++){
1040 //Dbprintf("%d",dest[idx+j]);
1041 unknown <<=1;
1042 if (dest[idx+j]) unknown |= 1;
1043 }
1044 for(int j=36;j<45;j++){
1045 //Dbprintf("%d",dest[idx+j]);
1046 number <<=1;
1047 if (dest[idx+j]) number |= 1;
1048 }
1049 for(int j=46;j<53;j++){
1050 //Dbprintf("%d",dest[idx+j]);
1051 number <<=1;
1052 if (dest[idx+j]) number |= 1;
1053 }
1054 for(int j=0; j<32; j++){
1055 code <<=1;
1056 if(dest[idx+j]) code |= 1;
1057 }
1058 for(int j=32; j<64; j++){
1059 code2 <<=1;
1060 if(dest[idx+j]) code2 |= 1;
1061 }
1062
1063 Dbprintf("XSF(%02d)%02x:%d (%08x%08x)",version,unknown,number,code,code2);
1064 if (ledcontrol)
1065 LED_D_OFF();
1066 }
1067 // if we're only looking for one tag
1068 if (findone){
1069 //*high = hi;
1070 //*low = lo;
1071 LED_A_OFF();
1072 return;
1073 }
1074
1075 //hi=0;
1076 //lo=0;
1077 found=0;
1078 }
1079
1080 }
1081 }
1082 WDT_HIT();
1083}
1084
2d4eae76 1085/*------------------------------
1086 * T5555/T5557/T5567 routines
1087 *------------------------------
1088 */
1089
1090/* T55x7 configuration register definitions */
1091#define T55x7_POR_DELAY 0x00000001
1092#define T55x7_ST_TERMINATOR 0x00000008
1093#define T55x7_PWD 0x00000010
1094#define T55x7_MAXBLOCK_SHIFT 5
1095#define T55x7_AOR 0x00000200
1096#define T55x7_PSKCF_RF_2 0
1097#define T55x7_PSKCF_RF_4 0x00000400
1098#define T55x7_PSKCF_RF_8 0x00000800
1099#define T55x7_MODULATION_DIRECT 0
1100#define T55x7_MODULATION_PSK1 0x00001000
1101#define T55x7_MODULATION_PSK2 0x00002000
1102#define T55x7_MODULATION_PSK3 0x00003000
1103#define T55x7_MODULATION_FSK1 0x00004000
1104#define T55x7_MODULATION_FSK2 0x00005000
1105#define T55x7_MODULATION_FSK1a 0x00006000
1106#define T55x7_MODULATION_FSK2a 0x00007000
1107#define T55x7_MODULATION_MANCHESTER 0x00008000
1108#define T55x7_MODULATION_BIPHASE 0x00010000
1109#define T55x7_BITRATE_RF_8 0
1110#define T55x7_BITRATE_RF_16 0x00040000
1111#define T55x7_BITRATE_RF_32 0x00080000
1112#define T55x7_BITRATE_RF_40 0x000C0000
1113#define T55x7_BITRATE_RF_50 0x00100000
1114#define T55x7_BITRATE_RF_64 0x00140000
1115#define T55x7_BITRATE_RF_100 0x00180000
1116#define T55x7_BITRATE_RF_128 0x001C0000
1117
1118/* T5555 (Q5) configuration register definitions */
1119#define T5555_ST_TERMINATOR 0x00000001
1120#define T5555_MAXBLOCK_SHIFT 0x00000001
1121#define T5555_MODULATION_MANCHESTER 0
1122#define T5555_MODULATION_PSK1 0x00000010
1123#define T5555_MODULATION_PSK2 0x00000020
1124#define T5555_MODULATION_PSK3 0x00000030
1125#define T5555_MODULATION_FSK1 0x00000040
1126#define T5555_MODULATION_FSK2 0x00000050
1127#define T5555_MODULATION_BIPHASE 0x00000060
1128#define T5555_MODULATION_DIRECT 0x00000070
1129#define T5555_INVERT_OUTPUT 0x00000080
1130#define T5555_PSK_RF_2 0
1131#define T5555_PSK_RF_4 0x00000100
1132#define T5555_PSK_RF_8 0x00000200
1133#define T5555_USE_PWD 0x00000400
1134#define T5555_USE_AOR 0x00000800
1135#define T5555_BITRATE_SHIFT 12
1136#define T5555_FAST_WRITE 0x00004000
1137#define T5555_PAGE_SELECT 0x00008000
1138
1139/*
1140 * Relevant times in microsecond
1141 * To compensate antenna falling times shorten the write times
1142 * and enlarge the gap ones.
1143 */
1144#define START_GAP 250
1145#define WRITE_GAP 160
1146#define WRITE_0 144 // 192
1147#define WRITE_1 400 // 432 for T55x7; 448 for E5550
1148
1149// Write one bit to card
1150void T55xxWriteBit(int bit)
ec09b62d 1151{
7cc204bf 1152 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
ec09b62d 1153 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 1154 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
2d4eae76 1155 if (bit == 0)
1156 SpinDelayUs(WRITE_0);
1157 else
1158 SpinDelayUs(WRITE_1);
ec09b62d 1159 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
2d4eae76 1160 SpinDelayUs(WRITE_GAP);
ec09b62d 1161}
1162
2d4eae76 1163// Write one card block in page 0, no lock
54a942b0 1164void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
ec09b62d 1165{
2d4eae76 1166 unsigned int i;
ec09b62d 1167
7cc204bf 1168 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
ec09b62d 1169 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 1170 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
ec09b62d 1171
1172 // Give it a bit of time for the resonant antenna to settle.
1173 // And for the tag to fully power up
1174 SpinDelay(150);
1175
2d4eae76 1176 // Now start writting
ec09b62d 1177 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
2d4eae76 1178 SpinDelayUs(START_GAP);
1179
1180 // Opcode
1181 T55xxWriteBit(1);
1182 T55xxWriteBit(0); //Page 0
54a942b0 1183 if (PwdMode == 1){
1184 // Pwd
1185 for (i = 0x80000000; i != 0; i >>= 1)
1186 T55xxWriteBit(Pwd & i);
1187 }
2d4eae76 1188 // Lock bit
1189 T55xxWriteBit(0);
1190
1191 // Data
1192 for (i = 0x80000000; i != 0; i >>= 1)
1193 T55xxWriteBit(Data & i);
1194
54a942b0 1195 // Block
2d4eae76 1196 for (i = 0x04; i != 0; i >>= 1)
1197 T55xxWriteBit(Block & i);
1198
1199 // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
1200 // so wait a little more)
1201 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 1202 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
ec09b62d 1203 SpinDelay(20);
2d4eae76 1204 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
ec09b62d 1205}
1206
54a942b0 1207// Read one card block in page 0
1208void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
ec09b62d 1209{
54a942b0 1210 uint8_t *dest = (uint8_t *)BigBuf;
1211 int m=0, i=0;
1212
7cc204bf 1213 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
54a942b0 1214 m = sizeof(BigBuf);
1215 // Clear destination buffer before sending the command
1216 memset(dest, 128, m);
1217 // Connect the A/D to the peak-detected low-frequency path.
1218 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
1219 // Now set up the SSC to get the ADC samples that are now streaming at us.
1220 FpgaSetupSsc();
1221
1222 LED_D_ON();
1223 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 1224 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
54a942b0 1225
1226 // Give it a bit of time for the resonant antenna to settle.
1227 // And for the tag to fully power up
1228 SpinDelay(150);
1229
1230 // Now start writting
1231 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1232 SpinDelayUs(START_GAP);
1233
1234 // Opcode
1235 T55xxWriteBit(1);
1236 T55xxWriteBit(0); //Page 0
1237 if (PwdMode == 1){
1238 // Pwd
1239 for (i = 0x80000000; i != 0; i >>= 1)
1240 T55xxWriteBit(Pwd & i);
ec09b62d 1241 }
54a942b0 1242 // Lock bit
1243 T55xxWriteBit(0);
1244 // Block
1245 for (i = 0x04; i != 0; i >>= 1)
1246 T55xxWriteBit(Block & i);
1247
1248 // Turn field on to read the response
1249 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 1250 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
54a942b0 1251
1252 // Now do the acquisition
1253 i = 0;
1254 for(;;) {
1255 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
1256 AT91C_BASE_SSC->SSC_THR = 0x43;
1257 }
1258 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
1259 dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
1260 // we don't care about actual value, only if it's more or less than a
1261 // threshold essentially we capture zero crossings for later analysis
1262 // if(dest[i] < 127) dest[i] = 0; else dest[i] = 1;
1263 i++;
1264 if (i >= m) break;
1265 }
ec09b62d 1266 }
54a942b0 1267
1268 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
1269 LED_D_OFF();
1270 DbpString("DONE!");
1271}
2d4eae76 1272
54a942b0 1273// Read card traceability data (page 1)
1274void T55xxReadTrace(void){
1275 uint8_t *dest = (uint8_t *)BigBuf;
1276 int m=0, i=0;
1277
7cc204bf 1278 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
54a942b0 1279 m = sizeof(BigBuf);
1280 // Clear destination buffer before sending the command
1281 memset(dest, 128, m);
1282 // Connect the A/D to the peak-detected low-frequency path.
1283 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
1284 // Now set up the SSC to get the ADC samples that are now streaming at us.
1285 FpgaSetupSsc();
1286
1287 LED_D_ON();
1288 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 1289 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
54a942b0 1290
1291 // Give it a bit of time for the resonant antenna to settle.
1292 // And for the tag to fully power up
1293 SpinDelay(150);
1294
1295 // Now start writting
1296 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
1297 SpinDelayUs(START_GAP);
1298
1299 // Opcode
1300 T55xxWriteBit(1);
1301 T55xxWriteBit(1); //Page 1
1302
1303 // Turn field on to read the response
1304 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 1305 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
54a942b0 1306
1307 // Now do the acquisition
1308 i = 0;
1309 for(;;) {
1310 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
1311 AT91C_BASE_SSC->SSC_THR = 0x43;
1312 }
1313 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
1314 dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
1315 i++;
1316 if (i >= m) break;
1317 }
ec09b62d 1318 }
54a942b0 1319
1320 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
1321 LED_D_OFF();
1322 DbpString("DONE!");
1323}
ec09b62d 1324
54a942b0 1325/*-------------- Cloning routines -----------*/
1326// Copy HID id to card and setup block 0 config
1327void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
1328{
1329 int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format
1330 int last_block = 0;
1331
1332 if (longFMT){
1333 // Ensure no more than 84 bits supplied
1334 if (hi2>0xFFFFF) {
1335 DbpString("Tags can only have 84 bits.");
1336 return;
1337 }
1338 // Build the 6 data blocks for supplied 84bit ID
1339 last_block = 6;
1340 data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded)
1341 for (int i=0;i<4;i++) {
1342 if (hi2 & (1<<(19-i)))
1343 data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10
1344 else
1345 data1 |= (1<<((3-i)*2)); // 0 -> 01
1346 }
1347
1348 data2 = 0;
1349 for (int i=0;i<16;i++) {
1350 if (hi2 & (1<<(15-i)))
1351 data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10
1352 else
1353 data2 |= (1<<((15-i)*2)); // 0 -> 01
1354 }
1355
1356 data3 = 0;
1357 for (int i=0;i<16;i++) {
1358 if (hi & (1<<(31-i)))
1359 data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
1360 else
1361 data3 |= (1<<((15-i)*2)); // 0 -> 01
1362 }
1363
1364 data4 = 0;
1365 for (int i=0;i<16;i++) {
1366 if (hi & (1<<(15-i)))
1367 data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10
1368 else
1369 data4 |= (1<<((15-i)*2)); // 0 -> 01
1370 }
1371
1372 data5 = 0;
1373 for (int i=0;i<16;i++) {
1374 if (lo & (1<<(31-i)))
1375 data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10
1376 else
1377 data5 |= (1<<((15-i)*2)); // 0 -> 01
1378 }
1379
1380 data6 = 0;
1381 for (int i=0;i<16;i++) {
1382 if (lo & (1<<(15-i)))
1383 data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10
1384 else
1385 data6 |= (1<<((15-i)*2)); // 0 -> 01
1386 }
1387 }
1388 else {
1389 // Ensure no more than 44 bits supplied
1390 if (hi>0xFFF) {
1391 DbpString("Tags can only have 44 bits.");
1392 return;
1393 }
1394
1395 // Build the 3 data blocks for supplied 44bit ID
1396 last_block = 3;
1397
1398 data1 = 0x1D000000; // load preamble
1399
1400 for (int i=0;i<12;i++) {
1401 if (hi & (1<<(11-i)))
1402 data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10
1403 else
1404 data1 |= (1<<((11-i)*2)); // 0 -> 01
1405 }
1406
1407 data2 = 0;
1408 for (int i=0;i<16;i++) {
1409 if (lo & (1<<(31-i)))
1410 data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10
1411 else
1412 data2 |= (1<<((15-i)*2)); // 0 -> 01
1413 }
1414
1415 data3 = 0;
1416 for (int i=0;i<16;i++) {
1417 if (lo & (1<<(15-i)))
1418 data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
1419 else
1420 data3 |= (1<<((15-i)*2)); // 0 -> 01
1421 }
1422 }
1423
1424 LED_D_ON();
1425 // Program the data blocks for supplied ID
ec09b62d 1426 // and the block 0 for HID format
54a942b0 1427 T55xxWriteBlock(data1,1,0,0);
1428 T55xxWriteBlock(data2,2,0,0);
1429 T55xxWriteBlock(data3,3,0,0);
1430
1431 if (longFMT) { // if long format there are 6 blocks
1432 T55xxWriteBlock(data4,4,0,0);
1433 T55xxWriteBlock(data5,5,0,0);
1434 T55xxWriteBlock(data6,6,0,0);
1435 }
1436
1437 // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long)
2414f978 1438 T55xxWriteBlock(T55x7_BITRATE_RF_50 |
54a942b0 1439 T55x7_MODULATION_FSK2a |
1440 last_block << T55x7_MAXBLOCK_SHIFT,
1441 0,0,0);
1442
1443 LED_D_OFF();
1444
ec09b62d 1445 DbpString("DONE!");
2d4eae76 1446}
ec09b62d 1447
a1f3bb12 1448void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT)
1449{
1450 int data1=0, data2=0; //up to six blocks for long format
1451
1452 data1 = hi; // load preamble
1453 data2 = lo;
1454
1455 LED_D_ON();
1456 // Program the data blocks for supplied ID
1457 // and the block 0 for HID format
1458 T55xxWriteBlock(data1,1,0,0);
1459 T55xxWriteBlock(data2,2,0,0);
1460
1461 //Config Block
1462 T55xxWriteBlock(0x00147040,0,0,0);
1463 LED_D_OFF();
1464
1465 DbpString("DONE!");
1466}
1467
2d4eae76 1468// Define 9bit header for EM410x tags
1469#define EM410X_HEADER 0x1FF
1470#define EM410X_ID_LENGTH 40
ec09b62d 1471
2d4eae76 1472void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo)
1473{
1474 int i, id_bit;
1475 uint64_t id = EM410X_HEADER;
1476 uint64_t rev_id = 0; // reversed ID
1477 int c_parity[4]; // column parity
1478 int r_parity = 0; // row parity
e67b06b7 1479 uint32_t clock = 0;
2d4eae76 1480
1481 // Reverse ID bits given as parameter (for simpler operations)
1482 for (i = 0; i < EM410X_ID_LENGTH; ++i) {
1483 if (i < 32) {
1484 rev_id = (rev_id << 1) | (id_lo & 1);
1485 id_lo >>= 1;
1486 } else {
1487 rev_id = (rev_id << 1) | (id_hi & 1);
1488 id_hi >>= 1;
1489 }
1490 }
1491
1492 for (i = 0; i < EM410X_ID_LENGTH; ++i) {
1493 id_bit = rev_id & 1;
1494
1495 if (i % 4 == 0) {
1496 // Don't write row parity bit at start of parsing
1497 if (i)
1498 id = (id << 1) | r_parity;
1499 // Start counting parity for new row
1500 r_parity = id_bit;
1501 } else {
1502 // Count row parity
1503 r_parity ^= id_bit;
1504 }
1505
1506 // First elements in column?
1507 if (i < 4)
1508 // Fill out first elements
1509 c_parity[i] = id_bit;
1510 else
1511 // Count column parity
1512 c_parity[i % 4] ^= id_bit;
1513
1514 // Insert ID bit
1515 id = (id << 1) | id_bit;
1516 rev_id >>= 1;
1517 }
1518
1519 // Insert parity bit of last row
1520 id = (id << 1) | r_parity;
1521
1522 // Fill out column parity at the end of tag
1523 for (i = 0; i < 4; ++i)
1524 id = (id << 1) | c_parity[i];
1525
1526 // Add stop bit
1527 id <<= 1;
1528
1529 Dbprintf("Started writing %s tag ...", card ? "T55x7":"T5555");
1530 LED_D_ON();
1531
1532 // Write EM410x ID
54a942b0 1533 T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0);
1534 T55xxWriteBlock((uint32_t)id, 2, 0, 0);
2d4eae76 1535
1536 // Config for EM410x (RF/64, Manchester, Maxblock=2)
e67b06b7 1537 if (card) {
1538 // Clock rate is stored in bits 8-15 of the card value
1539 clock = (card & 0xFF00) >> 8;
1540 Dbprintf("Clock rate: %d", clock);
1541 switch (clock)
1542 {
1543 case 32:
1544 clock = T55x7_BITRATE_RF_32;
1545 break;
1546 case 16:
1547 clock = T55x7_BITRATE_RF_16;
1548 break;
1549 case 0:
1550 // A value of 0 is assumed to be 64 for backwards-compatibility
1551 // Fall through...
1552 case 64:
1553 clock = T55x7_BITRATE_RF_64;
1554 break;
1555 default:
1556 Dbprintf("Invalid clock rate: %d", clock);
1557 return;
1558 }
1559
2d4eae76 1560 // Writing configuration for T55x7 tag
e67b06b7 1561 T55xxWriteBlock(clock |
2d4eae76 1562 T55x7_MODULATION_MANCHESTER |
1563 2 << T55x7_MAXBLOCK_SHIFT,
54a942b0 1564 0, 0, 0);
e67b06b7 1565 }
2d4eae76 1566 else
1567 // Writing configuration for T5555(Q5) tag
1568 T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT |
1569 T5555_MODULATION_MANCHESTER |
1570 2 << T5555_MAXBLOCK_SHIFT,
54a942b0 1571 0, 0, 0);
2d4eae76 1572
1573 LED_D_OFF();
1574 Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555",
1575 (uint32_t)(id >> 32), (uint32_t)id);
1576}
2414f978 1577
1578// Clone Indala 64-bit tag by UID to T55x7
1579void CopyIndala64toT55x7(int hi, int lo)
1580{
1581
1582 //Program the 2 data blocks for supplied 64bit UID
1583 // and the block 0 for Indala64 format
54a942b0 1584 T55xxWriteBlock(hi,1,0,0);
1585 T55xxWriteBlock(lo,2,0,0);
2414f978 1586 //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2)
1587 T55xxWriteBlock(T55x7_BITRATE_RF_32 |
1588 T55x7_MODULATION_PSK1 |
1589 2 << T55x7_MAXBLOCK_SHIFT,
54a942b0 1590 0, 0, 0);
2414f978 1591 //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
1592// T5567WriteBlock(0x603E1042,0);
1593
1594 DbpString("DONE!");
1595
1596}
1597
1598void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7)
1599{
1600
1601 //Program the 7 data blocks for supplied 224bit UID
1602 // and the block 0 for Indala224 format
54a942b0 1603 T55xxWriteBlock(uid1,1,0,0);
1604 T55xxWriteBlock(uid2,2,0,0);
1605 T55xxWriteBlock(uid3,3,0,0);
1606 T55xxWriteBlock(uid4,4,0,0);
1607 T55xxWriteBlock(uid5,5,0,0);
1608 T55xxWriteBlock(uid6,6,0,0);
1609 T55xxWriteBlock(uid7,7,0,0);
2414f978 1610 //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7)
1611 T55xxWriteBlock(T55x7_BITRATE_RF_32 |
1612 T55x7_MODULATION_PSK1 |
1613 7 << T55x7_MAXBLOCK_SHIFT,
54a942b0 1614 0,0,0);
2414f978 1615 //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data)
1616// T5567WriteBlock(0x603E10E2,0);
1617
1618 DbpString("DONE!");
1619
1620}
54a942b0 1621
1622
1623#define abs(x) ( ((x)<0) ? -(x) : (x) )
1624#define max(x,y) ( x<y ? y:x)
1625
1626int DemodPCF7931(uint8_t **outBlocks) {
1627 uint8_t BitStream[256];
1628 uint8_t Blocks[8][16];
1629 uint8_t *GraphBuffer = (uint8_t *)BigBuf;
1630 int GraphTraceLen = sizeof(BigBuf);
1631 int i, j, lastval, bitidx, half_switch;
1632 int clock = 64;
1633 int tolerance = clock / 8;
1634 int pmc, block_done;
1635 int lc, warnings = 0;
1636 int num_blocks = 0;
1637 int lmin=128, lmax=128;
1638 uint8_t dir;
1639
1640 AcquireRawAdcSamples125k(0);
1641
1642 lmin = 64;
1643 lmax = 192;
1644
1645 i = 2;
1646
1647 /* Find first local max/min */
1648 if(GraphBuffer[1] > GraphBuffer[0]) {
1649 while(i < GraphTraceLen) {
1650 if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax)
1651 break;
1652 i++;
1653 }
1654 dir = 0;
1655 }
1656 else {
1657 while(i < GraphTraceLen) {
1658 if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin)
1659 break;
1660 i++;
1661 }
1662 dir = 1;
1663 }
1664
1665 lastval = i++;
1666 half_switch = 0;
1667 pmc = 0;
1668 block_done = 0;
1669
1670 for (bitidx = 0; i < GraphTraceLen; i++)
1671 {
1672 if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin))
1673 {
1674 lc = i - lastval;
1675 lastval = i;
1676
1677 // Switch depending on lc length:
1678 // Tolerance is 1/8 of clock rate (arbitrary)
1679 if (abs(lc-clock/4) < tolerance) {
1680 // 16T0
1681 if((i - pmc) == lc) { /* 16T0 was previous one */
1682 /* It's a PMC ! */
1683 i += (128+127+16+32+33+16)-1;
1684 lastval = i;
1685 pmc = 0;
1686 block_done = 1;
1687 }
1688 else {
1689 pmc = i;
1690 }
1691 } else if (abs(lc-clock/2) < tolerance) {
1692 // 32TO
1693 if((i - pmc) == lc) { /* 16T0 was previous one */
1694 /* It's a PMC ! */
1695 i += (128+127+16+32+33)-1;
1696 lastval = i;
1697 pmc = 0;
1698 block_done = 1;
1699 }
1700 else if(half_switch == 1) {
1701 BitStream[bitidx++] = 0;
1702 half_switch = 0;
1703 }
1704 else
1705 half_switch++;
1706 } else if (abs(lc-clock) < tolerance) {
1707 // 64TO
1708 BitStream[bitidx++] = 1;
1709 } else {
1710 // Error
1711 warnings++;
1712 if (warnings > 10)
1713 {
1714 Dbprintf("Error: too many detection errors, aborting.");
1715 return 0;
1716 }
1717 }
1718
1719 if(block_done == 1) {
1720 if(bitidx == 128) {
1721 for(j=0; j<16; j++) {
1722 Blocks[num_blocks][j] = 128*BitStream[j*8+7]+
1723 64*BitStream[j*8+6]+
1724 32*BitStream[j*8+5]+
1725 16*BitStream[j*8+4]+
1726 8*BitStream[j*8+3]+
1727 4*BitStream[j*8+2]+
1728 2*BitStream[j*8+1]+
1729 BitStream[j*8];
1730 }
1731 num_blocks++;
1732 }
1733 bitidx = 0;
1734 block_done = 0;
1735 half_switch = 0;
1736 }
1737 if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0;
1738 else dir = 1;
1739 }
1740 if(bitidx==255)
1741 bitidx=0;
1742 warnings = 0;
1743 if(num_blocks == 4) break;
1744 }
1745 memcpy(outBlocks, Blocks, 16*num_blocks);
1746 return num_blocks;
1747}
1748
1749int IsBlock0PCF7931(uint8_t *Block) {
1750 // Assume RFU means 0 :)
1751 if((memcmp(Block, "\x00\x00\x00\x00\x00\x00\x00\x01", 8) == 0) && memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) // PAC enabled
1752 return 1;
1753 if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ?
1754 return 1;
1755 return 0;
1756}
1757
1758int IsBlock1PCF7931(uint8_t *Block) {
1759 // Assume RFU means 0 :)
1760 if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0)
1761 if((Block[14] & 0x7f) <= 9 && Block[15] <= 9)
1762 return 1;
1763
1764 return 0;
1765}
1766
1767#define ALLOC 16
1768
1769void ReadPCF7931() {
1770 uint8_t Blocks[8][17];
1771 uint8_t tmpBlocks[4][16];
1772 int i, j, ind, ind2, n;
1773 int num_blocks = 0;
1774 int max_blocks = 8;
1775 int ident = 0;
1776 int error = 0;
1777 int tries = 0;
1778
1779 memset(Blocks, 0, 8*17*sizeof(uint8_t));
1780
1781 do {
1782 memset(tmpBlocks, 0, 4*16*sizeof(uint8_t));
1783 n = DemodPCF7931((uint8_t**)tmpBlocks);
1784 if(!n)
1785 error++;
1786 if(error==10 && num_blocks == 0) {
1787 Dbprintf("Error, no tag or bad tag");
1788 return;
1789 }
1790 else if (tries==20 || error==10) {
1791 Dbprintf("Error reading the tag");
1792 Dbprintf("Here is the partial content");
1793 goto end;
1794 }
1795
1796 for(i=0; i<n; i++)
1797 Dbprintf("(dbg) %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
1798 tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
1799 tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
1800 if(!ident) {
1801 for(i=0; i<n; i++) {
1802 if(IsBlock0PCF7931(tmpBlocks[i])) {
1803 // Found block 0 ?
1804 if(i < n-1 && IsBlock1PCF7931(tmpBlocks[i+1])) {
1805 // Found block 1!
1806 // \o/
1807 ident = 1;
1808 memcpy(Blocks[0], tmpBlocks[i], 16);
1809 Blocks[0][ALLOC] = 1;
1810 memcpy(Blocks[1], tmpBlocks[i+1], 16);
1811 Blocks[1][ALLOC] = 1;
1812 max_blocks = max((Blocks[1][14] & 0x7f), Blocks[1][15]) + 1;
1813 // Debug print
1814 Dbprintf("(dbg) Max blocks: %d", max_blocks);
1815 num_blocks = 2;
1816 // Handle following blocks
1817 for(j=i+2, ind2=2; j!=i; j++, ind2++, num_blocks++) {
1818 if(j==n) j=0;
1819 if(j==i) break;
1820 memcpy(Blocks[ind2], tmpBlocks[j], 16);
1821 Blocks[ind2][ALLOC] = 1;
1822 }
1823 break;
1824 }
1825 }
1826 }
1827 }
1828 else {
1829 for(i=0; i<n; i++) { // Look for identical block in known blocks
1830 if(memcmp(tmpBlocks[i], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16)) { // Block is not full of 00
1831 for(j=0; j<max_blocks; j++) {
1832 if(Blocks[j][ALLOC] == 1 && !memcmp(tmpBlocks[i], Blocks[j], 16)) {
1833 // Found an identical block
1834 for(ind=i-1,ind2=j-1; ind >= 0; ind--,ind2--) {
1835 if(ind2 < 0)
1836 ind2 = max_blocks;
1837 if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
1838 // Dbprintf("Tmp %d -> Block %d", ind, ind2);
1839 memcpy(Blocks[ind2], tmpBlocks[ind], 16);
1840 Blocks[ind2][ALLOC] = 1;
1841 num_blocks++;
1842 if(num_blocks == max_blocks) goto end;
1843 }
1844 }
1845 for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) {
1846 if(ind2 > max_blocks)
1847 ind2 = 0;
1848 if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
1849 // Dbprintf("Tmp %d -> Block %d", ind, ind2);
1850 memcpy(Blocks[ind2], tmpBlocks[ind], 16);
1851 Blocks[ind2][ALLOC] = 1;
1852 num_blocks++;
1853 if(num_blocks == max_blocks) goto end;
1854 }
1855 }
1856 }
1857 }
1858 }
1859 }
1860 }
1861 tries++;
1862 if (BUTTON_PRESS()) return;
1863 } while (num_blocks != max_blocks);
1864end:
1865 Dbprintf("-----------------------------------------");
1866 Dbprintf("Memory content:");
1867 Dbprintf("-----------------------------------------");
1868 for(i=0; i<max_blocks; i++) {
1869 if(Blocks[i][ALLOC]==1)
1870 Dbprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
1871 Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
1872 Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
1873 else
1874 Dbprintf("<missing block %d>", i);
1875 }
1876 Dbprintf("-----------------------------------------");
1877
1878 return ;
1879}
1880
1881
1882//-----------------------------------
1883// EM4469 / EM4305 routines
1884//-----------------------------------
1885#define FWD_CMD_LOGIN 0xC //including the even parity, binary mirrored
1886#define FWD_CMD_WRITE 0xA
1887#define FWD_CMD_READ 0x9
1888#define FWD_CMD_DISABLE 0x5
1889
1890
1891uint8_t forwardLink_data[64]; //array of forwarded bits
1892uint8_t * forward_ptr; //ptr for forward message preparation
1893uint8_t fwd_bit_sz; //forwardlink bit counter
1894uint8_t * fwd_write_ptr; //forwardlink bit pointer
1895
1896//====================================================================
1897// prepares command bits
1898// see EM4469 spec
1899//====================================================================
1900//--------------------------------------------------------------------
1901uint8_t Prepare_Cmd( uint8_t cmd ) {
1902 //--------------------------------------------------------------------
1903
1904 *forward_ptr++ = 0; //start bit
1905 *forward_ptr++ = 0; //second pause for 4050 code
1906
1907 *forward_ptr++ = cmd;
1908 cmd >>= 1;
1909 *forward_ptr++ = cmd;
1910 cmd >>= 1;
1911 *forward_ptr++ = cmd;
1912 cmd >>= 1;
1913 *forward_ptr++ = cmd;
1914
1915 return 6; //return number of emited bits
1916}
1917
1918//====================================================================
1919// prepares address bits
1920// see EM4469 spec
1921//====================================================================
1922
1923//--------------------------------------------------------------------
1924uint8_t Prepare_Addr( uint8_t addr ) {
1925 //--------------------------------------------------------------------
1926
1927 register uint8_t line_parity;
1928
1929 uint8_t i;
1930 line_parity = 0;
1931 for(i=0;i<6;i++) {
1932 *forward_ptr++ = addr;
1933 line_parity ^= addr;
1934 addr >>= 1;
1935 }
1936
1937 *forward_ptr++ = (line_parity & 1);
1938
1939 return 7; //return number of emited bits
1940}
1941
1942//====================================================================
1943// prepares data bits intreleaved with parity bits
1944// see EM4469 spec
1945//====================================================================
1946
1947//--------------------------------------------------------------------
1948uint8_t Prepare_Data( uint16_t data_low, uint16_t data_hi) {
1949 //--------------------------------------------------------------------
1950
1951 register uint8_t line_parity;
1952 register uint8_t column_parity;
1953 register uint8_t i, j;
1954 register uint16_t data;
1955
1956 data = data_low;
1957 column_parity = 0;
1958
1959 for(i=0; i<4; i++) {
1960 line_parity = 0;
1961 for(j=0; j<8; j++) {
1962 line_parity ^= data;
1963 column_parity ^= (data & 1) << j;
1964 *forward_ptr++ = data;
1965 data >>= 1;
1966 }
1967 *forward_ptr++ = line_parity;
1968 if(i == 1)
1969 data = data_hi;
1970 }
1971
1972 for(j=0; j<8; j++) {
1973 *forward_ptr++ = column_parity;
1974 column_parity >>= 1;
1975 }
1976 *forward_ptr = 0;
1977
1978 return 45; //return number of emited bits
1979}
1980
1981//====================================================================
1982// Forward Link send function
1983// Requires: forwarLink_data filled with valid bits (1 bit per byte)
1984// fwd_bit_count set with number of bits to be sent
1985//====================================================================
1986void SendForward(uint8_t fwd_bit_count) {
1987
1988 fwd_write_ptr = forwardLink_data;
1989 fwd_bit_sz = fwd_bit_count;
1990
1991 LED_D_ON();
1992
1993 //Field on
7cc204bf 1994 FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
54a942b0 1995 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 1996 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
54a942b0 1997
1998 // Give it a bit of time for the resonant antenna to settle.
1999 // And for the tag to fully power up
2000 SpinDelay(150);
2001
2002 // force 1st mod pulse (start gap must be longer for 4305)
2003 fwd_bit_sz--; //prepare next bit modulation
2004 fwd_write_ptr++;
2005 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
2006 SpinDelayUs(55*8); //55 cycles off (8us each)for 4305
2007 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 2008 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
54a942b0 2009 SpinDelayUs(16*8); //16 cycles on (8us each)
2010
2011 // now start writting
2012 while(fwd_bit_sz-- > 0) { //prepare next bit modulation
2013 if(((*fwd_write_ptr++) & 1) == 1)
2014 SpinDelayUs(32*8); //32 cycles at 125Khz (8us each)
2015 else {
2016 //These timings work for 4469/4269/4305 (with the 55*8 above)
2017 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
2018 SpinDelayUs(23*8); //16-4 cycles off (8us each)
2019 FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
b014c96d 2020 FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
54a942b0 2021 SpinDelayUs(9*8); //16 cycles on (8us each)
2022 }
2023 }
2024}
2025
2026void EM4xLogin(uint32_t Password) {
2027
2028 uint8_t fwd_bit_count;
2029
2030 forward_ptr = forwardLink_data;
2031 fwd_bit_count = Prepare_Cmd( FWD_CMD_LOGIN );
2032 fwd_bit_count += Prepare_Data( Password&0xFFFF, Password>>16 );
2033
2034 SendForward(fwd_bit_count);
2035
2036 //Wait for command to complete
2037 SpinDelay(20);
2038
2039}
2040
2041void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
2042
2043 uint8_t fwd_bit_count;
2044 uint8_t *dest = (uint8_t *)BigBuf;
2045 int m=0, i=0;
2046
2047 //If password mode do login
2048 if (PwdMode == 1) EM4xLogin(Pwd);
2049
2050 forward_ptr = forwardLink_data;
2051 fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
2052 fwd_bit_count += Prepare_Addr( Address );
2053
2054 m = sizeof(BigBuf);
2055 // Clear destination buffer before sending the command
2056 memset(dest, 128, m);
2057 // Connect the A/D to the peak-detected low-frequency path.
2058 SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
2059 // Now set up the SSC to get the ADC samples that are now streaming at us.
2060 FpgaSetupSsc();
2061
2062 SendForward(fwd_bit_count);
2063
2064 // Now do the acquisition
2065 i = 0;
2066 for(;;) {
2067 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
2068 AT91C_BASE_SSC->SSC_THR = 0x43;
2069 }
2070 if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
2071 dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
2072 i++;
2073 if (i >= m) break;
2074 }
2075 }
2076 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
2077 LED_D_OFF();
2078}
2079
2080void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
2081
2082 uint8_t fwd_bit_count;
2083
2084 //If password mode do login
2085 if (PwdMode == 1) EM4xLogin(Pwd);
2086
2087 forward_ptr = forwardLink_data;
2088 fwd_bit_count = Prepare_Cmd( FWD_CMD_WRITE );
2089 fwd_bit_count += Prepare_Addr( Address );
2090 fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 );
2091
2092 SendForward(fwd_bit_count);
2093
2094 //Wait for write to complete
2095 SpinDelay(20);
2096 FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
2097 LED_D_OFF();
2098}
Impressum, Datenschutz