uint8_t version=0;
uint8_t facilitycode=0;
uint16_t number=0;
+ uint8_t crc = 0;
+ uint16_t calccrc = 0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
//| | | | | | |
//01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
//-----------------------------------------------------------------------------
- //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
+ //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 checksum 11
//
+ //Checksum:
+ //00000000 0 11110000 1 11100000 1 00000001 1 00000011 1 10110110 1 01110101 11
+ //preamble F0 E0 01 03 B6 75
+ // How to calc checksum,
+ // http://www.proxmark.org/forum/viewtopic.php?id=364&p=6
+ // F0 + E0 + 01 + 03 + B6 = 28A
+ // 28A & FF = 8A
+ // FF - 8A = 75
+ // Checksum: 0x75
//XSF(version)facility:codeone+codetwo
//Handle the data
if(findone){ //only print binary if we are doing one
facilitycode = bytebits_to_byte(dest+idx+18,8) ;
number = (bytebits_to_byte(dest+idx+36,8)<<8)|(bytebits_to_byte(dest+idx+45,8)); //36,9
- Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
+ crc = bytebits_to_byte(dest+idx+54,8);
+ for (uint8_t i=1; i<6; ++i)
+ calccrc += bytebits_to_byte(dest+idx+9*i,8);
+ calccrc &= 0xff;
+ calccrc = 0xff - calccrc;
+
+ char *crcStr = (crc == calccrc) ? "ok":"!crc";
+
+ Dbprintf("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
// if we're only looking for one tag
if (findone){
if (ledcontrol) LED_A_OFF();
// These timings work for 4469/4269/4305 (with the 55*8 above)
// WRITE_0 = 23*8 , 9*8 SpinDelayUs(23*8);
+// Sam7s has several timers, we will use the source TIMER_CLOCK1 (aka AT91C_TC_CLKS_TIMER_DIV1_CLOCK)
+// TIMER_CLOCK1 = MCK/2, MCK is running at 48 MHz, Timer is running at 48/2 = 24 MHz
+// Hitag units (T0) have duration of 8 microseconds (us), which is 1/125000 per second (carrier)
+// T0 = TIMER_CLOCK1 / 125000 = 192
+// 1 Cycle = 8 microseconds(us)
+
#define T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
// Write one bit to card
// Write one card block in page 0, no lock
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
- uint32_t i = 0;
+ uint32_t i = 0;
- // Set up FPGA, 125kHz
- // Wait for config.. (192+8190xPOW)x8 == 67ms
- LFSetupFPGAForADC(0, true);
+ // Set up FPGA, 125kHz
+ // Wait for config.. (192+8190xPOW)x8 == 67ms
+ LFSetupFPGAForADC(0, true);
// Now start writting
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
+void TurnReadLFOn(){
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+ // Give it a bit of time for the resonant antenna to settle.
+ SpinDelayUs(8*150);
+}
+
+
// Read one card block in page 0
void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
{
uint32_t i = 0;
uint8_t *dest = BigBuf_get_addr();
uint16_t bufferlength = BigBuf_max_traceLen();
- if ( bufferlength > T55xx_SAMPLES_SIZE )
- bufferlength = T55xx_SAMPLES_SIZE;
+ if ( bufferlength > T55xx_SAMPLES_SIZE )
+ bufferlength = T55xx_SAMPLES_SIZE;
- memset(dest, 0x80, bufferlength);
-
- // Set up FPGA, 125kHz
- // Wait for config.. (192+8190xPOW)x8 == 67ms
- LFSetupFPGAForADC(0, true);
+ // Clear destination buffer before sending the command
+ memset(dest, 0x80, bufferlength);
+
+ // Set up FPGA, 125kHz
+ // Wait for config.. (192+8190xPOW)x8 == 67ms
+ LFSetupFPGAForADC(0, true);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
T55xxWriteBit(Block & i);
// Turn field on to read the response
- TurnReadLFOn();
-
+ TurnReadLFOn();
// Now do the acquisition
i = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
AT91C_BASE_SSC->SSC_THR = 0x43;
- LED_D_ON();
+ LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- ++i;
- LED_D_OFF();
- if (i >= bufferlength) break;
+ i++;
+ LED_D_OFF();
+ if (i >= bufferlength) break;
}
}
- cmd_send(CMD_ACK,0,0,0,0,0);
+ cmd_send(CMD_ACK,0,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
// Read card traceability data (page 1)
void T55xxReadTrace(void){
-
- uint32_t i = 0;
+
+ uint32_t i = 0;
uint8_t *dest = BigBuf_get_addr();
uint16_t bufferlength = BigBuf_max_traceLen();
- if ( bufferlength > T55xx_SAMPLES_SIZE )
- bufferlength = T55xx_SAMPLES_SIZE;
+ if ( bufferlength > T55xx_SAMPLES_SIZE )
+ bufferlength= T55xx_SAMPLES_SIZE;
- memset(dest, 0x80, bufferlength);
-
- LFSetupFPGAForADC(0, true);
+ // Clear destination buffer before sending the command
+ memset(dest, 0x80, bufferlength);
+
+ LFSetupFPGAForADC(0, true);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
T55xxWriteBit(1); //Page 1
// Turn field on to read the response
- TurnReadLFOn();
+ TurnReadLFOn();
// Now do the acquisition
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
AT91C_BASE_SSC->SSC_THR = 0x43;
- LED_D_ON();
+ LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
- ++i;
- LED_D_OFF();
-
- if (i >= bufferlength) break;
+ i++;
+ LED_D_OFF();
+
+ if (i >= bufferlength) break;
}
}
cmd_send(CMD_ACK,0,0,0,0,0);
+ cmd_send(CMD_ACK,0,0,0,0,0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
int DemodPCF7931(uint8_t **outBlocks) {
- uint8_t BitStream[256] = {0x00};
- uint8_t Blocks[8][16];
+ uint8_t bits[256] = {0x00};
+ uint8_t blocks[8][16];
uint8_t *dest = BigBuf_get_addr();
- int GraphTraceLen = BigBuf_max_traceLen();
+
+ int GraphTraceLen = BigBuf_max_traceLen();
+ if ( GraphTraceLen > 18000 )
+ GraphTraceLen = 18000;
+
+
int i, j, lastval, bitidx, half_switch;
int clock = 64;
int tolerance = clock / 8;
block_done = 1;
}
else if(half_switch == 1) {
- BitStream[bitidx++] = 0;
+ bits[bitidx++] = 0;
half_switch = 0;
}
else
half_switch++;
} else if (abs(lc-clock) < tolerance) {
// 64TO
- BitStream[bitidx++] = 1;
+ bits[bitidx++] = 1;
} else {
// Error
warnings++;
if(block_done == 1) {
if(bitidx == 128) {
for(j=0; j<16; j++) {
- Blocks[num_blocks][j] = 128*BitStream[j*8+7]+
- 64*BitStream[j*8+6]+
- 32*BitStream[j*8+5]+
- 16*BitStream[j*8+4]+
- 8*BitStream[j*8+3]+
- 4*BitStream[j*8+2]+
- 2*BitStream[j*8+1]+
- BitStream[j*8];
+ blocks[num_blocks][j] = 128*bits[j*8+7]+
+ 64*bits[j*8+6]+
+ 32*bits[j*8+5]+
+ 16*bits[j*8+4]+
+ 8*bits[j*8+3]+
+ 4*bits[j*8+2]+
+ 2*bits[j*8+1]+
+ bits[j*8];
+
}
num_blocks++;
}
half_switch = 0;
}
if(i < GraphTraceLen)
- {
- if (dest[i-1] > dest[i]) dir=0;
- else dir = 1;
- }
+ dir =(dest[i-1] > dest[i]) ? 0 : 1;
}
if(bitidx==255)
bitidx=0;
warnings = 0;
if(num_blocks == 4) break;
}
- memcpy(outBlocks, Blocks, 16*num_blocks);
+ memcpy(outBlocks, blocks, 16*num_blocks);
return num_blocks;
}