]> cvs.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/lfops.c
add : writing on PCF7931 tags
[proxmark3-svn] / armsrc / lfops.c
index 797bc51ce5613486c447de87b95cd912054a2205..dc7ffd8818d9f7e9829dad12f26613ba4e09106d 100644 (file)
@@ -16,8 +16,7 @@
 #include "string.h"
 #include "lfdemod.h"
 #include "lfsampling.h"
 #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.
 
 /**
  * Function to do a modulation and then get samples.
@@ -214,6 +213,8 @@ void ReadTItag(void)
        }
 }
 
        }
 }
 
+
+
 void WriteTIbyte(uint8_t b)
 {
        int i = 0;
 void WriteTIbyte(uint8_t b)
 {
        int i = 0;
@@ -310,12 +311,17 @@ void AcquireTiType(void)
        }
 }
 
        }
 }
 
+
+
+
 // 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)
 {
 // 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);
+
+
+FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
        if(crc == 0) {
                crc = update_crc16(crc, (idlo)&0xff);
                crc = update_crc16(crc, (idlo>>8)&0xff);
        if(crc == 0) {
                crc = update_crc16(crc, (idlo)&0xff);
                crc = update_crc16(crc, (idlo>>8)&0xff);
@@ -402,7 +408,7 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
        for(;;) {
                //wait until SSC_CLK goes HIGH
                while(!(AT91C_BASE_PIOA->PIO_PDSR & GPIO_SSC_CLK)) {
        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;
                        }
                                DbpString("Stopped");
                                return;
                        }
@@ -651,7 +657,7 @@ void CmdASKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
        int ledcontrol = 1;
        int n=0, i=0;
        uint8_t clk = (arg1 >> 8) & 0xFF;
        int ledcontrol = 1;
        int n=0, i=0;
        uint8_t clk = (arg1 >> 8) & 0xFF;
-       uint8_t encoding = arg1 & 1;
+       uint8_t encoding = arg1 & 0xFF;
        uint8_t separator = arg2 & 1;
        uint8_t invert = (arg2 >> 8) & 1;
 
        uint8_t separator = arg2 & 1;
        uint8_t invert = (arg2 >> 8) & 1;
 
@@ -755,8 +761,8 @@ void CmdPSKsimTag(uint16_t arg1, uint16_t arg2, size_t size, uint8_t *BitStream)
 void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
 {
        uint8_t *dest = BigBuf_get_addr();
 void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
 {
        uint8_t *dest = BigBuf_get_addr();
-       const size_t sizeOfBigBuff = BigBuf_max_traceLen();
-       size_t size = 0
+       //const size_t sizeOfBigBuff = BigBuf_max_traceLen();
+       size_t size; 
        uint32_t hi2=0, hi=0, lo=0;
        int idx=0;
        // Configure to go in 125Khz listen mode
        uint32_t hi2=0, hi=0, lo=0;
        int idx=0;
        // Configure to go in 125Khz listen mode
@@ -769,16 +775,16 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
 
                DoAcquisition_default(-1,true);
                // FSK demodulator
 
                DoAcquisition_default(-1,true);
                // FSK demodulator
-               size = sizeOfBigBuff;  //variable size will change after demod so re initialize it before use
+               //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 = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
                
                idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
                
-               if (idx>0 && lo>0){
-                       // final loop, go over previously decoded manchester data and decode into usable tag ID
-                       // 111000 bit pattern represent start of frame, 01 pattern represents a 1 and 10 represents a 0
-                       if (hi2 != 0){ //extra large HID tags
+               if (idx>0 && lo>0 && (size==96 || size==192)){
+                       // go over previously decoded manchester data and decode into usable tag ID
+                       if (hi2 != 0){ //extra large HID tags  88/192 bits
                                Dbprintf("TAG ID: %x%08x%08x (%d)",
                                  (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
                                Dbprintf("TAG ID: %x%08x%08x (%d)",
                                  (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
-                       }else {  //standard HID tags <38 bits
+                       }else {  //standard HID tags 44/96 bits
                                //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
                                uint8_t bitlen = 0;
                                uint32_t fc = 0;
                                //Dbprintf("TAG ID: %x%08x (%d)",(unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF); //old print cmd
                                uint8_t bitlen = 0;
                                uint32_t fc = 0;
@@ -833,8 +839,98 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
                                return;
                        }
                        // reset
                                return;
                        }
                        // reset
-                       hi2 = hi = lo = 0;
                }
                }
+               hi2 = hi = lo = idx = 0;
+               WDT_HIT();
+       }
+       DbpString("Stopped");
+       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()) {
+
+               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");
                WDT_HIT();
        }
        DbpString("Stopped");
@@ -859,49 +955,42 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
 
                DoAcquisition_default(-1,true);
                size  = BigBuf_max_traceLen();
 
                DoAcquisition_default(-1,true);
                size  = BigBuf_max_traceLen();
-               //Dbprintf("DEBUG: Buffer got");
                //askdemod and manchester decode
                //askdemod and manchester decode
-               errCnt = askmandemod(dest, &size, &clk, &invert, maxErr);
-               //Dbprintf("DEBUG: ASK Got");
+               if (size > 16385) size = 16385; //big enough to catch 2 sequences of largest format
+               errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1);
                WDT_HIT();
 
                WDT_HIT();
 
-               if (errCnt>=0){
-                       errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
-                       //Dbprintf("DEBUG: EM GOT");
-                       if (errCnt){
-                               if (size>64){
-                                       Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
-                                         hi,
-                                         (uint32_t)(lo>>32),
-                                         (uint32_t)lo,
-                                         (uint32_t)(lo&0xFFFF),
-                                         (uint32_t)((lo>>16LL) & 0xFF),
-                                         (uint32_t)(lo & 0xFFFFFF));
-                               } else {
-                                       Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
-                                         (uint32_t)(lo>>32),
-                                         (uint32_t)lo,
-                                         (uint32_t)(lo&0xFFFF),
-                                         (uint32_t)((lo>>16LL) & 0xFF),
-                                         (uint32_t)(lo & 0xFFFFFF));
-                               }
+               if (errCnt<0) continue;
+       
+               errCnt = Em410xDecode(dest, &size, &idx, &hi, &lo);
+               if (errCnt){
+                       if (size>64){
+                               Dbprintf("EM XL TAG ID: %06x%08x%08x - (%05d_%03d_%08d)",
+                                 hi,
+                                 (uint32_t)(lo>>32),
+                                 (uint32_t)lo,
+                                 (uint32_t)(lo&0xFFFF),
+                                 (uint32_t)((lo>>16LL) & 0xFF),
+                                 (uint32_t)(lo & 0xFFFFFF));
+                       } else {
+                               Dbprintf("EM TAG ID: %02x%08x - (%05d_%03d_%08d)",
+                                 (uint32_t)(lo>>32),
+                                 (uint32_t)lo,
+                                 (uint32_t)(lo&0xFFFF),
+                                 (uint32_t)((lo>>16LL) & 0xFF),
+                                 (uint32_t)(lo & 0xFFFFFF));
                        }
                        }
+
                        if (findone){
                                if (ledcontrol) LED_A_OFF();
                                *high=lo>>32;
                                *low=lo & 0xFFFFFFFF;
                                return;
                        }
                        if (findone){
                                if (ledcontrol) LED_A_OFF();
                                *high=lo>>32;
                                *low=lo & 0xFFFFFFFF;
                                return;
                        }
-               } else{
-                       //Dbprintf("DEBUG: No Tag");
                }
                WDT_HIT();
                }
                WDT_HIT();
-               hi = 0;
-               lo = 0;
-               clk=0;
-               invert=0;
-               errCnt=0;
-               size=0;
+               hi = lo = size = idx = 0;
+               clk = invert = errCnt = 0;
        }
        DbpString("Stopped");
        if (ledcontrol) LED_A_OFF();
        }
        DbpString("Stopped");
        if (ledcontrol) LED_A_OFF();
@@ -925,47 +1014,47 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
                //fskdemod and get start index
                WDT_HIT();
                idx = IOdemodFSK(dest, BigBuf_max_traceLen());
                //fskdemod and get start index
                WDT_HIT();
                idx = IOdemodFSK(dest, BigBuf_max_traceLen());
-               if (idx>0){
-                       //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 ???????? 11
-                       //
-                       //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
-
-                       Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
-                       // if we're only looking for one tag
-                       if (findone){
-                               if (ledcontrol) LED_A_OFF();
-                               //LED_A_OFF();
-                               *high=code;
-                               *low=code2;
-                               return;
-                       }
-                       code=code2=0;
-                       version=facilitycode=0;
-                       number=0;
-                       idx=0;
+               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 ???????? 11
+               //
+               //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
+
+               Dbprintf("XSF(%02d)%02x:%05d (%08x%08x)",version,facilitycode,number,code,code2);
+               // if we're only looking for one tag
+               if (findone){
+                       if (ledcontrol) LED_A_OFF();
+                       //LED_A_OFF();
+                       *high=code;
+                       *low=code2;
+                       return;
+               }
+               code=code2=0;
+               version=facilitycode=0;
+               number=0;
+               idx=0;
+
                WDT_HIT();
        }
        DbpString("Stopped");
                WDT_HIT();
        }
        DbpString("Stopped");
@@ -1031,10 +1120,10 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
  * To compensate antenna falling times shorten the write times
  * and enlarge the gap ones.
  */
  * To compensate antenna falling times shorten the write times
  * and enlarge the gap ones.
  */
