crc = update_crc16(crc, (shift1>>16)&0xff);
crc = update_crc16(crc, (shift1>>24)&0xff);
- Dbprintf("Info: Tag data: %x%08x, crc=%x",
- (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF);
+ Dbprintf("Info: Tag data: %x%08x, crc=%x", (unsigned int)shift1, (unsigned int)shift0, (unsigned int)shift2 & 0xFFFF);
if (crc != (shift2&0xffff)) {
Dbprintf("Error: CRC mismatch, expected %x", (unsigned int)crc);
} else {
// start by writing 0xBB (keyword) and 0xEB (password)
// then write 80 bits of data (or 64 bit data + 16 bit crc if you prefer)
// finally end with 0x0300 (write frame)
- // all data is sent lsb firts
+ // all data is sent lsb first
// finish with 15ms programming time
// modulate antenna
for(;;) {
//wait until SSC_CLK goes HIGH
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
- if(BUTTON_PRESS() || (usb_poll_validate_length() )) {
+ if(BUTTON_PRESS() || !usb_poll_validate_length() ) {
DbpString("Stopped");
return;
}
//wait until SSC_CLK goes LOW
while(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK) {
- if(BUTTON_PRESS()) {
+ if( BUTTON_PRESS() || !usb_poll_validate_length() ) {
DbpString("Stopped");
return;
}
}
}
Dbprintf("Simulating with fcHigh: %d, fcLow: %d, clk: %d, invert: %d, n: %d",fcHigh, fcLow, clk, invert, n);
- /*Dbprintf("DEBUG: First 32:");
- uint8_t *dest = BigBuf_get_addr();
- i=0;
- Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
- i+=16;
- Dbprintf("%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d", dest[i],dest[i+1],dest[i+2],dest[i+3],dest[i+4],dest[i+5],dest[i+6],dest[i+7],dest[i+8],dest[i+9],dest[i+10],dest[i+11],dest[i+12],dest[i+13],dest[i+14],dest[i+15]);
- */
- if (ledcontrol)
- LED_A_ON();
+ if (ledcontrol) LED_A_ON();
SimulateTagLowFrequency(n, 0, ledcontrol);
-
- if (ledcontrol)
- LED_A_OFF();
+ if (ledcontrol) LED_A_OFF();
}
// compose ask waveform for one bit(ASK)
size = 50*128*2; //big enough to catch 2 sequences of largest format
idx = AWIDdemodFSK(dest, &size);
- if (idx>0 && size==96){
+ if (idx<=0 || size!=96) continue;
// Index map
// 0 10 20 30 40 50 60
// | | | | | | |
uint32_t rawHi2 = bytebits_to_byte(dest+idx,32);
size = removeParity(dest, idx+8, 4, 1, 88);
+ if (size != 66) continue;
// ok valid card found!
// Index map
return;
}
// reset
- }
idx = 0;
WDT_HIT();
}
}
/*------------------------------
- * T5555/T5557/T5567 routines
+ * T5555/T5557/T5567/T5577 routines
*------------------------------
* NOTE: T55x7/T5555 configuration register definitions moved to protocols.h
*
* Q5 tags seems to have issues when these values changes.
*/
-#define START_GAP 50*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
+#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc)
-#define WRITE_0 16*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
+#define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
#define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550
-#define READ_GAP 52*8
+#define READ_GAP 15*8
// VALUES TAKEN FROM EM4x function: SendForward
// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle)
SpinDelayUs(WRITE_GAP);
}
+// Send T5577 reset command then read stream (see if we can identify the start of the stream)
+void T55xxResetRead(void) {
+ LED_A_ON();
+ //clear buffer now so it does not interfere with timing later
+ BigBuf_Clear_ext(false);
+
+ // Set up FPGA, 125kHz
+ LFSetupFPGAForADC(95, true);
+
+ // Trigger T55x7 in mode.
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+ SpinDelayUs(START_GAP);
+
+ // reset tag - op code 00
+ T55xxWriteBit(0);
+ T55xxWriteBit(0);
+
+ // Turn field on to read the response
+ TurnReadLFOn(READ_GAP);
+
+ // Acquisition
+ doT55x7Acquisition(BigBuf_max_traceLen());
+
+ // Turn the field off
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+ cmd_send(CMD_ACK,0,0,0,0,0);
+ LED_A_OFF();
+}
+
// Write one card block in page 0, no lock
-void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
+void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) {
LED_A_ON();
bool PwdMode = arg & 0x1;
uint8_t Page = (arg & 0x2)>>1;
// turn field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
- cmd_send(CMD_ACK,0,0,0,0,0);
LED_A_OFF();
}
-// Read one card block in page 0
+// Write one card block in page 0, no lock
+void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) {
+ T55xxWriteBlockExt(Data, Block, Pwd, arg);
+ cmd_send(CMD_ACK,0,0,0,0,0);
+}
+
+// Read one card block in page [page]
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
LED_A_ON();
bool PwdMode = arg0 & 0x1;
TurnReadLFOn(READ_GAP);
// Acquisition
- doT55x7Acquisition();
+ doT55x7Acquisition(12000);
// Turn the field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
// write last block first and config block last (if included)
- for (uint8_t i = numblocks; i > startblock; i--)
- T55xxWriteBlock(blockdata[i-1],i-1,0,0);
+ for (uint8_t i = numblocks+startblock; i > startblock; i--)
+ T55xxWriteBlockExt(blockdata[i-1], i-1, 0, 0);
}
// Copy HID id to card and setup block 0 config
void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) {
uint32_t data[] = {0,0,0,0,0,0,0};
- //int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format
uint8_t last_block = 0;
if (longFMT){
// Build the 6 data blocks for supplied 84bit ID
last_block = 6;
// load preamble (1D) & long format identifier (9E manchester encoded)
- data[1] = 0x1D96A900 | manchesterEncode2Bytes((hi2 >> 16) & 0xF);
+ data[1] = 0x1D96A900 | (manchesterEncode2Bytes((hi2 >> 16) & 0xF) & 0xFF);
// load raw id from hi2, hi, lo to data blocks (manchester encoded)
data[2] = manchesterEncode2Bytes(hi2 & 0xFFFF);
data[3] = manchesterEncode2Bytes(hi >> 16);
// Build the 3 data blocks for supplied 44bit ID
last_block = 3;
// load preamble
- data[1] = 0x1D000000 | manchesterEncode2Bytes(hi & 0xFFF);
+ data[1] = 0x1D000000 | (manchesterEncode2Bytes(hi) & 0xFFFFFF);
data[2] = manchesterEncode2Bytes(lo >> 16);
data[3] = manchesterEncode2Bytes(lo & 0xFFFF);
}
// load chip config block
data[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2a | last_block << T55x7_MAXBLOCK_SHIFT;
+ //TODO add selection of chip for Q5 or T55x7
+ // data[0] = (((50-2)/2)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | last_block << T5555_MAXBLOCK_SHIFT;
+
LED_D_ON();
// Program the data blocks for supplied ID
// and the block 0 for HID format
DbpString("DONE!");
}
-void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT)
-{
+void CopyIOtoT55x7(uint32_t hi, uint32_t lo) {
uint32_t data[] = {T55x7_BITRATE_RF_64 | T55x7_MODULATION_FSK2a | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo};
+ //TODO add selection of chip for Q5 or T55x7
+ // data[0] = (((64-2)/2)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 2 << T5555_MAXBLOCK_SHIFT;
LED_D_ON();
// Program the data blocks for supplied ID
//Program the 2 data blocks for supplied 64bit UID
// and the Config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2)
uint32_t data[] = { T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo};
+ //TODO add selection of chip for Q5 or T55x7
+ // data[0] = (((32-2)/2)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT;
+
WriteT55xx(data, 0, 3);
//Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
// T5567WriteBlock(0x603E1042,0);
DbpString("DONE!");
}
// Clone Indala 224-bit tag by UID to T55x7
-void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7)
-{
+void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7) {
//Program the 7 data blocks for supplied 224bit UID
uint32_t data[] = {0, uid1, uid2, uid3, uid4, uid5, uid6, uid7};
// and the block 0 for Indala224 format
//Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7)
data[0] = T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (7 << T55x7_MAXBLOCK_SHIFT);
+ //TODO add selection of chip for Q5 or T55x7
+ // data[0] = (((32-2)/2)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_PSK1 | 7 << T5555_MAXBLOCK_SHIFT;
WriteT55xx(data, 0, 8);
//Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data)
// T5567WriteBlock(0x603E10E2,0);
DbpString("DONE!");
}
+// clone viking tag to T55xx
+void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5) {
+ uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2};
+ if (Q5) data[0] = (32 << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT;
+ // Program the data blocks for supplied ID and the block 0 config
+ WriteT55xx(data, 0, 3);
+ LED_D_OFF();
+ cmd_send(CMD_ACK,0,0,0,0,0);
+}
// Define 9bit header for EM410x tags
#define EM410X_HEADER 0x1FF
#define EM410X_ID_LENGTH 40
-void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo)
-{
+void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) {
int i, id_bit;
uint64_t id = EM410X_HEADER;
uint64_t rev_id = 0; // reversed ID
LED_D_ON();
// Write EM410x ID
- uint32_t data[] = {0, id>>32, id & 0xFFFF};
- if (card) {
- clock = (card & 0xFF00) >> 8;
- clock = (clock == 0) ? 64 : clock;
- Dbprintf("Clock rate: %d", clock);
+ uint32_t data[] = {0, (uint32_t)(id>>32), id & 0xFFFFFFFF};
+
+ clock = (card & 0xFF00) >> 8;
+ clock = (clock == 0) ? 64 : clock;
+ Dbprintf("Clock rate: %d", clock);
+ if (card & 0xFF) { //t55x7
clock = GetT55xxClockBit(clock);
if (clock == 0) {
Dbprintf("Invalid clock rate: %d", clock);
return;
}
-
data[0] = clock | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT);
- } else {
- data[0] = (0x1F << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
+ } else { //t5555 (Q5)
+ clock = (clock-2)>>1; //n = (RF-2)/2
+ data[0] = (clock << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
}
WriteT55xx(data, 0, 3);
LED_D_OFF();
- Dbprintf("Tag %s written with 0x%08x%08x\n", card ? "T55x7":"T5555",
- (uint32_t)(id >> 32), (uint32_t)id);
+ Dbprintf("Tag %s written with 0x%08x%08x\n",
+ card ? "T55x7":"T5555",
+ (uint32_t)(id >> 32),
+ (uint32_t)id);
}
//-----------------------------------
// prepares command bits
// see EM4469 spec
//====================================================================
+//--------------------------------------------------------------------
+// VALUES TAKEN FROM EM4x function: SendForward
+// START_GAP = 440; (55*8) cycles at 125Khz (8us = 1cycle)
+// WRITE_GAP = 128; (16*8)
+// WRITE_1 = 256 32*8; (32*8)
+
+// These timings work for 4469/4269/4305 (with the 55*8 above)
+// WRITE_0 = 23*8 , 9*8 SpinDelayUs(23*8);
+
uint8_t Prepare_Cmd( uint8_t cmd ) {
*forward_ptr++ = 0; //start bit
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
LED_D_OFF();
}
-
-void CopyViKingtoT55x7(uint32_t block1, uint32_t block2) {
- LED_D_ON();
- T55xxWriteBlock(block1,1,0,0);
- T55xxWriteBlock(block2,2,0,0);
- T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T55x7_MAXBLOCK_SHIFT,0,0,0);
- // T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T5555_MAXBLOCK_SHIFT,0,0,1);
- // ICEMAN NOTES:
- // Shouldn't this one be: T55x7_MAXBLOCK_SHIFT and 0 in password mode
- LED_D_OFF();
-}
-