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