-#define START_GAP 50*8 // 10 - 50fc 250
-#define WRITE_GAP 20*8 //    - 30fc 160
-#define WRITE_0   24*8 // 16 - 63fc 54fc 144
-#define WRITE_1   54*8 // 48 - 63fc 54fc 432 for T55x7; 448 for E5550 //400
+#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   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 T55xx_SAMPLES_SIZE      12000 // 32 x 32 x 10  (32 bit times numofblock (7), times clock skip..)
 
 
 #define T55xx_SAMPLES_SIZE      12000 // 32 x 32 x 10  (32 bit times numofblock (7), times clock skip..)
 
@@ -1622,6 +1711,8 @@ int DemodPCF7931(uint8_t **outBlocks) {
                if(num_blocks == 4) break;
        }
        memcpy(outBlocks, Blocks, 16*num_blocks);
                if(num_blocks == 4) break;
        }
        memcpy(outBlocks, Blocks, 16*num_blocks);
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+
        return num_blocks;
 }
 
        return num_blocks;
 }
 
@@ -1745,14 +1836,21 @@ void ReadPCF7931() {
        Dbprintf("Memory content:");
        Dbprintf("-----------------------------------------");
        for(i=0; i<max_blocks; i++) {
        Dbprintf("Memory content:");
        Dbprintf("-----------------------------------------");
        for(i=0; i<max_blocks; i++) {
-               if(Blocks[i][ALLOC]==1)
+               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]);
                        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
+               if(i==3){       
+                       if(Blocks[3][0] == 0xAA)
+                       Dbprintf("Solde actuel : %d centimes,  solde précédent : %d centimes", (Blocks[3][1] << 8 | Blocks[3][2]), (Blocks[3][6] << 8 | Blocks[3][7]));
+                       else
+                       Dbprintf("Solde actuel : %d centimes,  solde précédent : %d centimes", (Blocks[3][6] << 8 | Blocks[3][7]), (Blocks[3][1] << 8 | Blocks[3][2]));
+               }
+               }else
                        Dbprintf("<missing block %d>", i);
        }
        Dbprintf("-----------------------------------------");
                        Dbprintf("<missing block %d>", i);
        }
        Dbprintf("-----------------------------------------");
