- // we now have a set of cycle counts, loop over previous results and aggregate data into bit patterns
- lastval=dest[0];
- idx=0;
- i=0;
- n=0;
- for( idx=0; idx<m; idx++) {
- if (dest[idx]==lastval) {
- n++;
- } else {
- // a bit time is five fc/10 or six fc/8 cycles so figure out how many bits a pattern width represents,
- // an extra fc/8 pattern preceeds every 4 bits (about 200 cycles) just to complicate things but it gets
- // swallowed up by rounding
- // expected results are 1 or 2 bits, any more and it's an invalid manchester encoding
- // special start of frame markers use invalid manchester states (no transitions) by using sequences
- // like 111000
- if (dest[idx-1]) {
- n=(n+1)/7; // fc/8 in sets of 7
- } else {
- n=(n+1)/6; // fc/10 in sets of 6
- }
- switch (n) { // stuff appropriate bits in buffer
- case 0:
- case 1: // one bit
- dest[i++]=dest[idx-1]^1;
- //Dbprintf("%d",dest[idx-1]);
- break;
- case 2: // two bits
- dest[i++]=dest[idx-1]^1;
- dest[i++]=dest[idx-1]^1;
- //Dbprintf("%d",dest[idx-1]);
- //Dbprintf("%d",dest[idx-1]);
- break;
- case 3: // 3 bit start of frame markers
- for(int j=0; j<3; j++){
- dest[i++]=dest[idx-1]^1;
- // Dbprintf("%d",dest[idx-1]);
- }
- break;
- case 4:
- for(int j=0; j<4; j++){
- dest[i++]=dest[idx-1]^1;
- // Dbprintf("%d",dest[idx-1]);
- }
- break;
- case 5:
- for(int j=0; j<5; j++){
- dest[i++]=dest[idx-1]^1;
- // Dbprintf("%d",dest[idx-1]);
- }
- break;
- case 6:
- for(int j=0; j<6; j++){
- dest[i++]=dest[idx-1]^1;
- // Dbprintf("%d",dest[idx-1]);
- }
- break;
- case 7:
- for(int j=0; j<7; j++){
- dest[i++]=dest[idx-1]^1;
- // Dbprintf("%d",dest[idx-1]);
- }
- break;
- case 8:
- for(int j=0; j<8; j++){
- dest[i++]=dest[idx-1]^1;
- // Dbprintf("%d",dest[idx-1]);
- }
- break;
- case 9:
- for(int j=0; j<9; j++){
- dest[i++]=dest[idx-1]^1;
- // Dbprintf("%d",dest[idx-1]);
- }
- break;
- case 10:
- for(int j=0; j<10; j++){
- dest[i++]=dest[idx-1]^1;
- // Dbprintf("%d",dest[idx-1]);
- }
- break;
- case 11:
- for(int j=0; j<11; j++){
- dest[i++]=dest[idx-1]^1;
- // Dbprintf("%d",dest[idx-1]);
- }
- break;
- case 12:
- for(int j=0; j<12; j++){
- dest[i++]=dest[idx-1]^1;
- // Dbprintf("%d",dest[idx-1]);
- }
- break;
- default: // this shouldn't happen, don't stuff any bits
- //Dbprintf("%d",dest[idx-1]);
- break;
- }
- n=0;
- lastval=dest[idx];
+void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
+{
+ uint8_t *dest = BigBuf_get_addr();
+ int idx=0;
+ uint32_t code=0, code2=0;
+ uint8_t version=0;
+ uint8_t facilitycode=0;
+ uint16_t number=0;
+ uint8_t crc = 0;
+ uint16_t calccrc = 0;
+
+ //clear read buffer
+ BigBuf_Clear_keep_EM();
+
+ // 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);
+ //fskdemod and get start index
+ WDT_HIT();
+ idx = IOdemodFSK(dest, BigBuf_max_traceLen());
+ if (idx<0) continue;
+ //valid tag found
+
+ //Index map
+ //0 10 20 30 40 50 60
+ //| | | | | | |
+ //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 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
+ // Dbprintf("%d%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],dest[idx+8]);
+ // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+9], dest[idx+10],dest[idx+11],dest[idx+12],dest[idx+13],dest[idx+14],dest[idx+15],dest[idx+16],dest[idx+17]);
+ // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+18],dest[idx+19],dest[idx+20],dest[idx+21],dest[idx+22],dest[idx+23],dest[idx+24],dest[idx+25],dest[idx+26]);
+ // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+27],dest[idx+28],dest[idx+29],dest[idx+30],dest[idx+31],dest[idx+32],dest[idx+33],dest[idx+34],dest[idx+35]);
+ // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+36],dest[idx+37],dest[idx+38],dest[idx+39],dest[idx+40],dest[idx+41],dest[idx+42],dest[idx+43],dest[idx+44]);
+ // Dbprintf("%d%d%d%d%d%d%d%d %d",dest[idx+45],dest[idx+46],dest[idx+47],dest[idx+48],dest[idx+49],dest[idx+50],dest[idx+51],dest[idx+52],dest[idx+53]);
+ // Dbprintf("%d%d%d%d%d%d%d%d %d%d",dest[idx+54],dest[idx+55],dest[idx+56],dest[idx+57],dest[idx+58],dest[idx+59],dest[idx+60],dest[idx+61],dest[idx+62],dest[idx+63]);
+ // }
+ code = bytebits_to_byte(dest+idx,32);
+ code2 = bytebits_to_byte(dest+idx+32,32);
+ version = bytebits_to_byte(dest+idx+27,8); //14,4
+ 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
+
+ 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();
+ *high=code;
+ *low=code2;
+ break;