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