#include "string.h"
#include "lfdemod.h"
#include "lfsampling.h"
-#include "usb_cdc.h"
-
+#include "usb_cdc.h" //test
/**
* Function to do a modulation and then get samples.
}
}
+
+
void WriteTIbyte(uint8_t b)
{
int i = 0;
}
}
+
+
+
// arguments: 64bit data split into 32bit idhi:idlo and optional 16bit crc
// if crc provided, it will be written with the data verbatim (even if bogus)
// if not provided a valid crc will be computed from the data and written.
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc)
{
+
+
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
if(crc == 0) {
crc = update_crc16(crc, (idlo)&0xff);
for(;;) {
//wait until SSC_CLK goes HIGH
while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
- if(BUTTON_PRESS() || usb_poll()) {
+ if(BUTTON_PRESS() || (usb_poll_validate_length() )) {
DbpString("Stopped");
return;
}
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
if (ledcontrol) LED_A_OFF();
}
+// loop to get raw HID waveform then FSK demodulate the TAG ID from it
+void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
+{
+ uint8_t *dest = BigBuf_get_addr();
+ //const size_t sizeOfBigBuff = BigBuf_max_traceLen();
+ size_t size;
+ int idx=0;
+ // Configure to go in 125Khz listen mode
+ LFSetupFPGAForADC(95, true);
+
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
+
+ WDT_HIT();
+ if (ledcontrol) LED_A_ON();
+
+ DoAcquisition_default(-1,true);
+ // FSK demodulator
+ //size = sizeOfBigBuff; //variable size will change after demod so re initialize it before use
+ size = 50*128*2; //big enough to catch 2 sequences of largest format
+ idx = AWIDdemodFSK(dest, &size);
+
+ if (idx>0 && size==96){
+ // Index map
+ // 0 10 20 30 40 50 60
+ // | | | | | | |
+ // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
+ // -----------------------------------------------------------------------------
+ // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
+ // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
+ // |---26 bit---| |-----117----||-------------142-------------|
+ // b = format bit len, o = odd parity of last 3 bits
+ // f = facility code, c = card number
+ // w = wiegand parity
+ // (26 bit format shown)
+
+ //get raw ID before removing parities
+ uint32_t rawLo = bytebits_to_byte(dest+idx+64,32);
+ uint32_t rawHi = bytebits_to_byte(dest+idx+32,32);
+ uint32_t rawHi2 = bytebits_to_byte(dest+idx,32);
+
+ size = removeParity(dest, idx+8, 4, 1, 88);
+ // ok valid card found!
+
+ // Index map
+ // 0 10 20 30 40 50 60
+ // | | | | | | |
+ // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
+ // -----------------------------------------------------------------------------
+ // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
+ // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ // |26 bit| |-117--| |-----142------|
+ // b = format bit len, o = odd parity of last 3 bits
+ // f = facility code, c = card number
+ // w = wiegand parity
+ // (26 bit format shown)
+
+ uint32_t fc = 0;
+ uint32_t cardnum = 0;
+ uint32_t code1 = 0;
+ uint32_t code2 = 0;
+ uint8_t fmtLen = bytebits_to_byte(dest,8);
+ if (fmtLen==26){
+ fc = bytebits_to_byte(dest+9, 8);
+ cardnum = bytebits_to_byte(dest+17, 16);
+ code1 = bytebits_to_byte(dest+8,fmtLen);
+ Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
+ } else {
+ cardnum = bytebits_to_byte(dest+8+(fmtLen-17), 16);
+ if (fmtLen>32){
+ code1 = bytebits_to_byte(dest+8,fmtLen-32);
+ code2 = bytebits_to_byte(dest+8+(fmtLen-32),32);
+ Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
+ } else{
+ code1 = bytebits_to_byte(dest+8,fmtLen);
+ Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
+ }
+ }
+ if (findone){
+ if (ledcontrol) LED_A_OFF();
+ return;
+ }
+ // reset
+ }
+ idx = 0;
+ WDT_HIT();
+ }
+ DbpString("Stopped");
+ if (ledcontrol) LED_A_OFF();
+}
+
void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr();
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
- while(!BUTTON_PRESS()) {
+ while(!BUTTON_PRESS() && !usb_poll_validate_length()) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1,true);
#define T55x7_MODULATION_FSK2a 0x00007000
#define T55x7_MODULATION_MANCHESTER 0x00008000
#define T55x7_MODULATION_BIPHASE 0x00010000
+#define T55x7_MODULATION_DIPHASE 0x00018000
#define T55x7_BITRATE_RF_8 0
#define T55x7_BITRATE_RF_16 0x00040000
#define T55x7_BITRATE_RF_32 0x00080000
#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 T55xx_SAMPLES_SIZE 12000 // 32 x 32 x 10 (32 bit times numofblock (7), times clock skip..)
-
+#define T55xx_READ_UPPER_THRESHOLD 128+40 // 50
+#define T55xx_READ_TOL 5
+//#define T55xx_READ_LOWER_THRESHOLD 128-40 //-50
// Write one bit to card
void T55xxWriteBit(int bit)
{
// Set up FPGA, 125kHz
// Wait for config.. (192+8190xPOW)x8 == 67ms
- LFSetupFPGAForADC(0, true);
+ LFSetupFPGAForADC(95, true);
// Now start writting
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);
+ SpinDelayUs(50*8); //155*8
}
uint16_t bufferlength = BigBuf_max_traceLen();
if ( bufferlength > T55xx_SAMPLES_SIZE )
bufferlength = T55xx_SAMPLES_SIZE;
-
+ Block &= 0x7; //make sure block is at max 7
// 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);
+
+ LFSetupFPGAForADC(95, true);
+ FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
+
+ // Connect the A/D to the peak-detected low-frequency path.
+ SetAdcMuxFor(GPIO_MUXSEL_LOPKD);
+
+ // Now set up the SSC to get the ADC samples that are now streaming at us.
+ FpgaSetupSsc();
+
+ // Give it a bit of time for the resonant antenna to settle.
+ //SpinDelayUs(8*200); //192FC
+ SpinDelay(50);
+
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
SpinDelayUs(START_GAP);
TurnReadLFOn();
// Now do the acquisition
i = 0;
+ bool startFound = false;
+ bool highFound = false;
+ uint8_t curSample = 0;
+ uint8_t firstSample = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
AT91C_BASE_SSC->SSC_THR = 0x43;
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;
+ curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+
+ // find first high sample
+ if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) {
+ if (curSample > firstSample) firstSample = curSample;
+ highFound = true;
+ } else if (!highFound) {
+ continue;
+ }
+
+ // skip until samples begin to change
+ if (startFound || curSample < firstSample-T55xx_READ_TOL){
+ if (!startFound) dest[i++] = firstSample;
+ startFound = true;
+ dest[i++] = curSample;
+ LED_D_OFF();
+ if (i >= bufferlength) break;
+ }
}
}
TurnReadLFOn();
// Now do the acquisition
+ bool startFound = false;// false;
+ bool highFound = false;
+ uint8_t curSample = 0;
+ uint8_t firstSample = 0;
for(;;) {
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
AT91C_BASE_SSC->SSC_THR = 0x43;
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();
+ curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+
+ // find first high sample
+ if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) {
+ if (curSample > firstSample) firstSample = curSample;
+ highFound = true;
+ } else if (!highFound) {
+ continue;
+ }
- if (i >= bufferlength) break;
+ // skip until samples begin to change
+ if (startFound || curSample < firstSample-T55xx_READ_TOL){
+ if (!startFound) dest[i++] = firstSample;
+ startFound = true;
+ dest[i++] = curSample;
+ LED_D_OFF();
+ if (i >= bufferlength) break;
+ }
}
}
}
-
-#define abs(x) ( ((x)<0) ? -(x) : (x) )
-#define max(x,y) ( x<y ? y:x)
-
-int DemodPCF7931(uint8_t **outBlocks) {
- uint8_t BitStream[256];
- uint8_t Blocks[8][16];
- uint8_t *GraphBuffer = BigBuf_get_addr();
- int GraphTraceLen = BigBuf_max_traceLen();
- int i, j, lastval, bitidx, half_switch;
- int clock = 64;
- int tolerance = clock / 8;
- int pmc, block_done;
- int lc, warnings = 0;
- int num_blocks = 0;
- int lmin=128, lmax=128;
- uint8_t dir;
-
- LFSetupFPGAForADC(95, true);
- DoAcquisition_default(0, 0);
-
-
- lmin = 64;
- lmax = 192;
-
- i = 2;
-
- /* Find first local max/min */
- if(GraphBuffer[1] > GraphBuffer[0]) {
- while(i < GraphTraceLen) {
- if( !(GraphBuffer[i] > GraphBuffer[i-1]) && GraphBuffer[i] > lmax)
- break;
- i++;
- }
- dir = 0;
- }
- else {
- while(i < GraphTraceLen) {
- if( !(GraphBuffer[i] < GraphBuffer[i-1]) && GraphBuffer[i] < lmin)
- break;
- i++;
- }
- dir = 1;
- }
-
- lastval = i++;
- half_switch = 0;
- pmc = 0;
- block_done = 0;
-
- for (bitidx = 0; i < GraphTraceLen; i++)
- {
- if ( (GraphBuffer[i-1] > GraphBuffer[i] && dir == 1 && GraphBuffer[i] > lmax) || (GraphBuffer[i-1] < GraphBuffer[i] && dir == 0 && GraphBuffer[i] < lmin))
- {
- lc = i - lastval;
- lastval = i;
-
- // Switch depending on lc length:
- // Tolerance is 1/8 of clock rate (arbitrary)
- if (abs(lc-clock/4) < tolerance) {
- // 16T0
- if((i - pmc) == lc) { /* 16T0 was previous one */
- /* It's a PMC ! */
- i += (128+127+16+32+33+16)-1;
- lastval = i;
- pmc = 0;
- block_done = 1;
- }
- else {
- pmc = i;
- }
- } else if (abs(lc-clock/2) < tolerance) {
- // 32TO
- if((i - pmc) == lc) { /* 16T0 was previous one */
- /* It's a PMC ! */
- i += (128+127+16+32+33)-1;
- lastval = i;
- pmc = 0;
- block_done = 1;
- }
- else if(half_switch == 1) {
- BitStream[bitidx++] = 0;
- half_switch = 0;
- }
- else
- half_switch++;
- } else if (abs(lc-clock) < tolerance) {
- // 64TO
- BitStream[bitidx++] = 1;
- } else {
- // Error
- warnings++;
- if (warnings > 10)
- {
- Dbprintf("Error: too many detection errors, aborting.");
- return 0;
- }
- }
-
- 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];
- }
- num_blocks++;
- }
- bitidx = 0;
- block_done = 0;
- half_switch = 0;
- }
- if(i < GraphTraceLen)
- {
- if (GraphBuffer[i-1] > GraphBuffer[i]) dir=0;
- else dir = 1;
- }
- }
- if(bitidx==255)
- bitidx=0;
- warnings = 0;
- if(num_blocks == 4) break;
- }
- memcpy(outBlocks, Blocks, 16*num_blocks);
- return num_blocks;
-}
-
-int IsBlock0PCF7931(uint8_t *Block) {
- // Assume RFU means 0 :)
- 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
- return 1;
- if((memcmp(Block+9, "\x00\x00\x00\x00\x00\x00\x00", 7) == 0) && Block[7] == 0) // PAC disabled, can it *really* happen ?
- return 1;
- return 0;
-}
-
-int IsBlock1PCF7931(uint8_t *Block) {
- // Assume RFU means 0 :)
- if(Block[10] == 0 && Block[11] == 0 && Block[12] == 0 && Block[13] == 0)
- if((Block[14] & 0x7f) <= 9 && Block[15] <= 9)
- return 1;
-
- return 0;
-}
-
-#define ALLOC 16
-
-void ReadPCF7931() {
- uint8_t Blocks[8][17];
- uint8_t tmpBlocks[4][16];
- int i, j, ind, ind2, n;
- int num_blocks = 0;
- int max_blocks = 8;
- int ident = 0;
- int error = 0;
- int tries = 0;
-
- memset(Blocks, 0, 8*17*sizeof(uint8_t));
-
- do {
- memset(tmpBlocks, 0, 4*16*sizeof(uint8_t));
- n = DemodPCF7931((uint8_t**)tmpBlocks);
- if(!n)
- error++;
- if(error==10 && num_blocks == 0) {
- Dbprintf("Error, no tag or bad tag");
- return;
- }
- else if (tries==20 || error==10) {
- Dbprintf("Error reading the tag");
- Dbprintf("Here is the partial content");
- goto end;
- }
-
- for(i=0; i<n; i++)
- Dbprintf("(dbg) %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
- tmpBlocks[i][0], tmpBlocks[i][1], tmpBlocks[i][2], tmpBlocks[i][3], tmpBlocks[i][4], tmpBlocks[i][5], tmpBlocks[i][6], tmpBlocks[i][7],
- tmpBlocks[i][8], tmpBlocks[i][9], tmpBlocks[i][10], tmpBlocks[i][11], tmpBlocks[i][12], tmpBlocks[i][13], tmpBlocks[i][14], tmpBlocks[i][15]);
- if(!ident) {
- for(i=0; i<n; i++) {
- if(IsBlock0PCF7931(tmpBlocks[i])) {
- // Found block 0 ?
- if(i < n-1 && IsBlock1PCF7931(tmpBlocks[i+1])) {
- // Found block 1!
- // \o/
- ident = 1;
- memcpy(Blocks[0], tmpBlocks[i], 16);
- Blocks[0][ALLOC] = 1;
- memcpy(Blocks[1], tmpBlocks[i+1], 16);
- Blocks[1][ALLOC] = 1;
- max_blocks = max((Blocks[1][14] & 0x7f), Blocks[1][15]) + 1;
- // Debug print
- Dbprintf("(dbg) Max blocks: %d", max_blocks);
- num_blocks = 2;
- // Handle following blocks
- for(j=i+2, ind2=2; j!=i; j++, ind2++, num_blocks++) {
- if(j==n) j=0;
- if(j==i) break;
- memcpy(Blocks[ind2], tmpBlocks[j], 16);
- Blocks[ind2][ALLOC] = 1;
- }
- break;
- }
- }
- }
- }
- else {
- for(i=0; i<n; i++) { // Look for identical block in known blocks
- 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
- for(j=0; j<max_blocks; j++) {
- if(Blocks[j][ALLOC] == 1 && !memcmp(tmpBlocks[i], Blocks[j], 16)) {
- // Found an identical block
- for(ind=i-1,ind2=j-1; ind >= 0; ind--,ind2--) {
- if(ind2 < 0)
- ind2 = max_blocks;
- if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
- // Dbprintf("Tmp %d -> Block %d", ind, ind2);
- memcpy(Blocks[ind2], tmpBlocks[ind], 16);
- Blocks[ind2][ALLOC] = 1;
- num_blocks++;
- if(num_blocks == max_blocks) goto end;
- }
- }
- for(ind=i+1,ind2=j+1; ind < n; ind++,ind2++) {
- if(ind2 > max_blocks)
- ind2 = 0;
- if(!Blocks[ind2][ALLOC]) { // Block ind2 not already found
- // Dbprintf("Tmp %d -> Block %d", ind, ind2);
- memcpy(Blocks[ind2], tmpBlocks[ind], 16);
- Blocks[ind2][ALLOC] = 1;
- num_blocks++;
- if(num_blocks == max_blocks) goto end;
- }
- }
- }
- }
- }
- }
- }
- tries++;
- if (BUTTON_PRESS()) return;
- } while (num_blocks != max_blocks);
- end:
- Dbprintf("-----------------------------------------");
- Dbprintf("Memory content:");
- Dbprintf("-----------------------------------------");
- for(i=0; i<max_blocks; i++) {
- if(Blocks[i][ALLOC]==1)
- Dbprintf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
- Blocks[i][0], Blocks[i][1], Blocks[i][2], Blocks[i][3], Blocks[i][4], Blocks[i][5], Blocks[i][6], Blocks[i][7],
- Blocks[i][8], Blocks[i][9], Blocks[i][10], Blocks[i][11], Blocks[i][12], Blocks[i][13], Blocks[i][14], Blocks[i][15]);
- else
- Dbprintf("<missing block %d>", i);
- }
- Dbprintf("-----------------------------------------");
-
- return ;
-}
-
-
//-----------------------------------
// EM4469 / EM4305 routines
//-----------------------------------