+       
 
        return ;
 }
 
        return ;
 }
@@ -1975,3 +2073,261 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
        LED_D_OFF();
 }
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
        LED_D_OFF();
 }
+
+
+#define T0_PCF 8 //period for the pcf7931 in us
+
+/* Write on a byte of a PCF7931 tag
+ * @param address : address of the block to write
+   @param byte : address of the byte to write
+    @param data : data to write
+ */
+void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data)
+{
+
+       uint32_t tab[1024]={0}; // data times frame
+       uint32_t u = 0;
+       uint8_t parity = 0;
+       bool comp = 0;
+
+
+       //BUILD OF THE DATA FRAME
+
+       //alimentation of the tag (time for initializing)
+       AddPatternPCF7931(init_delay, 0, 8192/2*T0_PCF, tab);
+
+       //PMC
+       Dbprintf("Initialization delay : %d us", init_delay);
+       AddPatternPCF7931(8192/2*T0_PCF + 319*T0_PCF+70, 3*T0_PCF, 29*T0_PCF, tab);
+
+       Dbprintf("Offsets : %d us on the low pulses width, %d us on the low pulses positions", l, p);
+
+       //password indication bit
+       AddBitPCF7931(1, tab, l, p);
+
+
+       //password (on 56 bits)
+       Dbprintf("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", pass1,pass2,pass3,pass4,pass5,pass6,pass7);
+       AddBytePCF7931(pass1, tab, l, p);
+       AddBytePCF7931(pass2, tab, l, p);
+       AddBytePCF7931(pass3, tab, l, p);
+       AddBytePCF7931(pass4, tab, l, p);
+       AddBytePCF7931(pass5, tab, l, p);
+       AddBytePCF7931(pass6, tab, l, p);
+       AddBytePCF7931(pass7, tab, l, p);
+
+
+       //programming mode (0 or 1)
+       AddBitPCF7931(0, tab, l, p);
+
+       //block adress on 6 bits
+       Dbprintf("Block address : %02x", address);
+       for (u=0; u<6; u++)
+       {
+               if (address&(1<<u)) {   // bit 1
+                        parity++;
+                        AddBitPCF7931(1, tab, l, p);
+               } else{                                 // bit 0
+                        AddBitPCF7931(0, tab, l, p);
+               }
+       }
+
+       //byte address on 4 bits
+       Dbprintf("Byte address : %02x", byte);
+       for (u=0; u<4; u++)
+       {
+               if (byte&(1<<u)) {      // bit 1
+                        parity++;
+                        AddBitPCF7931(1, tab, l, p);
+               } else{                         // bit 0
+                        AddBitPCF7931(0, tab, l, p);
+               }
+       }
+
+       //data on 8 bits
+       Dbprintf("Data : %02x", data);
+       for (u=0; u<8; u++)
+       {
+               if (data&(1<<u)) {      // bit 1
+                        parity++;
+                        AddBitPCF7931(1, tab, l, p);
+               } else{                         //bit 0
+                        AddBitPCF7931(0, tab, l, p);
+               }
+       }
+
+
+       //parity bit
+       if((parity%2)==0){
+               AddBitPCF7931(0, tab, l, p); //even parity
+       }else{
+               AddBitPCF7931(1, tab, l, p);//odd parity
+       }
+
+       //time access memory
+       AddPatternPCF7931(5120+2680, 0, 0, tab);
+
+       //conversion of the scale time
+       for(u=0;u<500;u++){
+               tab[u]=(tab[u] * 3)/2;
+       }
+
+
+       //compennsation of the counter reload
+       while (!comp){
+               comp = 1;
+               for(u=0;tab[u]!=0;u++){
+                       if(tab[u] > 0xFFFF){
+                         tab[u] -= 0xFFFF;
+                         comp = 0;
+                       }
+               }
+       }
+
+       SendCmdPCF7931(tab);
+}
+
+
+
+/* Send a trame to a PCF7931 tags
+ * @param tab : array of the data frame
+ */
+
+void SendCmdPCF7931(uint32_t * tab){
+       uint16_t u=0;
+       uint16_t tempo=0;
+
+       Dbprintf("SENDING DATA FRAME...");
+
+       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
+
+       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_PASSTHRU );
+
+       LED_A_ON();
+
+       // steal this pin from the SSP and use it to control the modulation
+       AT91C_BASE_PIOA->PIO_PER = GPIO_SSC_DOUT;
+       AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
+
+       //initialization of the timer
+       AT91C_BASE_PMC->PMC_PCER |= (0x1 << 12) | (0x1 << 13) | (0x1 << 14);
+       AT91C_BASE_TCB->TCB_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_TIOA0 | AT91C_TCB_TC2XC2S_NONE;
+       AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
+       AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV3_CLOCK;  //clock at 48/32 MHz
+       AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKEN;
+       AT91C_BASE_TCB->TCB_BCR = 1;
+
+
+       tempo = AT91C_BASE_TC0->TC_CV;
+       for(u=0;tab[u]!= 0;u+=3){
+
+
+               // modulate antenna
+               HIGH(GPIO_SSC_DOUT);
+               while(tempo !=  tab[u]){
+                       tempo = AT91C_BASE_TC0->TC_CV;
+               }
+
+               // stop modulating antenna
+               LOW(GPIO_SSC_DOUT);
+               while(tempo !=  tab[u+1]){
+                       tempo = AT91C_BASE_TC0->TC_CV;
+               }
+
+
+               // modulate antenna
+               HIGH(GPIO_SSC_DOUT);
+               while(tempo !=  tab[u+2]){
+                       tempo = AT91C_BASE_TC0->TC_CV;
+               }
+
+
+       }
+
+       LED_A_OFF();
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       SpinDelay(200);
+
+
+       AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS; // timer disable
+       DbpString("FINISH !");
+       DbpString("(Could be usefull to send the same trame many times)");
+       LED(0xFFFF, 1000);
+}
+
+
+/* Add a byte for building the data frame of PCF7931 tags 
+ * @param b : byte to add
+ * @param tab : array of the data frame
+ * @param l : offset on low pulse width
+ * @param p : offset on low pulse positioning
+ */
+
+bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p){
+
+       uint32_t u;
+       for (u=0; u<8; u++)
+       {
+               if (byte&(1<<u)) {      //bit à 1
+                       if(AddBitPCF7931(1, tab, l, p)==1)return 1;
+               } else { //bit à 0
+                       if(AddBitPCF7931(0, tab, l, p)==1)return 1;
+               }
+       }
+
+       return 0;
+}
+
+/* Add a bits for building the data frame of PCF7931 tags 
+ * @param b : bit to add
+ * @param tab : array of the data frame
+ * @param l : offset on low pulse width
+ * @param p : offset on low pulse positioning
+ */
+bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p){
+       uint8_t u = 0;
+
+       for(u=0;tab[u]!=0;u+=3){} //we put the cursor at the last value of the array
+       
+
+       if(b==1){       //add a bit 1
+               if(u==0) tab[u] = 34*T0_PCF+p;
+               else     tab[u] = 34*T0_PCF+tab[u-1]+p;
+
+               tab[u+1] = 6*T0_PCF+tab[u]+l;
+               tab[u+2] = 88*T0_PCF+tab[u+1]-l-p;
+               return 0;
+       }else{          //add a bit 0
+
+               if(u==0) tab[u] = 98*T0_PCF+p;
+               else     tab[u] = 98*T0_PCF+tab[u-1]+p;
+
+               tab[u+1] = 6*T0_PCF+tab[u]+l;
+               tab[u+2] = 24*T0_PCF+tab[u+1]-l-p;
+               return 0;
+       }
+
+       
+       return 1;
+}
+
+/* Add a custom pattern in the data frame
+ * @param a : delay of the first high pulse
+ * @param b : delay of the low pulse
+ * @param c : delay of the last high pulse
+ * @param tab : array of the data frame
+ */
+bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab){
+       uint32_t u = 0;
+       for(u=0;tab[u]!=0;u+=3){} //we put the cursor at the last value of the array
+
+       if(u==0) tab[u] = a;
+       else tab[u] = a + tab[u-1];
+
+       tab[u+1] = b+tab[u];
+       tab[u+2] = c+tab[u+1];
+
+       return 0;
+}
\ No newline at end of file
Impressum, Datenschutz