]> git.zerfleddert.de Git - proxmark3-svn/commitdiff
Merge pull request #147 from ha7dcd/pcb
authorMartin Holst Swende <martin@swende.se>
Sun, 22 Nov 2015 14:05:47 +0000 (15:05 +0100)
committerMartin Holst Swende <martin@swende.se>
Sun, 22 Nov 2015 14:05:47 +0000 (15:05 +0100)
Updates and fixes to the PCB schematics

29 files changed:
CHANGELOG.md
Makefile
armsrc/BigBuf.c
armsrc/BigBuf.h
armsrc/Makefile
armsrc/appmain.c
armsrc/apps.h
armsrc/lfops.c
armsrc/lfsampling.c
armsrc/lfsampling.h
armsrc/pcf7931.c [new file with mode: 0644]
armsrc/pcf7931.h [new file with mode: 0644]
client/cmddata.c
client/cmddata.h
client/cmdhf14a.c
client/cmdlf.c
client/cmdlfem4x.c
client/cmdlfpcf7931.c
client/cmdlfpcf7931.h
client/cmdlft55xx.c
client/cmdlft55xx.h
client/hid-flasher/usb_cmd.h
client/lualibs/commands.lua
client/scripting.c
common/lfdemod.c
common/lfdemod.h
common/protocols.c
common/protocols.h
include/usb_cmd.h

index 80c16ffaba1a703771faeeec6da6fa9e71901092..a3a0799ecf37928618e879cc5525069d606baabf 100644 (file)
@@ -5,6 +5,11 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 ## [unreleased][unreleased]
 
 ### Added
+- Added viking demod to `lf search` (marshmellow)
+- `data askvikingdemod` demod viking id tag from graphbuffer (marshmellow)
+- `lf t55xx resetread` added reset then read command - should allow determining start
+of stream transmissions (marshmellow)
+- `lf t55xx wakeup` added wake with password (AOR) to allow lf search or standard lf read after (iceman, marshmellow)
 - `hf iclass managekeys` to save, load and manage iclass keys.  (adjusted most commands to accept a loaded key in memory) (marshmellow)
 - `hf iclass readblk` to select, authenticate, and read 1 block from an iclass card (marshmellow)
 - `hf iclass writeblk` to select, authenticate, and write 1 block to an iclass card (or picopass) (marshmellow + others)
@@ -21,6 +26,13 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
 - Added option c to 'hf list' (mark CRC bytes) (piwi)
 
 ### Changed
+- Adjusted lf em410x em410xsim to accept a clock argument
+- Adjusted lf t55xx dump to allow overriding the safety check and warning text (marshmellow)
+- Adjusted lf t55xx write input variables (marshmellow)
+- Adjusted lf t55xx read with password safety check and warning text and adjusted the input variables (marshmellow & iceman)
+- Adjusted LF FSK demod to account for cross threshold fluctuations (898 count waves will adjust the 9 to 8 now...) more accurate.
+- Adjusted timings for t55xx commands.  more reliable now. (marshmellow & iceman)
+- `lf cmdread` adjusted input methods and added help text (marshmellow & iceman)
 - changed `lf config t <threshold>` to be 0 - 128 and will trigger on + or - threshold value (marshmellow) 
 - `hf iclass dump` cli options - can now dump AA1 and AA2 with different keys in one run (does not go to muliple pages for the larger tags yet)
 - Revised workflow for StandAloneMode14a (Craig Young)
index 0e065b41dc9ee86c6245d421163f66990c0a75e5..bafd816102dc3cd1156edc8a54e4cfb5046a149a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -22,7 +22,7 @@ help:
        @echo + all           - Make bootrom, armsrc and the OS-specific host directory
        @echo + client        - Make only the OS-specific host directory
        @echo + flash-bootrom - Make bootrom and flash it
-       @echo + flash-os      - Make armsrc and flash os (includes fpga)
+       @echo + flash-os      - Make armsrc and flash os \(includes fpga\)
        @echo + flash-all     - Make bootrom and armsrc and flash bootrom and os image
        @echo + clean         - Clean in bootrom, armsrc and the OS-specific host directory
 
index 6b52a5894545beaa352273aeea608945a6ada7b0..8f9ee4beb7a2e58a02b35996d7645575cc1f7abb 100644 (file)
@@ -50,9 +50,15 @@ uint8_t *BigBuf_get_EM_addr(void)
 
 // clear ALL of BigBuf
 void BigBuf_Clear(void)
+{
+       BigBuf_Clear_ext(true);
+}
+// clear ALL of BigBuf
+void BigBuf_Clear_ext(bool verbose)
 {
        memset(BigBuf,0,BIGBUF_SIZE);
-       Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
+       if (verbose) 
+               Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
 }
 
 
index 05b4180e4b21c77b1604734035b5478216b7918d..13432e7eabf2953e2ec0bfce9af9645897866b2a 100644 (file)
@@ -25,6 +25,7 @@ extern uint8_t *BigBuf_get_addr(void);
 extern uint8_t *BigBuf_get_EM_addr(void);
 extern uint16_t BigBuf_max_traceLen(void);
 extern void BigBuf_Clear(void);
+extern void BigBuf_Clear_ext(bool verbose);
 extern uint8_t *BigBuf_malloc(uint16_t);
 extern void BigBuf_free(void);
 extern void BigBuf_free_keep_EM(void);
index 3c6c14c64305a05ce5d561e9bda8de9ff8ef78e6..69ea23006c54c4a8008880179bc8c9d67628a63c 100644 (file)
@@ -15,7 +15,7 @@ APP_CFLAGS    = -DWITH_ISO14443a_StandAlone -DWITH_LF -DWITH_ISO15693 -DWITH_ISO144
 #-DWITH_LCD
 
 #SRC_LCD = fonts.c LCD.c
-SRC_LF = lfops.c hitag2.c lfsampling.c
+SRC_LF = lfops.c hitag2.c lfsampling.c pcf7931.c lfdemod.c protocols.c
 SRC_ISO15693 = iso15693.c iso15693tools.c
 SRC_ISO14443a = epa.c iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
 SRC_ISO14443b = iso14443b.c
@@ -52,7 +52,6 @@ THUMBSRC = start.c \
 # These are to be compiled in ARM mode
 ARMSRC = fpgaloader.c \
        legicrf.c \
-       lfdemod.c \
        $(SRC_ISO14443a) \
        $(SRC_ISO14443b) \
        $(SRC_CRAPTO1) \
index 8c2aefbbaf3ce7c9eb9c0a5525737f95a827d768..e7324723f3049dc8ab3327f27d9f546f445827af 100644 (file)
@@ -26,6 +26,7 @@
 #include "lfsampling.h"
 #include "BigBuf.h"
 #include "mifareutil.h"
+#include "pcf7931.h"
 #ifdef WITH_LCD
  #include "LCD.h"
 #endif
@@ -945,7 +946,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        CmdIOdemodFSK(c->arg[0], 0, 0, 1);
                        break;
                case CMD_IO_CLONE_TAG:
-                       CopyIOtoT55x7(c->arg[0], c->arg[1], c->d.asBytes[0]);
+                       CopyIOtoT55x7(c->arg[0], c->arg[1]);
                        break;
                case CMD_EM410X_DEMOD:
                        CmdEM410xdemod(c->arg[0], 0, 0, 1);
@@ -974,21 +975,22 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        CopyIndala224toT55x7(c->d.asDwords[0], c->d.asDwords[1], c->d.asDwords[2], c->d.asDwords[3], c->d.asDwords[4], c->d.asDwords[5], c->d.asDwords[6]);
                        break;
                case CMD_T55XX_READ_BLOCK:
-                       T55xxReadBlock(c->arg[1], c->arg[2],c->d.asBytes[0]);
+                       T55xxReadBlock(c->arg[0], c->arg[1], c->arg[2]);
                        break;
                case CMD_T55XX_WRITE_BLOCK:
                        T55xxWriteBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes[0]);
-                       cmd_send(CMD_ACK,0,0,0,0,0);
                        break;
-               case CMD_T55XX_READ_TRACE:
-                       T55xxReadTrace();
+               case CMD_T55XX_WAKEUP:
+                       T55xxWakeUp(c->arg[0]);
+                       break;
+               case CMD_T55XX_RESET_READ:
+                       T55xxResetRead();
                        break;
                case CMD_PCF7931_READ:
                        ReadPCF7931();
-                       cmd_send(CMD_ACK,0,0,0,0,0);
                        break;
                case CMD_PCF7931_WRITE:
-                       WritePCF7931(c->d.asDwords[0],c->d.asDwords[1],c->d.asDwords[2],c->d.asDwords[3],c->d.asDwords[4],c->d.asDwords[5],c->d.asDwords[6], c->d.asDwords[9], c->d.asDwords[7]-128,c->d.asDwords[8]-128, c->arg[0], c->arg[1], c->arg[2]);
+                       WritePCF7931(c->d.asBytes[0],c->d.asBytes[1],c->d.asBytes[2],c->d.asBytes[3],c->d.asBytes[4],c->d.asBytes[5],c->d.asBytes[6], c->d.asBytes[9], c->d.asBytes[7]-128,c->d.asBytes[8]-128, c->arg[0], c->arg[1], c->arg[2]);
                        break;
                case CMD_EM4X_READ_WORD:
                        EM4xReadWord(c->arg[1], c->arg[2],c->d.asBytes[0]);
@@ -998,7 +1000,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
                        break;
                case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
                        CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
-                        break;
+                       break;
 #endif
 
 #ifdef WITH_HITAG
index 2cfd31d73420ff1ac58f675743fb66d482615357..4f3b50c6171ef99b6184c95505cae602fd2622cf 100644 (file)
@@ -58,7 +58,7 @@ extern uint8_t bits_per_sample ;
 extern bool averaging;
 
 void AcquireRawAdcSamples125k(int divisor);
-void ModThenAcquireRawAdcSamples125k(int delay_off,int period_0,int period_1,uint8_t *command);
+void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command);
 void ReadTItag(void);
 void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
 
@@ -73,24 +73,18 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol);
 void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol); // Realtime demodulation mode for AWID26
 void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol);
 void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol);
-void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an ioProx card to T5557/T5567
+void CopyIOtoT55x7(uint32_t hi, uint32_t lo); // Clone an ioProx card to T5557/T5567
 void SimulateTagLowFrequencyBidir(int divisor, int max_bitlen);
 void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT); // Clone an HID card to T5557/T5567
 void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo);
-void CopyIndala64toT55x7(int hi, int lo); // Clone Indala 64-bit tag by UID to T55x7
-void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7); // Clone Indala 224-bit tag by UID to T55x7
+void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-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); // Clone Indala 224-bit tag by UID to T55x7
+void T55xxResetRead(void);
 void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode);
-void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode );
-void T55xxReadTrace(void);
-int DemodPCF7931(uint8_t **outBlocks);
-int IsBlock0PCF7931(uint8_t *Block);
-int IsBlock1PCF7931(uint8_t *Block);
-void ReadPCF7931();
-void SendCmdPCF7931(uint32_t * tab);
-bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p);
-bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p);
-bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab);
-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);
+void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd);
+void T55xxWakeUp(uint32_t Pwd);
+void TurnReadLFOn();
+//void T55xxReadTrace(void);
 void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
 void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
 
index d7f91c533e041be303e657a79471f33f8535a682..01b88178169c6fe6c992e27d6b420b24a0ee24d4 100644 (file)
@@ -16,6 +16,7 @@
 #include "string.h"
 #include "lfdemod.h"
 #include "lfsampling.h"
+#include "protocols.h"
 #include "usb_cdc.h" //test
 
 /**
@@ -25,7 +26,7 @@
  * @param period_1
  * @param command
  */
-void ModThenAcquireRawAdcSamples125k(int delay_off, int period_0, int period_1, uint8_t *command)
+void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command)
 {
 
        int divisor_used = 95; // 125 KHz
@@ -648,7 +649,6 @@ static void biphaseSimBit(uint8_t c, int *n, uint8_t clock, uint8_t *phase)
                memset(dest+(*n), c ^ *phase, clock);
                *phase ^= 1;
        }
-
 }
 
 // args clock, ask/man or askraw, invert, transmission separator
@@ -768,7 +768,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
        // 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();
@@ -857,7 +857,7 @@ void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
        // 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();
@@ -948,7 +948,7 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
        // 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();
@@ -1007,7 +1007,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
        // 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);
@@ -1062,237 +1062,225 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
 }
 
 /*------------------------------
- * T5555/T5557/T5567 routines
+ * T5555/T5557/T5567/T5577 routines
  *------------------------------
  */
 
-/* T55x7 configuration register definitions */
-#define T55x7_POR_DELAY                        0x00000001
-#define T55x7_ST_TERMINATOR            0x00000008
-#define T55x7_PWD                      0x00000010
-#define T55x7_MAXBLOCK_SHIFT           5
-#define T55x7_AOR                      0x00000200
-#define T55x7_PSKCF_RF_2               0
-#define T55x7_PSKCF_RF_4               0x00000400
-#define T55x7_PSKCF_RF_8               0x00000800
-#define T55x7_MODULATION_DIRECT                0
-#define T55x7_MODULATION_PSK1          0x00001000
-#define T55x7_MODULATION_PSK2          0x00002000
-#define T55x7_MODULATION_PSK3          0x00003000
-#define T55x7_MODULATION_FSK1          0x00004000
-#define T55x7_MODULATION_FSK2          0x00005000
-#define T55x7_MODULATION_FSK1a         0x00006000
-#define T55x7_MODULATION_FSK2a         0x00007000
-#define T55x7_MODULATION_MANCHESTER    0x00008000
-#define T55x7_MODULATION_BIPHASE       0x00010000
-#define T55x7_BITRATE_RF_8             0
-#define T55x7_BITRATE_RF_16            0x00040000
-#define T55x7_BITRATE_RF_32            0x00080000
-#define T55x7_BITRATE_RF_40            0x000C0000
-#define T55x7_BITRATE_RF_50            0x00100000
-#define T55x7_BITRATE_RF_64            0x00140000
-#define T55x7_BITRATE_RF_100           0x00180000
-#define T55x7_BITRATE_RF_128           0x001C0000
-
-/* T5555 (Q5) configuration register definitions */
-#define T5555_ST_TERMINATOR            0x00000001
-#define T5555_MAXBLOCK_SHIFT           0x00000001
-#define T5555_MODULATION_MANCHESTER    0
-#define T5555_MODULATION_PSK1          0x00000010
-#define T5555_MODULATION_PSK2          0x00000020
-#define T5555_MODULATION_PSK3          0x00000030
-#define T5555_MODULATION_FSK1          0x00000040
-#define T5555_MODULATION_FSK2          0x00000050
-#define T5555_MODULATION_BIPHASE       0x00000060
-#define T5555_MODULATION_DIRECT                0x00000070
-#define T5555_INVERT_OUTPUT            0x00000080
-#define T5555_PSK_RF_2                 0
-#define T5555_PSK_RF_4                 0x00000100
-#define T5555_PSK_RF_8                 0x00000200
-#define T5555_USE_PWD                  0x00000400
-#define T5555_USE_AOR                  0x00000800
-#define T5555_BITRATE_SHIFT            12
-#define T5555_FAST_WRITE               0x00004000
-#define T5555_PAGE_SELECT              0x00008000
+/* NOTE: T55x7/T5555 configuration register definitions moved to protocols.h */
 
 /*
- * Relevant times in microsecond
+ * Relevant communication times in microsecond
  * To compensate antenna falling times shorten the write times
  * and enlarge the gap ones.
+ * Q5 tags seems to have issues when these values changes. 
  */
 #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 READ_GAP  52*8 
 
-#define T55xx_SAMPLES_SIZE      12000 // 32 x 32 x 10  (32 bit times numofblock (7), times clock skip..)
+//  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) 
 
-// Write one bit to card
-void T55xxWriteBit(int bit)
-{
-       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
+//  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)  == 1 field clock
+
+void TurnReadLFOn(int delay) {
        FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-       if (bit == 0)
-               SpinDelayUs(WRITE_0);
+       // Give it a bit of time for the resonant antenna to settle.
+       SpinDelayUs(delay); //155*8 //50*8
+}
+
+// Write one bit to card
+void T55xxWriteBit(int bit) {
+       if (!bit)
+               TurnReadLFOn(WRITE_0);
        else
-               SpinDelayUs(WRITE_1);
+               TurnReadLFOn(WRITE_1);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        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 PwdMode)
-{
+void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
+       LED_A_ON();
+       bool PwdMode = arg & 0x1;
+       uint8_t Page = (arg & 0x2)>>1;
        uint32_t i = 0;
 
        // Set up FPGA, 125kHz
-       // Wait for config.. (192+8190xPOW)x8 == 67ms
-       LFSetupFPGAForADC(0, true);
+       LFSetupFPGAForADC(95, true);
 
-       // Now start writting
+       // Trigger T55x7 in mode.
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        SpinDelayUs(START_GAP);
 
-       // Opcode
+       // Opcode 10
        T55xxWriteBit(1);
-       T55xxWriteBit(0); //Page 0
-       if (PwdMode == 1){
-               // Pwd
+       T55xxWriteBit(Page); //Page 0
+       if (PwdMode){
+               // Send Pwd
                for (i = 0x80000000; i != 0; i >>= 1)
                        T55xxWriteBit(Pwd & i);
        }
-       // Lock bit
+       // Send Lock bit
        T55xxWriteBit(0);
 
-       // Data
+       // Send Data
        for (i = 0x80000000; i != 0; i >>= 1)
                T55xxWriteBit(Data & i);
 
-       // Block
+       // Send Block number
        for (i = 0x04; i != 0; i >>= 1)
                T55xxWriteBit(Block & i);
 
-       // Now perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
+       // Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
        // so wait a little more)
-       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-       SpinDelay(20);
+       TurnReadLFOn(20 * 1000);
+               //could attempt to do a read to confirm write took
+               // as the tag should repeat back the new block 
+               // until it is reset, but to confirm it we would 
+               // need to know the current block 0 config mode
+
+       // turn field off
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
+       LED_A_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);
+// Write one card block in page 0, no lock
+void T55xxWriteBlock(uint32_t Data, uint32_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 0
-void T55xxReadBlock(uint32_t Block, uint32_t Pwd, uint8_t PwdMode)
-{
+void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
+       LED_A_ON();
+       bool PwdMode = arg0 & 0x1;
+       uint8_t Page = (arg0 & 0x2) >> 1;
        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;
+       bool RegReadMode = (Block == 0xFF);
 
-       // Clear destination buffer before sending the command
-       memset(dest, 0x80, bufferlength);
+       //clear buffer now so it does not interfere with timing later
+       BigBuf_Clear_ext(false);
 
-       // Set up FPGA, 125kHz
-       // Wait for config.. (192+8190xPOW)x8 == 67ms
-       LFSetupFPGAForADC(0, true);
+       //make sure block is at max 7
+       Block &= 0x7;
+
+       // Set up FPGA, 125kHz to power up the tag
+       LFSetupFPGAForADC(95, true);
+
+       // Trigger T55x7 Direct Access Mode with start gap
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        SpinDelayUs(START_GAP);
 
-       // Opcode
+       // Opcode 1[page]
        T55xxWriteBit(1);
-       T55xxWriteBit(0); //Page 0
-       if (PwdMode == 1){
-               // Pwd
+       T55xxWriteBit(Page); //Page 0
+
+       if (PwdMode){
+               // Send Pwd
                for (i = 0x80000000; i != 0; i >>= 1)
                        T55xxWriteBit(Pwd & i);
        }
-       // Lock bit
+       // Send a zero bit separation
        T55xxWriteBit(0);
-       // Block
-       for (i = 0x04; i != 0; i >>= 1)
-               T55xxWriteBit(Block & i);
+
+       // Send Block number (if direct access mode)
+       if (!RegReadMode)
+               for (i = 0x04; i != 0; i >>= 1)
+                       T55xxWriteBit(Block & i);               
 
        // Turn field on to read the response
-       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();
-               }
-               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;
-               }
-       }
+       TurnReadLFOn(READ_GAP);
 
-       cmd_send(CMD_ACK,0,0,0,0,0);    
+       // Acquisition
+       doT55x7Acquisition(12000);
+
+       // Turn the field off
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
-       LED_D_OFF();
+       cmd_send(CMD_ACK,0,0,0,0,0);    
+       LED_A_OFF();
 }
 
-// Read card traceability data (page 1)
-void T55xxReadTrace(void){
-       
+void T55xxWakeUp(uint32_t Pwd){
+       LED_B_ON();
        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;
-
-       // Clear destination buffer before sending the command
-       memset(dest, 0x80, bufferlength);
-
-       LFSetupFPGAForADC(0, true);
+       
+       // Set up FPGA, 125kHz
+       LFSetupFPGAForADC(95, true);
+       
+       // Trigger T55x7 Direct Access Mode
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        SpinDelayUs(START_GAP);
-
-       // Opcode
+       
+       // Opcode 10
        T55xxWriteBit(1);
-       T55xxWriteBit(1); //Page 1
+       T55xxWriteBit(0); //Page 0
 
-       // Turn field on to read the response
-       TurnReadLFOn();
+       // Send Pwd
+       for (i = 0x80000000; i != 0; i >>= 1)
+               T55xxWriteBit(Pwd & i);
 
-       // Now do the acquisition
-       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();
+       // Turn and leave field on to let the begin repeating transmission
+       TurnReadLFOn(20*1000);
+}
 
-                       if (i >= bufferlength) break;
-               }
-       }
+/*-------------- Cloning routines -----------*/
 
-       cmd_send(CMD_ACK,0,0,0,0,0);
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
-       LED_D_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+startblock; i > startblock; i--) {
+               //Dbprintf("write- Blk: %d, d:%08X",i-1,blockdata[i-1]);
+               T55xxWriteBlockExt(blockdata[i-1],i-1,0,0);
+       }
 }
 
-/*-------------- Cloning routines -----------*/
 // Copy HID id to card and setup block 0 config
-void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
-{
-       int data1=0, data2=0, data3=0, data4=0, data5=0, data6=0; //up to six blocks for long format
-       int last_block = 0;
+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){
+       if (longFMT) {
                // Ensure no more than 84 bits supplied
                if (hi2>0xFFFFF) {
                        DbpString("Tags can only have 84 bits.");
@@ -1300,140 +1288,91 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT)
                }
                // Build the 6 data blocks for supplied 84bit ID
                last_block = 6;
-               data1 = 0x1D96A900; // load preamble (1D) & long format identifier (9E manchester encoded)
-               for (int i=0;i<4;i++) {
-                       if (hi2 & (1<<(19-i)))
-                               data1 |= (1<<(((3-i)*2)+1)); // 1 -> 10
-                       else
-                               data1 |= (1<<((3-i)*2)); // 0 -> 01
-               }
-
-               data2 = 0;
-               for (int i=0;i<16;i++) {
-                       if (hi2 & (1<<(15-i)))
-                               data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10
-                       else
-                               data2 |= (1<<((15-i)*2)); // 0 -> 01
-               }
-
-               data3 = 0;
-               for (int i=0;i<16;i++) {
-                       if (hi & (1<<(31-i)))
-                               data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
-                       else
-                               data3 |= (1<<((15-i)*2)); // 0 -> 01
-               }
-
-               data4 = 0;
-               for (int i=0;i<16;i++) {
-                       if (hi & (1<<(15-i)))
-                               data4 |= (1<<(((15-i)*2)+1)); // 1 -> 10
-                       else
-                               data4 |= (1<<((15-i)*2)); // 0 -> 01
-               }
-
-               data5 = 0;
-               for (int i=0;i<16;i++) {
-                       if (lo & (1<<(31-i)))
-                               data5 |= (1<<(((15-i)*2)+1)); // 1 -> 10
-                       else
-                               data5 |= (1<<((15-i)*2)); // 0 -> 01
-               }
-
-               data6 = 0;
-               for (int i=0;i<16;i++) {
-                       if (lo & (1<<(15-i)))
-                               data6 |= (1<<(((15-i)*2)+1)); // 1 -> 10
-                       else
-                               data6 |= (1<<((15-i)*2)); // 0 -> 01
-               }
-       }
-       else {
+               // load preamble (1D) & long format identifier (9E manchester encoded)
+               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);
+               data[4] = manchesterEncode2Bytes(hi & 0xFFFF);
+               data[5] = manchesterEncode2Bytes(lo >> 16);
+               data[6] = manchesterEncode2Bytes(lo & 0xFFFF);
+       }       else {
                // Ensure no more than 44 bits supplied
                if (hi>0xFFF) {
                        DbpString("Tags can only have 44 bits.");
                        return;
                }
-
                // Build the 3 data blocks for supplied 44bit ID
                last_block = 3;
-
-               data1 = 0x1D000000; // load preamble
-
-               for (int i=0;i<12;i++) {
-                       if (hi & (1<<(11-i)))
-                               data1 |= (1<<(((11-i)*2)+1)); // 1 -> 10
-                       else
-                               data1 |= (1<<((11-i)*2)); // 0 -> 01
-               }
-
-               data2 = 0;
-               for (int i=0;i<16;i++) {
-                       if (lo & (1<<(31-i)))
-                               data2 |= (1<<(((15-i)*2)+1)); // 1 -> 10
-                       else
-                               data2 |= (1<<((15-i)*2)); // 0 -> 01
-               }
-
-               data3 = 0;
-               for (int i=0;i<16;i++) {
-                       if (lo & (1<<(15-i)))
-                               data3 |= (1<<(((15-i)*2)+1)); // 1 -> 10
-                       else
-                               data3 |= (1<<((15-i)*2)); // 0 -> 01
-               }
+               // load preamble
+               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
-       T55xxWriteBlock(data1,1,0,0);
-       T55xxWriteBlock(data2,2,0,0);
-       T55xxWriteBlock(data3,3,0,0);
-
-       if (longFMT) { // if long format there are 6 blocks
-               T55xxWriteBlock(data4,4,0,0);
-               T55xxWriteBlock(data5,5,0,0);
-               T55xxWriteBlock(data6,6,0,0);
-       }
-
-       // Config for HID (RF/50, FSK2a, Maxblock=3 for short/6 for long)
-       T55xxWriteBlock(T55x7_BITRATE_RF_50    |
-                                       T55x7_MODULATION_FSK2a |
-                                       last_block << T55x7_MAXBLOCK_SHIFT,
-                                       0,0,0);
+       WriteT55xx(data, 0, last_block+1);
 
        LED_D_OFF();
 
        DbpString("DONE!");
 }
 
-void CopyIOtoT55x7(uint32_t hi, uint32_t lo, uint8_t longFMT)
-{
-       int data1=0, data2=0; //up to six blocks for long format
-
-       data1 = hi;  // load preamble
-       data2 = lo;
+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
-       // and the block 0 for HID format
-       T55xxWriteBlock(data1,1,0,0);
-       T55xxWriteBlock(data2,2,0,0);
+       // and the block 0 config
+       WriteT55xx(data, 0, 3);
 
-       //Config Block
-       T55xxWriteBlock(0x00147040,0,0,0);
        LED_D_OFF();
 
        DbpString("DONE!");
 }
 
+// Clone Indala 64-bit tag by UID to T55x7
+void CopyIndala64toT55x7(uint32_t hi, uint32_t lo) {
+       //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) {
+       //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!");
+}
+
 // Define 9bit header for EM410x tags
-#define EM410X_HEADER          0x1FF
+#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
@@ -1493,363 +1432,30 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo)
        LED_D_ON();
 
        // Write EM410x ID
-       T55xxWriteBlock((uint32_t)(id >> 32), 1, 0, 0);
-       T55xxWriteBlock((uint32_t)id, 2, 0, 0);
-
-       // Config for EM410x (RF/64, Manchester, Maxblock=2)
-       if (card) {
-               // Clock rate is stored in bits 8-15 of the card value
-               clock = (card & 0xFF00) >> 8;
-               Dbprintf("Clock rate: %d", clock);
-               switch (clock)
-               {
-               case 32:
-                       clock = T55x7_BITRATE_RF_32;
-                       break;
-               case 16:
-                       clock = T55x7_BITRATE_RF_16;
-                       break;
-               case 0:
-                       // A value of 0 is assumed to be 64 for backwards-compatibility
-                       // Fall through...
-               case 64:
-                       clock = T55x7_BITRATE_RF_64;
-                       break;
-               default:
+       uint32_t data[] = {0, 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;
                }
-
-               // Writing configuration for T55x7 tag
-               T55xxWriteBlock(clock       |
-                                               T55x7_MODULATION_MANCHESTER |
-                                               2 << T55x7_MAXBLOCK_SHIFT,
-                                               0, 0, 0);
+               data[0] = clock | T55x7_MODULATION_MANCHESTER | (2 << T55x7_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);
        }
-       else
-               // Writing configuration for T5555(Q5) tag
-               T55xxWriteBlock(0x1F << T5555_BITRATE_SHIFT |
-                                               T5555_MODULATION_MANCHESTER |
-                                               2 << T5555_MAXBLOCK_SHIFT,
-                                               0, 0, 0);
+
+       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);
 }
 
-// Clone Indala 64-bit tag by UID to T55x7
-void CopyIndala64toT55x7(int hi, int lo)
-{
-
-       //Program the 2 data blocks for supplied 64bit UID
-       // and the block 0 for Indala64 format
-       T55xxWriteBlock(hi,1,0,0);
-       T55xxWriteBlock(lo,2,0,0);
-       //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=2)
-       T55xxWriteBlock(T55x7_BITRATE_RF_32    |
-                                       T55x7_MODULATION_PSK1 |
-                                       2 << T55x7_MAXBLOCK_SHIFT,
-                                       0, 0, 0);
-       //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
-       //      T5567WriteBlock(0x603E1042,0);
-
-       DbpString("DONE!");
-
-}
-
-void CopyIndala224toT55x7(int uid1, int uid2, int uid3, int uid4, int uid5, int uid6, int uid7)
-{
-
-       //Program the 7 data blocks for supplied 224bit UID
-       // and the block 0 for Indala224 format
-       T55xxWriteBlock(uid1,1,0,0);
-       T55xxWriteBlock(uid2,2,0,0);
-       T55xxWriteBlock(uid3,3,0,0);
-       T55xxWriteBlock(uid4,4,0,0);
-       T55xxWriteBlock(uid5,5,0,0);
-       T55xxWriteBlock(uid6,6,0,0);
-       T55xxWriteBlock(uid7,7,0,0);
-       //Config for Indala (RF/32;PSK1 with RF/2;Maxblock=7)
-       T55xxWriteBlock(T55x7_BITRATE_RF_32    |
-                                       T55x7_MODULATION_PSK1 |
-                                       7 << T55x7_MAXBLOCK_SHIFT,
-                                       0,0,0);
-       //Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=7;Inverse data)
-       //      T5567WriteBlock(0x603E10E2,0);
-
-       DbpString("DONE!");
-
-}
-
-
-#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);
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
-
-       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
 //-----------------------------------
@@ -1961,14 +1567,8 @@ void SendForward(uint8_t fwd_bit_count) {
 
        LED_D_ON();
 
-       //Field on
-       FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
-       FpgaSendCommand(FPGA_CMD_SET_DIVISOR, 95); //125Khz
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
-
-       // Give it a bit of time for the resonant antenna to settle.
-       // And for the tag to fully power up
-       SpinDelay(150);
+       // Set up FPGA, 125kHz
+       LFSetupFPGAForADC(95, true);
 
        // force 1st mod pulse (start gap must be longer for 4305)
        fwd_bit_sz--; //prepare next bit modulation
@@ -2013,7 +1613,11 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
 
        uint8_t fwd_bit_count;
        uint8_t *dest = BigBuf_get_addr();
-       int m=0, i=0;
+       uint16_t bufferlength = BigBuf_max_traceLen();
+       uint32_t i = 0;
+
+       // Clear destination buffer before sending the command
+       memset(dest, 0x80, bufferlength);
 
        //If password mode do login
        if (PwdMode == 1) EM4xLogin(Pwd);
@@ -2022,9 +1626,6 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
        fwd_bit_count = Prepare_Cmd( FWD_CMD_READ );
        fwd_bit_count += Prepare_Addr( Address );
 
-       m = BigBuf_max_traceLen();
-       // Clear destination buffer before sending the command
-       memset(dest, 128, m);
        // 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.
@@ -2041,10 +1642,11 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
                if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
                        dest[i] = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
                        i++;
-                       if (i >= m) break;
+                       if (i >= bufferlength) break;
                }
        }
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
+       cmd_send(CMD_ACK,0,0,0,0,0);
        LED_D_OFF();
 }
 
@@ -2067,261 +1669,3 @@ void EM4xWriteWord(uint32_t Data, uint8_t Address, uint32_t Pwd, uint8_t PwdMode
        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
index 6e78376986daa167079608c83b2189d4c528ea42..115d4b18ffaba74ef9c5da113cabb5444679375b 100644 (file)
@@ -103,7 +103,6 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
        FpgaSetupSsc();
 }
 
-
 /**
  * Does the sample acquisition. If threshold is specified, the actual sampling
  * is not commenced until the threshold has been reached.
@@ -154,9 +153,6 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
                        if ((trigger_threshold > 0) && (sample < (trigger_threshold+128)) && (sample > (128-trigger_threshold))) // 
                                continue;
                
-                       //if (trigger_threshold > 0 && sample < trigger_threshold) // 
-                               //continue;
-
                        trigger_threshold = 0;
                        sample_total_numbers++;
 
@@ -252,3 +248,59 @@ uint32_t SnoopLF()
 {
        return ReadLF(false, true);
 }
+
+/**
+* acquisition of T55x7 LF signal. Similart to other LF, but adjusted with @marshmellows thresholds
+* the data is collected in BigBuf.
+**/
+void doT55x7Acquisition(size_t sample_size) {
+
+       #define T55xx_READ_UPPER_THRESHOLD 128+40  // 40 grph
+       #define T55xx_READ_TOL   5
+
+       uint8_t *dest = BigBuf_get_addr();
+       uint16_t bufsize = BigBuf_max_traceLen();
+       
+       if ( bufsize > sample_size )
+               bufsize = sample_size;
+
+       uint16_t i = 0;
+       bool startFound = false;
+       bool highFound = false;
+       uint8_t curSample = 0;
+       uint8_t firstSample = 0;
+       uint16_t skipCnt = 0;
+       while(!BUTTON_PRESS() && skipCnt<1000) {
+               WDT_HIT();
+               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) {
+                       curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
+                       LED_D_OFF();
+
+                       // skip until the first high sample above threshold
+                       if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) {
+                               if (curSample > firstSample) 
+                                       firstSample = curSample;
+                               highFound = true;
+                       } else if (!highFound) {
+                               skipCnt++;
+                               continue;
+                       }
+
+                       // skip until first high samples begin to change
+                       if (startFound || curSample < firstSample-T55xx_READ_TOL){
+                               // if just found start - recover last sample
+                               if (!startFound) {
+                                       dest[i++] = firstSample;
+                                       startFound = true;
+                               }
+                               // collect samples
+                               dest[i++] = curSample;
+                               if (i >= bufsize-1) break;
+                       }
+               }
+       }
+}
index 7d3925cddfff0d70e7032da25b3284276abd3e0d..bd8ad1d0833c33de6d53d448bf6ec8a70eb174d4 100644 (file)
@@ -1,6 +1,12 @@
 #ifndef LFSAMPLING_H
 #define LFSAMPLING_H
 
+/**
+* acquisition of T55x7 LF signal. Similart to other LF, but adjusted with @marshmellows thresholds
+* the data is collected in BigBuf.
+**/
+void doT55x7Acquisition(size_t sample_size);
+
 /**
 * Initializes the FPGA for reader-mode (field on), and acquires the samples.
 * @return number of bits sampled
@@ -41,7 +47,6 @@ uint32_t DoAcquisition_config( bool silent);
 **/
 void LFSetupFPGAForADC(int divisor, bool lf_field);
 
-
 /**
  * Called from the USB-handler to set the sampling configuration
  * The sampling config is used for std reading and snooping.
diff --git a/armsrc/pcf7931.c b/armsrc/pcf7931.c
new file mode 100644 (file)
index 0000000..3093a5e
--- /dev/null
@@ -0,0 +1,526 @@
+#include "proxmark3.h"
+#include "apps.h"
+#include "lfsampling.h"
+#include "pcf7931.h"
+#include "string.h"
+
+#define T0_PCF 8 //period for the pcf7931 in us
+#define ALLOC 16
+
+#define abs(x) ( ((x)<0) ? -(x) : (x) )
+#define max(x,y) ( x<y ? y:x)
+
+int DemodPCF7931(uint8_t **outBlocks) {
+
+    uint8_t bits[256] = {0x00};
+       uint8_t blocks[8][16];
+    uint8_t *dest = BigBuf_get_addr();
+    
+       int GraphTraceLen = BigBuf_max_traceLen();
+       if (  GraphTraceLen > 18000 )
+               GraphTraceLen = 18000;
+       
+       
+       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, true);
+
+       lmin = 64;
+       lmax = 192;
+
+       i = 2;
+
+       /* Find first local max/min */
+    if(dest[1] > dest[0]) {
+               while(i < GraphTraceLen) {
+            if( !(dest[i] > dest[i-1]) && dest[i] > lmax)
+                               break;
+                       i++;
+               }
+               dir = 0;
+       }
+       else {
+               while(i < GraphTraceLen) {
+            if( !(dest[i] < dest[i-1]) && dest[i] < lmin)
+                               break;
+                       i++;
+               }
+               dir = 1;
+       }
+
+       lastval = i++;
+       half_switch = 0;
+       pmc = 0;
+       block_done = 0;
+
+       for (bitidx = 0; i < GraphTraceLen; i++)
+       {
+        if ( (dest[i-1] > dest[i] && dir == 1 && dest[i] > lmax) || (dest[i-1] < dest[i] && dir == 0 && dest[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) {
+                    bits[bitidx++] = 0;
+                                       half_switch = 0;
+                               }
+                               else
+                                       half_switch++;
+                       } else if (abs(lc-clock) < tolerance) {
+                               // 64TO
+                bits[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*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++;
+                               }
+                               bitidx = 0;
+                               block_done = 0;
+                               half_switch = 0;
+                       }
+                       if(i < GraphTraceLen)
+                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);
+       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;
+}
+
+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("-----------------------------------------");
+
+       cmd_send(CMD_ACK,0,0,0,0,0);
+}
+
+
+/* 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;
+}
diff --git a/armsrc/pcf7931.h b/armsrc/pcf7931.h
new file mode 100644 (file)
index 0000000..26aaff6
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef __PCF7931_H
+#define __PCF7931_H
+
+int DemodPCF7931(uint8_t **outBlocks);
+int IsBlock0PCF7931(uint8_t *Block);
+int IsBlock1PCF7931(uint8_t *Block);
+void ReadPCF7931();
+void SendCmdPCF7931(uint32_t * tab);
+bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p);
+bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p);
+bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab);
+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);
+
+#endif
index 22da18053c4f80b35e899dbf029c67454e43111a..580352780720f8ce12f71885477b04ad3e312293 100644 (file)
@@ -637,6 +637,32 @@ int CmdG_Prox_II_Demod(const char *Cmd)
        return 1;
 }
 
+//by marshmellow
+//see ASKDemod for what args are accepted
+int CmdVikingDemod(const char *Cmd)
+{
+       if (!ASKDemod(Cmd, false, false, 1)) {
+               if (g_debugMode) PrintAndLog("ASKDemod failed");
+               return 0;
+       }
+       size_t size = DemodBufferLen;
+       //call lfdemod.c demod for gProxII
+       int ans = VikingDemod_AM(DemodBuffer, &size);
+       if (ans < 0) {
+               if (g_debugMode) PrintAndLog("Error Viking_Demod %d", ans);
+               return 0;
+       }
+       //got a good demod
+       uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32);
+       uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
+       uint32_t cardid = bytebits_to_byte(DemodBuffer+ans+24, 32);
+       uint8_t checksum = bytebits_to_byte(DemodBuffer+ans+32+24, 8);
+       PrintAndLog("Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum);
+       PrintAndLog("Raw: %08X%08X", raw1,raw2);
+       setDemodBuf(DemodBuffer+ans, 64, 0);
+       return 1;
+}
+
 //by marshmellow - see ASKDemod
 int Cmdaskrawdemod(const char *Cmd)
 {
@@ -1130,8 +1156,6 @@ int CmdFSKdemodParadox(const char *Cmd)
 //print ioprox ID and some format details
 int CmdFSKdemodIO(const char *Cmd)
 {
-       //raw fsk demod no manchester decoding no start bit finding just get binary from wave
-       //set defaults
        int idx=0;
        //something in graphbuffer?
        if (GraphTraceLen < 65) {
@@ -1220,11 +1244,6 @@ int CmdFSKdemodIO(const char *Cmd)
 //print full AWID Prox ID and some bit format details if found
 int CmdFSKdemodAWID(const char *Cmd)
 {
-
-       //int verbose=1;
-       //sscanf(Cmd, "%i", &verbose);
-
-       //raw fsk demod no manchester decoding no start bit finding just get binary from wave
        uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
        size_t size = getFromGraphBuf(BitStream);
        if (size==0) return 0;
@@ -1423,7 +1442,6 @@ int CmdFSKdemodPyramid(const char *Cmd)
        uint32_t fc = 0;
        uint32_t cardnum = 0;
        uint32_t code1 = 0;
-       //uint32_t code2 = 0;
        if (fmtLen==26){
                fc = bytebits_to_byte(BitStream+73, 8);
                cardnum = bytebits_to_byte(BitStream+81, 16);
@@ -1597,61 +1615,33 @@ int CmdIndalaDecode(const char *Cmd)
                return 0;
        }
        uint8_t invert=0;
-       ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert);
-       if (ans < 1) {
+       size_t size = DemodBufferLen;
+       size_t startIdx = indala26decode(DemodBuffer, &size, &invert);
+       if (startIdx < 1) {
                if (g_debugMode==1)
                        PrintAndLog("Error2: %d",ans);
                return -1;
        }
-       char showbits[251]={0x00};
+       setDemodBuf(DemodBuffer, size, startIdx);
        if (invert)
                if (g_debugMode==1)
                        PrintAndLog("Had to invert bits");
 
+       PrintAndLog("BitLen: %d",DemodBufferLen);
        //convert UID to HEX
        uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
-       int idx;
-       uid1=0;
-       uid2=0;
-       PrintAndLog("BitLen: %d",DemodBufferLen);
-       if (DemodBufferLen==64){
-               for( idx=0; idx<64; idx++) {
-                       uid1=(uid1<<1)|(uid2>>31);
-                       if (DemodBuffer[idx] == 0) {
-                               uid2=(uid2<<1)|0;
-                               showbits[idx]='0';
-                       } else {
-                               uid2=(uid2<<1)|1;
-                               showbits[idx]='1';
-                       }
-               }
-               showbits[idx]='\0';
-               PrintAndLog("Indala UID=%s (%x%08x)", showbits, uid1, uid2);
-       }
-       else {
-               uid3=0;
-               uid4=0;
-               uid5=0;
-               uid6=0;
-               uid7=0;
-               for( idx=0; idx<DemodBufferLen; idx++) {
-                       uid1=(uid1<<1)|(uid2>>31);
-                       uid2=(uid2<<1)|(uid3>>31);
-                       uid3=(uid3<<1)|(uid4>>31);
-                       uid4=(uid4<<1)|(uid5>>31);
-                       uid5=(uid5<<1)|(uid6>>31);
-                       uid6=(uid6<<1)|(uid7>>31);
-                       if (DemodBuffer[idx] == 0) {
-                               uid7=(uid7<<1)|0;
-                               showbits[idx]='0';
-                       }
-                       else {
-                               uid7=(uid7<<1)|1;
-                               showbits[idx]='1';
-                       }
-               }
-               showbits[idx]='\0';
-               PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
+       uid1=bytebits_to_byte(DemodBuffer,32);
+       uid2=bytebits_to_byte(DemodBuffer+32,32);
+       if (DemodBufferLen==64) {
+               PrintAndLog("Indala UID=%s (%x%08x)", sprint_bin(DemodBuffer,DemodBufferLen), uid1, uid2);
+       } else {
+               uid3=bytebits_to_byte(DemodBuffer+64,32);
+               uid4=bytebits_to_byte(DemodBuffer+96,32);
+               uid5=bytebits_to_byte(DemodBuffer+128,32);
+               uid6=bytebits_to_byte(DemodBuffer+160,32);
+               uid7=bytebits_to_byte(DemodBuffer+192,32);
+               PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", 
+                   sprint_bin(DemodBuffer,DemodBufferLen), uid1, uid2, uid3, uid4, uid5, uid6, uid7);
        }
        if (g_debugMode){
                PrintAndLog("DEBUG: printing demodbuffer:");
@@ -2353,6 +2343,7 @@ static command_t CommandTable[] =
        {"askedgedetect",   CmdAskEdgeDetect,   1, "[threshold] Adjust Graph for manual ask demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)"},
        {"askem410xdemod",  CmdAskEM410xDemod,  1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
        {"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
+       {"askvikingdemod",  CmdVikingDemod,     1, "Demodulate a Viking tag from GraphBuffer"},
        {"autocorr",        CmdAutoCorr,        1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
        {"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
        {"bin2hex",         Cmdbin2hex,         1, "bin2hex <digits>     -- Converts binary to hexadecimal"},
index fcc51a6bee079068127950e46a2fde9dd9edf3bf..c3303c54c25ce0c269e22523b7953fd5a1308ea2 100644 (file)
@@ -17,6 +17,7 @@ int CmdData(const char *Cmd);
 void printDemodBuff(void);
 void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
 int CmdAskEM410xDemod(const char *Cmd);
+int CmdVikingDemod(const char *Cmd);
 int CmdG_Prox_II_Demod(const char *Cmd);
 int Cmdaskrawdemod(const char *Cmd);
 int Cmdaskmandemod(const char *Cmd);
index cba179ec75cf55ae03a268525f0b0d1d00afb002..81716db32c4e5d3842fe634af7b23c1b1884991f 100644 (file)
@@ -352,16 +352,16 @@ int CmdHF14AReader(const char *Cmd)
                                                PrintAndLog("                     x0 -> <1 kByte");
                                                break;
                                        case 0x01:
-                                               PrintAndLog("                     x0 -> 1 kByte");
+                                               PrintAndLog("                     x1 -> 1 kByte");
                                                break;
                                        case 0x02:
-                                               PrintAndLog("                     x0 -> 2 kByte");
+                                               PrintAndLog("                     x2 -> 2 kByte");
                                                break;
                                        case 0x03:
-                                               PrintAndLog("                     x0 -> 4 kByte");
+                                               PrintAndLog("                     x3 -> 4 kByte");
                                                break;
                                        case 0x04:
-                                               PrintAndLog("                     x0 -> 8 kByte");
+                                               PrintAndLog("                     x4 -> 8 kByte");
                                                break;
                                }
                                switch (card.ats[pos + 3] & 0xf0) {
index edf6c3a9eb689a24f158d319e33f013a1b4cdcc3..616d932a25251aa46cf2fc3bee614b4702bb7675 100644 (file)
 
 static int CmdHelp(const char *Cmd);
 
+
+
+int usage_lf_cmdread()
+{
+       PrintAndLog("Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes> [H] ");
+       PrintAndLog("Options:        ");
+       PrintAndLog("       h             This help");
+       PrintAndLog("       L             Low frequency (125 KHz)");
+       PrintAndLog("       H             High frequency (134 KHz)");
+       PrintAndLog("       d <delay>     delay OFF period");
+       PrintAndLog("       z <zero>      time period ZERO");
+       PrintAndLog("       o <one>       time period ONE");
+       PrintAndLog("       c <cmd>       Command bytes");
+       PrintAndLog("       ************* All periods in microseconds");
+       PrintAndLog("Examples:");
+       PrintAndLog("      lf cmdread d 80 z 100 o 200 c 11000");
+       PrintAndLog("      lf cmdread d 80 z 100 o 100 c 11000 H");
+       return 0;
+}
+
 /* send a command before reading */
 int CmdLFCommandRead(const char *Cmd)
 {
-       static char dummy[3];
-
-       dummy[0]= ' ';
-
+       static char dummy[3] = {0x20,0x00,0x00};
        UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
-       sscanf(Cmd, "%"lli" %"lli" %"lli" %s %s", &c.arg[0], &c.arg[1], &c.arg[2],(char*)(&c.d.asBytes),(char*)(&dummy+1));
-       // in case they specified 'h'
+       bool errors = FALSE;
+       //uint8_t divisor = 95; //125khz
+       uint8_t cmdp = 0;
+       int strLength = 0;
+       while(param_getchar(Cmd, cmdp) != 0x00)
+       {
+               switch(param_getchar(Cmd, cmdp))
+               {
+               case 'h':
+                       return usage_lf_cmdread();
+               case 'H':
+                       //divisor = 88;
+                       dummy[1]='h';
+                       cmdp++;
+                       break;
+               case 'L':
+                       cmdp++;
+                       break;
+               case 'c':
+                       strLength = param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes);
+                       cmdp+=2;
+                       break;
+               case 'd':
+                       c.arg[0] = param_get32ex(Cmd, cmdp+1, 0, 10);
+                       cmdp+=2;
+                       break;
+               case 'z':
+                       c.arg[1] = param_get32ex(Cmd, cmdp+1, 0, 10);
+                       cmdp+=2;
+                       break;
+               case 'o':
+                       c.arg[2] = param_get32ex(Cmd, cmdp+1, 0, 10);
+                       cmdp+=2;
+                       break;
+               default:
+                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+                       errors = 1;
+                       break;
+               }
+               if(errors) break;
+       }
+       // No args
+       if(cmdp == 0) errors = 1;
+
+       //Validations
+       if(errors) return usage_lf_cmdread();
+       
+       // in case they specified 'H'
        strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
+
+       clearCommandBuffer();
        SendCommand(&c);
        return 0;
 }
@@ -493,7 +558,12 @@ int CmdLFRead(const char *Cmd)
        //And ship it to device
        UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
        SendCommand(&c);
-       WaitForResponse(CMD_ACK,NULL);
+       //WaitForResponse(CMD_ACK,NULL);        
+       if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
+               PrintAndLog("command execution time out");
+               return 1;
+       }
+
        return 0;
 }
 
@@ -1085,6 +1155,12 @@ int CmdLFfind(const char *Cmd)
                return 1;
        }       
 
+       ans=CmdVikingDemod("");
+       if (ans>0) {
+               PrintAndLog("\nValid Viking ID Found!");
+               return 1;
+       }       
+
        ans=CmdPSKNexWatch("");
        if (ans>0) {
                PrintAndLog("\nValid NexWatch ID Found!");
@@ -1126,13 +1202,17 @@ int CmdLFfind(const char *Cmd)
 static command_t CommandTable[] = 
 {
        {"help",        CmdHelp,            1, "This help"},
-       {"cmdread",     CmdLFCommandRead,   0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"},
+       {"awid",        CmdLFAWID,          1, "{ AWID RFIDs... }"},
        {"em4x",        CmdLFEM4X,          1, "{ EM4X RFIDs... }"},
+       {"hid",         CmdLFHID,           1, "{ HID RFIDs... }"},
+       {"hitag",       CmdLFHitag,         1, "{ Hitag tags and transponders... }"},
+       {"io",          CmdLFIO,            1, "{ ioProx tags... }"},
+       {"pcf7931",     CmdLFPCF7931,       1, "{ PCF7931 RFIDs... }"},
+       {"t55xx",       CmdLFT55XX,         1, "{ T55xx RFIDs... }"},
+       {"ti",          CmdLFTI,            1, "{ TI RFIDs... }"},
+       {"cmdread",     CmdLFCommandRead,   0, "<d period> <z period> <o period> <c command> ['H'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'H' for 134)"},
        {"config",      CmdLFSetConfig,     0, "Set config for LF sampling, bit/sample, decimation, frequency"},
        {"flexdemod",   CmdFlexdemod,       1, "Demodulate samples for FlexPass"},
-       {"hid",         CmdLFHID,           1, "{ HID RFIDs... }"},
-       {"awid",                CmdLFAWID,                  1, "{ AWID RFIDs... }"},
-       {"io",            CmdLFIO,                1, "{ ioProx tags... }"},
        {"indalademod", CmdIndalaDemod,     1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
        {"indalaclone", CmdIndalaClone,     0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
        {"read",        CmdLFRead,          0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
@@ -1143,11 +1223,7 @@ static command_t CommandTable[] =
        {"simpsk",      CmdLFpskSim,        0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] -- Simulate LF PSK tag from demodbuffer or input"},
        {"simbidir",    CmdLFSimBidir,      0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
        {"snoop",       CmdLFSnoop,         0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
-       {"ti",          CmdLFTI,            1, "{ TI RFIDs... }"},
-       {"hitag",       CmdLFHitag,         1, "{ Hitag tags and transponders... }"},
        {"vchdemod",    CmdVchDemod,        1, "['clone'] -- Demodulate samples for VeriChip"},
-       {"t55xx",       CmdLFT55XX,         1, "{ T55xx RFIDs... }"},
-       {"pcf7931",     CmdLFPCF7931,       1, "{PCF7931 RFIDs...}"},
        {NULL, NULL, 0, NULL}
 };
 
index eddeec5604ea68229d68088f409f2193d244259a..7ff8037b5763d3ce6c1aeec2cf4e7fdf1bcebc59 100644 (file)
@@ -73,22 +73,23 @@ int CmdEM410xSim(const char *Cmd)
        uint8_t uid[5] = {0x00};
 
        if (cmdp == 'h' || cmdp == 'H') {
-               PrintAndLog("Usage:  lf em4x 410xsim <UID>");
+               PrintAndLog("Usage:  lf em4x em410xsim <UID> <clock>");
                PrintAndLog("");
-               PrintAndLog("     sample: lf em4x 410xsim 0F0368568B");
+               PrintAndLog("     sample: lf em4x em410xsim 0F0368568B");
                return 0;
        }
+       /* clock is 64 in EM410x tags */
+       uint8_t clock = 64;
 
        if (param_gethex(Cmd, 0, uid, 10)) {
                PrintAndLog("UID must include 10 HEX symbols");
                return 0;
        }
-       
-       PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X", uid[0],uid[1],uid[2],uid[3],uid[4]);
+       param_getdec(Cmd,1, &clock);
+
+       PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X  clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock);
        PrintAndLog("Press pm3-button to about simulation");
 
-       /* clock is 64 in EM410x tags */
-       int clock = 64;
 
        /* clear our graph */
        ClearGraph(0);
@@ -197,21 +198,13 @@ int CmdEM410xWrite(const char *Cmd)
        }
 
        // Check Clock
-       if (card == 1)
-       {
-               // Default: 64
-               if (clock == 0)
-                       clock = 64;
-
-               // Allowed clock rates: 16, 32 and 64
-               if ((clock != 16) && (clock != 32) && (clock != 64)) {
-                       PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32 and 64.\n", clock);
-                       return 0;
-               }
-       }
-       else if (clock != 0)
-       {
-               PrintAndLog("Error! Clock rate is only supported on T55x7 tags.\n");
+       // Default: 64
+       if (clock == 0)
+               clock = 64;
+
+       // Allowed clock rates: 16, 32, 40 and 64
+       if ((clock != 16) && (clock != 32) && (clock != 64) && (clock != 40)) {
+               PrintAndLog("Error! Clock rate %d not valid. Supported clock rates are 16, 32, 40 and 64.\n", clock);
                return 0;
        }
 
@@ -221,11 +214,11 @@ int CmdEM410xWrite(const char *Cmd)
                //   provide for backwards-compatibility for older firmware, and to avoid
                //   having to add another argument to CMD_EM410X_WRITE_TAG, we just store
                //   the clock rate in bits 8-15 of the card value
-               card = (card & 0xFF) | (((uint64_t)clock << 8) & 0xFF00);
-       }
-       else if (card == 0)
+               card = (card & 0xFF) | ((clock << 8) & 0xFF00);
+       }       else if (card == 0) {
                PrintAndLog("Writing %s tag with UID 0x%010" PRIx64, "T5555", id, clock);
-       else {
+               card = (card & 0xFF) | ((clock << 8) & 0xFF00);
+       } else {
                PrintAndLog("Error! Bad card type selected.\n");
                return 0;
        }
@@ -608,7 +601,7 @@ static command_t CommandTable[] =
        {"help", CmdHelp, 1, "This help"},
        {"em410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},  
        {"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag in GraphBuffer"},
-       {"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
+       {"em410xsim", CmdEM410xSim, 0, "<UID> [clock rate] -- Simulate EM410x tag"},
        {"em410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
        {"em410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
        {"em410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
index b1e1ae9eaa47a788257f2ef6c33d25b35e02cc22..ffaf946f48e4c689eaac7d73cb703a3dab1ba04f 100644 (file)
@@ -8,11 +8,11 @@
 //-----------------------------------------------------------------------------
 // Low frequency PCF7931 commands
 //-----------------------------------------------------------------------------
-
 #include <stdio.h>
 #include <string.h>
 #include "proxmark3.h"
 #include "ui.h"
+#include "util.h"
 #include "graph.h"
 #include "cmdparser.h"
 #include "cmddata.h"
 
 static int CmdHelp(const char *Cmd);
 
-struct pcf7931_config configPcf = {{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},17500,{0,0}};
+#define PCF7931_DEFAULT_INITDELAY 17500
+#define PCF7931_DEFAULT_OFFSET_WIDTH 0
+#define PCF7931_DEFAULT_OFFSET_POSITION 0
+
+// Default values - Configuration
+struct pcf7931_config configPcf = {
+       {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
+       PCF7931_DEFAULT_INITDELAY,
+       PCF7931_DEFAULT_OFFSET_WIDTH, 
+       PCF7931_DEFAULT_OFFSET_POSITION
+       };
+
+// Resets the configuration settings to default values.
+int pcf7931_resetConfig(){
+       memset(configPcf.Pwd, 0xFF, sizeof(configPcf.Pwd) );
+       configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY;
+       configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH; 
+       configPcf.OffsetPosition = PCF7931_DEFAULT_OFFSET_POSITION; 
+       return 0;
+}
 
-int CmdLFPCF7931Read(const char *Cmd)
-{
-  UsbCommand c = {CMD_PCF7931_READ};
-  SendCommand(&c);
-  UsbCommand resp;
-  WaitForResponse(CMD_ACK,&resp);
-  return 0;
+int pcf7931_printConfig(){
+       PrintAndLog("Password (LSB first on bytes) : %s", sprint_hex( configPcf.Pwd, sizeof(configPcf.Pwd)));
+       PrintAndLog("Tag initialization delay      : %d us", configPcf.InitDelay);
+       PrintAndLog("Offset low pulses width       : %d us", configPcf.OffsetWidth);
+       PrintAndLog("Offset low pulses position    : %d us", configPcf.OffsetPosition);
+       return 0;
+}
+
+int usage_pcf7931_read(){
+       PrintAndLog("Usage: lf pcf7931 read [h] ");
+       PrintAndLog("This command tries to read a PCF7931 tag.");
+       PrintAndLog("Options:");
+       PrintAndLog("       h   This help");
+       PrintAndLog("Examples:");
+       PrintAndLog("      lf pcf7931 read");
+       return 0;
+}
+
+int usage_pcf7931_write(){
+       PrintAndLog("Usage: lf pcf7931 write [h] <block address> <byte address> <data>");
+       PrintAndLog("This command tries to write a PCF7931 tag.");
+       PrintAndLog("Options:");
+       PrintAndLog("       h          This help");
+       PrintAndLog("       blockaddress   Block to save [0-7]");
+       PrintAndLog("       byteaddress    Index of byte inside block to write [0-15]");
+       PrintAndLog("       data           one byte of data (hex)");
+       PrintAndLog("Examples:");
+       PrintAndLog("      lf pcf7931 write 2 1 FF");
+       return 0;
 }
 
-int CmdLFPCF7931Config(const char *Cmd)
-{ 
-  int res = 0;
-  res = sscanf(Cmd, "%02x %02x %02x %02x %02x %02x %02x %d %d %d", &configPcf.password[0], &configPcf.password[1], &configPcf.password[2], &configPcf.password[3], &configPcf.password[4], &configPcf.password[5], &configPcf.password[6], &configPcf.init_delay, &configPcf.offset[0], &configPcf.offset[1]);
-
-  if (res >= 7 || res < 1){
-      if(res == 7) configPcf.init_delay = 17500; //default value
-      
-      if(res<=8){
-        configPcf.offset[0] = 0; //default value
-        configPcf.offset[1] = 0; //default value
-      }
-     
-      if(res < 1){
-         PrintAndLog("Usage: <password byte 1 (in hex, lsb first)> <password byte 2  (in hex, lsb first)> [...] <password byte 7  (in hex, lsb first)> <tag initialization delay (in us)> <optional : offset on the low pulses width (in us)> <optional : offset on the low pulses position (in us)>");
-         PrintAndLog("The time offsets could be usefull to correct slew rate generated by the antenna.");
-      }
-
-      PrintAndLog("Current configuration :");
-      PrintAndLog("Password (LSB first on each byte) : %02x %02x %02x %02x %02x %02x %02x", configPcf.password[0], configPcf.password[1], configPcf.password[2], configPcf.password[3], configPcf.password[4], configPcf.password[5], configPcf.password[6]);
-      PrintAndLog("Tag initialization delay : %d us", configPcf.init_delay);
-      PrintAndLog("Offsets : %d us on the low pulses width, %d us on the low pulses positions", configPcf.offset[0], configPcf.offset[1]);
-
-      return 0;
-  }
-
-  //default values
-  configPcf.password[0] = 0xFF;  
-  configPcf.password[1] = 0xFF;  
-  configPcf.password[2] = 0xFF;  
-  configPcf.password[3] = 0xFF;  
-  configPcf.password[4] = 0xFF;  
-  configPcf.password[5] = 0xFF;  
-  configPcf.password[6] = 0xFF;
-
-  configPcf.init_delay = 17500;
-  configPcf.offset[0] = 0; 
-  configPcf.offset[1] = 0; 
-
-  PrintAndLog("Incorrect format");
-  PrintAndLog("Examples of right usage : lf pcf7931 config 11 22 33 44 55 66 77 20000");
-  PrintAndLog("                          lf pcf7931 config FF FF FF FF FF FF FF 17500 -10 30");
-  return 0;
+int usage_pcf7931_config(){
+       PrintAndLog("Usage: lf pcf7931 config [h] [r] <pwd> <delay> <offset width> <offset position>");
+       PrintAndLog("This command tries to set the configuration used with PCF7931 commands");
+       PrintAndLog("The time offsets could be useful to correct slew rate generated by the antenna");
+       PrintAndLog("Caling without some parameter will print the current configuration.");
+       PrintAndLog("Options:");
+       PrintAndLog("       h       This help");
+       PrintAndLog("       r       Reset configuration to default values");
+       PrintAndLog("       pwd     Password, hex, 7bytes, LSB-order");
+       PrintAndLog("       delay   Tag initialization delay (in us) decimal");
+       PrintAndLog("       offset  Low pulses width (in us) decimal");
+       PrintAndLog("       offset  Low pulses position (in us) decimal");  
+       PrintAndLog("Examples:");
+       PrintAndLog("      lf pcf7931 config");
+       PrintAndLog("      lf pcf7931 config r");
+       PrintAndLog("      lf pcf7931 config 11223344556677 20000");
+       PrintAndLog("      lf pcf7931 config 11223344556677 17500 -10 30");
+       return 0;
 }
 
+int CmdLFPCF7931Read(const char *Cmd){  
 
+       uint8_t ctmp = param_getchar(Cmd, 0);
+       if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_read();
 
-int CmdLFPCF7931Write(const char *Cmd)
-{
-  UsbCommand c = {CMD_PCF7931_WRITE};
-
-  int res = 0;
-  res = sscanf(Cmd, "%x %x %x", &c.arg[0], &c.arg[1], &c.arg[2]);
-
-  if(res < 1) {
-      PrintAndLog("Please specify the block address in hex");
-      return 0;
-  }
-  if (res == 1){ 
-    PrintAndLog("Please specify the byte address in hex");
-     return 0;
-  }
-  if(res == 2) {
-    PrintAndLog("Please specify the data in hex (1 byte)");
-     return 0;
-  }
-  if(res == 3) {
-    uint8_t n=0;
-    for(n=0;n<7;n++)  c.d.asDwords[n] = configPcf.password[n];
-    c.d.asDwords[7] = (configPcf.offset[0]+128);
-    c.d.asDwords[8] = (configPcf.offset[1]+128);
-    c.d.asDwords[9] = configPcf.init_delay;
-    SendCommand(&c);
-    return 0;
-  }
-
-  PrintAndLog("INCORRECT FORMAT");
-  return 0;
+       UsbCommand resp;
+       UsbCommand c = {CMD_PCF7931_READ, {0, 0, 0}};
+       clearCommandBuffer();
+       SendCommand(&c);
+       if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
+               PrintAndLog("command execution time out");
+               return 1;
+       }
+       return 0;
 }
 
+int CmdLFPCF7931Config(const char *Cmd){ 
+
+       uint8_t ctmp = param_getchar(Cmd, 0);
+       if ( ctmp == 0) return pcf7931_printConfig();
+       if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_config();
+       if ( ctmp == 'R' || ctmp == 'r' ) return pcf7931_resetConfig(); 
+
+       if ( param_gethex(Cmd, 0, configPcf.Pwd, 14) ) return usage_pcf7931_config();
+
+       configPcf.InitDelay = (param_get32ex(Cmd,1,0,10) & 0xFFFF);
+       configPcf.OffsetWidth = (int)(param_get32ex(Cmd,2,0,10) & 0xFFFF);
+       configPcf.OffsetPosition = (int)(param_get32ex(Cmd,3,0,10) & 0xFFFF);
+
+       pcf7931_printConfig();
+       return 0;
+}
+
+int CmdLFPCF7931Write(const char *Cmd){
+
+       uint8_t ctmp = param_getchar(Cmd, 0);
+       if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_write();  
+
+       uint8_t block = 0, bytepos = 0, data = 0;
+       
+       if ( param_getdec(Cmd, 0, &block) ) return usage_pcf7931_write();
+       if ( param_getdec(Cmd, 1, &bytepos) ) return usage_pcf7931_write();
+       
+       if ( (block > 7) || (bytepos > 15) ) return usage_pcf7931_write();
+
+       data  = param_get8ex(Cmd, 2, 0, 16);
+       
+       PrintAndLog("Writing block: %d", block);
+       PrintAndLog("          pos: %d", bytepos);
+       PrintAndLog("         data: 0x%02X", data);
+
+       UsbCommand c = {CMD_PCF7931_WRITE, { block, bytepos, data} };
+       memcpy(c.d.asDwords, configPcf.Pwd, sizeof(configPcf.Pwd) );
+         c.d.asDwords[7] = (configPcf.OffsetWidth + 128);
+         c.d.asDwords[8] = (configPcf.OffsetPosition + 128);
+         c.d.asDwords[9] = configPcf.InitDelay;
+
+       clearCommandBuffer();
+       SendCommand(&c);
+       //no ack?
+       return 0;
+}
 
 static command_t CommandTable[] = 
 {
-  {"help", CmdHelp, 1, "This help"},
-  {"read", CmdLFPCF7931Read, 1, "Read content of a PCF7931 transponder"},
-  {"write", CmdLFPCF7931Write, 1, "Write data on a PCF7931 transponder. Usage : lf pcf7931 write <bloc address> <byte address> <data>"},
-   {"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"},
-  {NULL, NULL, 0, NULL}
+       {"help",   CmdHelp,            1, "This help"},
+       {"read",   CmdLFPCF7931Read,   0, "Read content of a PCF7931 transponder"},
+       {"write",  CmdLFPCF7931Write,  0, "Write data on a PCF7931 transponder."},
+       {"config", CmdLFPCF7931Config, 1, "Configure the password, the tags initialization delay and time offsets (optional)"},
+       {NULL,     NULL,               0, NULL}
 };
 
 int CmdLFPCF7931(const char *Cmd)
 {
-  CmdsParse(CommandTable, Cmd);
-  return 0;
+       CmdsParse(CommandTable, Cmd);
+       return 0;
 }
 
 int CmdHelp(const char *Cmd)
 {
-  CmdsHelp(CommandTable);
-  return 0;
+       CmdsHelp(CommandTable);
+       return 0;
 }
index 78eaff5d28080f3dd90e57aa296211623d5257b4..e093039c98726988d57815488ab3185d2a8b79c7 100644 (file)
 #define CMDLFPCF7931_H__
 
 struct pcf7931_config{
-       uint8_t password[7];
-       uint16_t init_delay;
-       int16_t offset[2];
+       uint8_t Pwd[7];
+       uint16_t InitDelay;
+       int16_t OffsetWidth;
+       int16_t OffsetPosition;
 };
 
+int pcf7931_resetConfig();
+int pcf7931_printConfig();
+
+int usage_pcf7931_read();
+int usage_pcf7931_write();
+int usage_pcf7931_config();
+
 int CmdLFPCF7931(const char *Cmd);
 
 int CmdLFPCF7931Read(const char *Cmd);
-
 int CmdLFPCF7931Write(const char *Cmd);
-
 int CmdLFPCF7931Config(const char *Cmd);
 
 #endif
index 887547248abe6e3945a4f6153bbcd493972d0e93..55b4ab65284a8f921f9199fa31f4bce894f810ac 100644 (file)
 \r
 #define CONFIGURATION_BLOCK 0x00\r
 #define TRACE_BLOCK 0x01\r
+#define REGULAR_READ_MODE_BLOCK 0xFF\r
 \r
 // Default configuration\r
 t55xx_conf_block_t config = { .modulation = DEMOD_ASK, .inverted = FALSE, .offset = 0x00, .block0 = 0x00};\r
 \r
+t55xx_conf_block_t Get_t55xx_Config(){\r
+       return config;\r
+}\r
+void Set_t55xx_Config(t55xx_conf_block_t conf){\r
+       config = conf;\r
+}\r
+\r
 int usage_t55xx_config(){\r
        PrintAndLog("Usage: lf t55xx config [d <demodulation>] [i 1] [o <offset>]");\r
-       PrintAndLog("Options:        ");\r
+       PrintAndLog("Options:");\r
        PrintAndLog("       h                        This help");\r
        PrintAndLog("       b <8|16|32|40|50|64|100|128>     Set bitrate");\r
        PrintAndLog("       d <FSK|FSK1|FSK1a|FSK2|FSK2a|ASK|PSK1|PSK2|NRZ|BI|BIa>  Set demodulation FSK / ASK / PSK / NRZ / Biphase / Biphase A");\r
@@ -49,31 +57,41 @@ int usage_t55xx_config(){
        return 0;\r
 }\r
 int usage_t55xx_read(){\r
-       PrintAndLog("Usage:  lf t55xx read <block> <password>");\r
-       PrintAndLog("     <block>, block number to read. Between 0-7");\r
-       PrintAndLog("     <password>, OPTIONAL password (8 hex characters)");\r
+       PrintAndLog("Usage:  lf t55xx read [b <block>] [p <password>] <override_safety> <page1>");\r
+       PrintAndLog("Options:");\r
+       PrintAndLog("     b <block>    - block number to read. Between 0-7");\r
+       PrintAndLog("     p <password> - OPTIONAL password (8 hex characters)");\r
+       PrintAndLog("     o            - OPTIONAL override safety check");\r
+       PrintAndLog("     1            - OPTIONAL read Page 1 instead of Page 0");\r
+       PrintAndLog("     ****WARNING****");\r
+       PrintAndLog("     Use of read with password on a tag not configured for a pwd");\r
+       PrintAndLog("     can damage the tag");\r
        PrintAndLog("");\r
        PrintAndLog("Examples:");\r
-       PrintAndLog("      lf t55xx read 0           - read data from block 0");\r
-       PrintAndLog("      lf t55xx read 0 feedbeef  - read data from block 0 password feedbeef");\r
+       PrintAndLog("      lf t55xx read b 0              - read data from block 0");\r
+       PrintAndLog("      lf t55xx read b 0 p feedbeef   - read data from block 0 password feedbeef");\r
+       PrintAndLog("      lf t55xx read b 0 p feedbeef o - read data from block 0 password feedbeef safety check");\r
        PrintAndLog("");\r
        return 0;\r
 }\r
 int usage_t55xx_write(){\r
-       PrintAndLog("Usage:  lf t55xx wr <block> <data> [password]");\r
-       PrintAndLog("     <block>, block number to write. Between 0-7");\r
-       PrintAndLog("     <data>,  4 bytes of data to write (8 hex characters)");\r
-       PrintAndLog("     [password], OPTIONAL password 4bytes (8 hex characters)");\r
+       PrintAndLog("Usage:  lf t55xx wr [b <block>] [d <data>] [p <password>] [1]");\r
+       PrintAndLog("Options:");\r
+       PrintAndLog("     b <block>    - block number to write. Between 0-7");\r
+       PrintAndLog("     d <data>     - 4 bytes of data to write (8 hex characters)");\r
+       PrintAndLog("     p <password> - OPTIONAL password 4bytes (8 hex characters)");\r
+       PrintAndLog("     1            - OPTIONAL write Page 1 instead of Page 0");\r
        PrintAndLog("");\r
        PrintAndLog("Examples:");\r
-       PrintAndLog("      lf t55xx wr 3 11223344           - write 11223344 to block 3");\r
-       PrintAndLog("      lf t55xx wr 3 11223344 feedbeef  - write 11223344 to block 3 password feedbeef");\r
+       PrintAndLog("      lf t55xx wr b 3 d 11223344            - write 11223344 to block 3");\r
+       PrintAndLog("      lf t55xx wr b 3 d 11223344 p feedbeef - write 11223344 to block 3 password feedbeef");\r
        PrintAndLog("");\r
        return 0;\r
 }\r
 int usage_t55xx_trace() {\r
        PrintAndLog("Usage:  lf t55xx trace [1]");\r
-       PrintAndLog("     [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
+       PrintAndLog("Options:");\r
+       PrintAndLog("     [graph buffer data]  - if set, use Graphbuffer otherwise read data from tag.");\r
        PrintAndLog("");\r
        PrintAndLog("Examples:");\r
        PrintAndLog("      lf t55xx trace");\r
@@ -83,7 +101,8 @@ int usage_t55xx_trace() {
 }\r
 int usage_t55xx_info() {\r
        PrintAndLog("Usage:  lf t55xx info [1]");\r
-       PrintAndLog("     [graph buffer data], if set, use Graphbuffer otherwise read data from tag.");\r
+       PrintAndLog("Options:");\r
+       PrintAndLog("     [graph buffer data]  - if set, use Graphbuffer otherwise read data from tag.");\r
        PrintAndLog("");\r
        PrintAndLog("Examples:");\r
        PrintAndLog("      lf t55xx info");\r
@@ -92,17 +111,21 @@ int usage_t55xx_info() {
        return 0;\r
 }\r
 int usage_t55xx_dump(){\r
-       PrintAndLog("Usage:  lf t55xx dump <password>");\r
-    PrintAndLog("     <password>, OPTIONAL password 4bytes (8 hex symbols)");\r
+       PrintAndLog("Usage:  lf t55xx dump <password> [o]");\r
+       PrintAndLog("Options:");\r
+       PrintAndLog("     <password>  - OPTIONAL password 4bytes (8 hex symbols)");\r
+       PrintAndLog("     o           - OPTIONAL override, force pwd read despite danger to card");\r
        PrintAndLog("");\r
        PrintAndLog("Examples:");\r
        PrintAndLog("      lf t55xx dump");\r
-       PrintAndLog("      lf t55xx dump feedbeef");\r
+       PrintAndLog("      lf t55xx dump feedbeef o");\r
        PrintAndLog("");\r
        return 0;\r
 }\r
 int usage_t55xx_detect(){\r
-       PrintAndLog("Usage:  lf t55xx detect");\r
+       PrintAndLog("Usage:  lf t55xx detect [1]");\r
+       PrintAndLog("Options:");\r
+       PrintAndLog("     [graph buffer data]  - if set, use Graphbuffer otherwise read data from tag.");\r
        PrintAndLog("");\r
        PrintAndLog("Examples:");\r
        PrintAndLog("      lf t55xx detect");\r
@@ -110,18 +133,29 @@ int usage_t55xx_detect(){
        PrintAndLog("");\r
        return 0;\r
 }\r
+int usage_t55xx_wakup(){\r
+       PrintAndLog("Usage:  lf t55xx wakeup [h] p <password>");\r
+       PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards.");\r
+       PrintAndLog("Options:");\r
+       PrintAndLog("     h             - this help");\r
+       PrintAndLog("     p <password>  - password 4bytes (8 hex symbols)");\r
+       PrintAndLog("");\r
+       PrintAndLog("Examples:");\r
+               PrintAndLog("      lf t55xx wakeup p 11223344  - send wakeup password");\r
+       return 0;\r
+}\r
 \r
 static int CmdHelp(const char *Cmd);\r
 \r
 int CmdT55xxSetConfig(const char *Cmd) {\r
 \r
        uint8_t offset = 0;\r
-       bool errors = FALSE;\r
-       uint8_t cmdp = 0;\r
        char modulation[5] = {0x00};\r
        char tmp = 0x00;\r
        uint8_t bitRate = 0;\r
        uint8_t rates[9] = {8,16,32,40,50,64,100,128,0};\r
+       uint8_t cmdp = 0;\r
+       bool errors = FALSE;\r
        while(param_getchar(Cmd, cmdp) != 0x00 && !errors)\r
        {\r
                tmp = param_getchar(Cmd, cmdp);\r
@@ -201,64 +235,91 @@ int CmdT55xxSetConfig(const char *Cmd) {
        }\r
 \r
        // No args\r
-       if (cmdp == 0) {\r
-               printConfiguration( config );\r
-               return 0;\r
-       }\r
+       if (cmdp == 0) return printConfiguration( config );\r
+\r
        //Validations\r
-       if (errors)\r
-               return usage_t55xx_config();\r
+       if (errors) return usage_t55xx_config();\r
 \r
-       config.block0 = 0;\r
-       printConfiguration ( config );\r
-       return 0;\r
+       config.block0 = 0;\r
+       return printConfiguration ( config );\r
 }\r
 \r
-int CmdT55xxReadBlock(const char *Cmd) {\r
-       int block = -1;\r
-       int password = 0xFFFFFFFF; //default to blank Block 7\r
-\r
-       char cmdp = param_getchar(Cmd, 0);\r
-       if (cmdp == 'h' || cmdp == 'H')\r
-               return usage_t55xx_read();\r
-\r
-       int res = sscanf(Cmd, "%d %x", &block, &password);\r
+int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password){\r
+       //Password mode\r
+       if ( usepwd ) {\r
+               // try reading the config block and verify that PWD bit is set before doing this!\r
+               if ( !override ) {\r
+                       if ( !AquireData(0, CONFIGURATION_BLOCK, false, 0 ) ) return 0;\r
+                       if ( !tryDetectModulation() ) {\r
+                               PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits.");\r
+                               return 0;\r
+                       } else {\r
+                               PrintAndLog("Safety Check: PWD bit is NOT set in config block. Reading without password...");   \r
+                               usepwd = false;\r
+                               page1 = false;\r
+                       }\r
+               } else {\r
+                       PrintAndLog("Safety Check Overriden - proceeding despite risk");\r
+               }\r
+       }\r
 \r
-       if ( res < 1 || res > 2 )\r
-               return usage_t55xx_read();\r
+       if (!AquireData(page1, block, usepwd, password) )       return 0;\r
+       if (!DecodeT55xxBlock()) return 0;\r
 \r
-       \r
-       if ((block < 0) | (block > 7)) {\r
-               PrintAndLog("Block must be between 0 and 7");\r
-               return 1;\r
-       }       \r
-\r
-       UsbCommand c = {CMD_T55XX_READ_BLOCK, {0, block, 0}};\r
-       c.d.asBytes[0] = 0x0; \r
+       char blk[10]={0};\r
+       sprintf(blk,"%d", block);\r
+       printT55xxBlock(blk);   \r
+       return 1;\r
+}\r
 \r
-       //Password mode\r
-       if ( res == 2 ) {\r
-               c.arg[2] = password;\r
-               c.d.asBytes[0] = 0x1; \r
+int CmdT55xxReadBlock(const char *Cmd) {\r
+       uint8_t block = REGULAR_READ_MODE_BLOCK;\r
+       uint32_t password = 0; //default to blank Block 7\r
+       bool usepwd = false;\r
+       bool override = false;\r
+       bool page1 = false;\r
+       bool errors = false;\r
+       uint8_t cmdp = 0;\r
+       while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {\r
+               switch(param_getchar(Cmd, cmdp)) {\r
+               case 'h':\r
+               case 'H':\r
+                       return usage_t55xx_read();\r
+               case 'b':\r
+               case 'B':\r
+                       errors |= param_getdec(Cmd, cmdp+1, &block);\r
+                       cmdp += 2;\r
+                       break;\r
+               case 'o':\r
+               case 'O':\r
+                       override = true;\r
+                       cmdp++;\r
+                       break;\r
+               case 'p':\r
+               case 'P':\r
+                       password = param_get32ex(Cmd, cmdp+1, 0, 16);\r
+                       usepwd = true;\r
+                       cmdp += 2;\r
+                       break;\r
+               case '1':\r
+                       page1 = true;\r
+                       cmdp++;\r
+                       break;\r
+               default:\r
+                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
+                       errors = true;\r
+                       break;\r
+               }\r
        }\r
+       if (errors) return usage_t55xx_read();\r
 \r
-       clearCommandBuffer();\r
-       SendCommand(&c);\r
-       if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
-               PrintAndLog("command execution time out");\r
-               return 2;\r
+       if (block > 7 && block != REGULAR_READ_MODE_BLOCK       ) {\r
+               PrintAndLog("Block must be between 0 and 7");\r
+               return 0;\r
        }\r
-       \r
-       uint8_t got[12000];\r
-       GetFromBigBuf(got,sizeof(got),0);\r
-       WaitForResponse(CMD_ACK,NULL);\r
-       setGraphBuf(got, 12000);\r
-       DemodBufferLen=0;\r
-       if (!DecodeT55xxBlock()) return 3;\r
-       char blk[10]={0};\r
-       sprintf(blk,"%d", block);\r
-       printT55xxBlock(blk);\r
-       return 0;\r
+       PrintAndLog("Reading Page %d:", page1); \r
+       PrintAndLog("blk | hex data | binary");\r
+       return T55xxReadBlock(block, page1, usepwd, override, password);\r
 }\r
 \r
 bool DecodeT55xxBlock(){\r
@@ -269,9 +330,6 @@ bool DecodeT55xxBlock(){
        uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};\r
        DemodBufferLen = 0x00;\r
 \r
-       //trim 1/2 a clock from beginning\r
-       snprintf(cmdStr, sizeof(buf),"%d", bitRate[config.bitrate]/2 );\r
-       CmdLtrim(cmdStr);\r
        switch( config.modulation ){\r
                case DEMOD_FSK:\r
                        snprintf(cmdStr, sizeof(buf),"%d %d", bitRate[config.bitrate], config.inverted );\r
@@ -323,17 +381,17 @@ int CmdT55xxDetect(const char *Cmd){
                return usage_t55xx_detect();\r
        \r
        if (strlen(Cmd)==0)\r
-               AquireData( CONFIGURATION_BLOCK );\r
+               if ( !AquireData(0, CONFIGURATION_BLOCK, false, 0) )\r
+                       return 0;\r
 \r
        if ( !tryDetectModulation() )\r
                PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");\r
 \r
-       return 0;\r
+       return 1;\r
 }\r
 \r
 // detect configuration?\r
 bool tryDetectModulation(){\r
-       char cmdStr[8] = {0};\r
        uint8_t hits = 0;\r
        t55xx_conf_block_t tests[15];\r
        int bitRate=0;\r
@@ -341,8 +399,6 @@ bool tryDetectModulation(){
        save_restoreGB(1);\r
        if (GetFskClock("", FALSE, FALSE)){ \r
                fskClocks(&fc1, &fc2, &clk, FALSE);\r
-               sprintf(cmdStr,"%d", clk/2);\r
-               CmdLtrim(cmdStr);\r
                if ( FSKrawDemod("0 0", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate)){\r
                        tests[hits].modulation = DEMOD_FSK;\r
                        if (fc1==8 && fc2 == 5)\r
@@ -369,8 +425,6 @@ bool tryDetectModulation(){
        } else {\r
                clk = GetAskClock("", FALSE, FALSE);\r
                if (clk>0) {\r
-                       sprintf(cmdStr,"%d", clk/2);\r
-                       CmdLtrim(cmdStr);\r
                        if ( ASKDemod("0 0 0", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate)) {\r
                                tests[hits].modulation = DEMOD_ASK;\r
                                tests[hits].bitrate = bitRate;\r
@@ -404,8 +458,6 @@ bool tryDetectModulation(){
                save_restoreGB(0);\r
                clk = GetNrzClock("", FALSE, FALSE);\r
                if (clk>0) {\r
-                       sprintf(cmdStr,"%d", clk/2);\r
-                       CmdLtrim(cmdStr);\r
                        if ( NRZrawDemod("0 0 1", FALSE)  && test(DEMOD_NRZ, &tests[hits].offset, &bitRate)) {\r
                                tests[hits].modulation = DEMOD_NRZ;\r
                                tests[hits].bitrate = bitRate;\r
@@ -427,9 +479,6 @@ bool tryDetectModulation(){
                save_restoreGB(0);\r
                clk = GetPskClock("", FALSE, FALSE);\r
                if (clk>0) {\r
-                       PrintAndLog("clk %d",clk);\r
-                       sprintf(cmdStr,"%d", clk/2);\r
-                       CmdLtrim(cmdStr);       \r
                        if ( PSKDemod("0 0 1", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate)) {\r
                                tests[hits].modulation = DEMOD_PSK1;\r
                                tests[hits].bitrate = bitRate;\r
@@ -491,7 +540,7 @@ bool tryDetectModulation(){
 bool testModulation(uint8_t mode, uint8_t modread){\r
        switch( mode ){\r
                case DEMOD_FSK:\r
-                       if (modread > 3 && modread < 8) return TRUE;\r
+                       if (modread >= DEMOD_FSK1 && modread <= DEMOD_FSK2a) return TRUE;\r
                        break;\r
                case DEMOD_ASK:\r
                        if (modread == DEMOD_ASK) return TRUE;\r
@@ -615,14 +664,14 @@ void printT55xxBlock(const char *blockNum){
                bits[i - config.offset]=DemodBuffer[i];\r
 \r
        blockData = PackBits(0, 32, bits);\r
-       PrintAndLog("[%s] 0x%08X  %s", blockNum, blockData, sprint_bin(bits,32));\r
+       PrintAndLog("  %s | %08X | %s", blockNum, blockData, sprint_bin(bits,32));\r
 }\r
 \r
 int special(const char *Cmd) {\r
        uint32_t blockData = 0;\r
        uint8_t bits[32] = {0x00};\r
 \r
-       PrintAndLog("[OFFSET] [DATA] [BINARY]");\r
+       PrintAndLog("OFFSET | DATA       | BINARY");\r
        PrintAndLog("----------------------------------------------------");\r
        int i,j = 0;\r
        for (; j < 64; ++j){\r
@@ -632,86 +681,142 @@ int special(const char *Cmd) {
        \r
                blockData = PackBits(0, 32, bits);\r
                \r
-               PrintAndLog("[%02d] 0x%08X  %s",j , blockData, sprint_bin(bits,32));    \r
+               PrintAndLog("    %02d | 0x%08X | %s",j , blockData, sprint_bin(bits,32));       \r
        }\r
        return 0;\r
 }\r
 \r
-void printConfiguration( t55xx_conf_block_t b){\r
+int printConfiguration( t55xx_conf_block_t b){\r
        PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );\r
        PrintAndLog("Bit Rate   : %s", GetBitRateStr(b.bitrate) );\r
        PrintAndLog("Inverted   : %s", (b.inverted) ? "Yes" : "No" );\r
        PrintAndLog("Offset     : %d", b.offset);\r
        PrintAndLog("Block0     : 0x%08X", b.block0);\r
        PrintAndLog("");\r
+       return 0;\r
 }\r
 \r
-int CmdT55xxWriteBlock(const char *Cmd)\r
-{\r
-       int block = 8; //default to invalid block\r
-       int data = 0xFFFFFFFF; //default to blank Block \r
-       int password = 0xFFFFFFFF; //default to blank Block 7\r
-       \r
-       char cmdp = param_getchar(Cmd, 0);\r
-       if (cmdp == 'h' || cmdp == 'H') {\r
-               usage_t55xx_write();\r
-               return 0;\r
+int CmdT55xxWakeUp(const char *Cmd) {\r
+       uint32_t password = 0;\r
+       uint8_t cmdp = 0;\r
+       bool errors = true;\r
+       while(param_getchar(Cmd, cmdp) != 0x00) {\r
+               switch(param_getchar(Cmd, cmdp)) {\r
+               case 'h':\r
+               case 'H':\r
+                       return usage_t55xx_wakup();\r
+               case 'p':\r
+               case 'P':\r
+                       password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16);\r
+                       cmdp += 2;\r
+                       errors = false;\r
+                       break;\r
+               default:\r
+                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
+                       errors = true;\r
+                       break;\r
+               }\r
        }\r
-  \r
-       int res = sscanf(Cmd, "%d %x %x",&block, &data, &password);\r
-       \r
-       if ( res < 2 || res > 3) {\r
-               usage_t55xx_write();\r
-               return 1;\r
+       if (errors) return usage_t55xx_wakup();\r
+\r
+       UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}};\r
+       clearCommandBuffer();\r
+       SendCommand(&c);\r
+       PrintAndLog("Wake up command sent. Try read now");\r
+       return 0;\r
+}\r
+\r
+int CmdT55xxWriteBlock(const char *Cmd) {\r
+       uint8_t block = 0xFF; //default to invalid block\r
+       uint32_t data = 0xFFFFFFFF; //default to blank Block \r
+       uint32_t password = 0xFFFFFFFF; //default to blank Block 7\r
+       bool usepwd = false;\r
+       bool page1 = false;     \r
+       bool gotdata = false;\r
+       bool errors = false;\r
+       uint8_t cmdp = 0;\r
+       while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {\r
+               switch(param_getchar(Cmd, cmdp)) {\r
+               case 'h':\r
+               case 'H':\r
+                       return usage_t55xx_write();\r
+               case 'b':\r
+               case 'B':\r
+                       errors |= param_getdec(Cmd, cmdp+1, &block);\r
+                       cmdp += 2;\r
+                       break;\r
+               case 'd':\r
+               case 'D':\r
+                       data = param_get32ex(Cmd, cmdp+1, 0, 16);\r
+                       gotdata = true;\r
+                       cmdp += 2;\r
+                       break;\r
+               case 'p':\r
+               case 'P':\r
+                       password = param_get32ex(Cmd, cmdp+1, 0, 16);\r
+                       usepwd = true;\r
+                       cmdp += 2;\r
+                       break;\r
+               case '1':\r
+                       page1 = true;\r
+                       cmdp++;\r
+                       break;\r
+               default:\r
+                       PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));\r
+                       errors = true;\r
+                       break;\r
+               }\r
        }\r
+       if (errors || !gotdata) return usage_t55xx_write();\r
 \r
        if (block > 7) {\r
                PrintAndLog("Block number must be between 0 and 7");\r
-               return 1;\r
+               return 0;\r
        }\r
        \r
        UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};\r
        UsbCommand resp;\r
-       c.d.asBytes[0] = 0x0; \r
+       c.d.asBytes[0] = (page1) ? 0x2 : 0; \r
 \r
-       PrintAndLog("Writing to block: %d  data  : 0x%08X", block, data);\r
+       PrintAndLog("Writing to page: %d  block: %d  data : 0x%08X", page1, block, data);\r
 \r
        //Password mode\r
-       if (res == 3) {\r
+       if (usepwd) {\r
                c.arg[2] = password;\r
-               c.d.asBytes[0] = 0x1; \r
+               c.d.asBytes[0] |= 0x1; \r
                PrintAndLog("pwd   : 0x%08X", password);\r
        }\r
        clearCommandBuffer();\r
        SendCommand(&c);\r
        if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){\r
                PrintAndLog("Error occurred, device did not ACK write operation. (May be due to old firmware)");\r
-               return -1;\r
+               return 0;\r
        }\r
-       return 0;\r
+       return 1;\r
 }\r
 \r
-int CmdT55xxReadTrace(const char *Cmd)\r
-{\r
+int CmdT55xxReadTrace(const char *Cmd) {\r
        char cmdp = param_getchar(Cmd, 0);\r
-       \r
+       bool pwdmode = false;\r
+       uint32_t password = 0;\r
        if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H') \r
                return usage_t55xx_trace();\r
 \r
        if (strlen(Cmd)==0)\r
-               AquireData( TRACE_BLOCK );\r
+               if ( !AquireData( TRACE_BLOCK, REGULAR_READ_MODE_BLOCK, pwdmode, password ) )\r
+                       return 0;\r
        \r
-       if (!DecodeT55xxBlock()) return 1;\r
+       if (!DecodeT55xxBlock()) return 0;\r
+\r
+       if ( !DemodBufferLen) return 0;\r
 \r
-       if ( !DemodBufferLen) return 1;\r
-       \r
        RepaintGraphWindow();\r
        uint8_t repeat = 0;\r
        if (config.offset > 5) \r
                repeat = 32;\r
        uint8_t si = config.offset+repeat;\r
-       uint32_t bl0     = PackBits(si, 32, DemodBuffer);\r
-       uint32_t bl1     = PackBits(si+32, 32, DemodBuffer);\r
+       uint32_t bl1     = PackBits(si, 32, DemodBuffer);\r
+       uint32_t bl2     = PackBits(si+32, 32, DemodBuffer);\r
        \r
        uint32_t acl     = PackBits(si, 8,  DemodBuffer); si += 8;\r
        uint32_t mfc     = PackBits(si, 8,  DemodBuffer); si += 8;\r
@@ -732,7 +837,7 @@ int CmdT55xxReadTrace(const char *Cmd)
 \r
        if ( acl != 0xE0 ) {\r
                PrintAndLog("The modulation is most likely wrong since the ACL is not 0xE0. ");\r
-               return 1;\r
+               return 0;\r
        }\r
 \r
        PrintAndLog("");\r
@@ -749,8 +854,8 @@ int CmdT55xxReadTrace(const char *Cmd)
        PrintAndLog("     Die Number   : %d", dw);\r
        PrintAndLog("-------------------------------------------------------------");\r
        PrintAndLog(" Raw Data - Page 1");\r
-       PrintAndLog("     Block 0  : 0x%08X  %s", bl0, sprint_bin(DemodBuffer+config.offset+repeat,32) );\r
-       PrintAndLog("     Block 1  : 0x%08X  %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );\r
+       PrintAndLog("     Block 1  : 0x%08X  %s", bl1, sprint_bin(DemodBuffer+config.offset+repeat,32) );\r
+       PrintAndLog("     Block 2  : 0x%08X  %s", bl2, sprint_bin(DemodBuffer+config.offset+repeat+32,32) );\r
        PrintAndLog("-------------------------------------------------------------");\r
 \r
        /*\r
@@ -779,13 +884,16 @@ int CmdT55xxInfo(const char *Cmd){
                Normal mode\r
                Extended mode\r
        */\r
+       bool pwdmode = false;\r
+       uint32_t password = 0;\r
        char cmdp = param_getchar(Cmd, 0);\r
 \r
        if (strlen(Cmd) > 1 || cmdp == 'h' || cmdp == 'H')\r
                return usage_t55xx_info();\r
        \r
        if (strlen(Cmd)==0)\r
-               AquireData( CONFIGURATION_BLOCK );\r
+               if ( !AquireData( 0, CONFIGURATION_BLOCK, pwdmode, password ) )\r
+                       return 1;\r
 \r
        if (!DecodeT55xxBlock()) return 1;\r
 \r
@@ -836,67 +944,59 @@ int CmdT55xxInfo(const char *Cmd){
 \r
 int CmdT55xxDump(const char *Cmd){\r
 \r
-       char s[20] = {0x00};\r
-       uint8_t pwd[4] = {0x00};\r
-\r
+       uint32_t password = 0;\r
        char cmdp = param_getchar(Cmd, 0);\r
-       if ( cmdp == 'h' || cmdp == 'H') {\r
-               usage_t55xx_dump();\r
-               return 0;\r
-       }\r
-\r
-       bool hasPwd = ( strlen(Cmd) > 0);       \r
-       if ( hasPwd ){\r
-               if (param_gethex(Cmd, 0, pwd, 8)) {\r
-                       PrintAndLog("password must include 8 HEX symbols");\r
-                       return 1;\r
-               }\r
+       bool override = false;\r
+       if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_dump();\r
+\r
+       bool usepwd = ( strlen(Cmd) > 0);       \r
+       if ( usepwd ){\r
+               password = param_get32ex(Cmd, 0, 0, 16);\r
+               if (param_getchar(Cmd, 1) =='o' )\r
+                       override = true;\r
        }\r
        \r
-       for ( int i = 0; i <8; ++i){\r
-               memset(s,0,sizeof(s));\r
+       PrintAndLog("Reading Page 0:"); \r
+       PrintAndLog("blk | hex data | binary");\r
+       for ( uint8_t i = 0; i <8; ++i){\r
+               T55xxReadBlock(i, 0, usepwd, override, password);\r
+               /*memset(s,0,sizeof(s));\r
                if ( hasPwd ) {\r
-                       sprintf(s,"%d %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]);\r
+                       if ( override ) {\r
+                               sprintf(s,"b %d p %02x%02x%02x%02x o", i, pwd[0],pwd[1],pwd[2],pwd[3]);                         \r
+                       } else {\r
+                               sprintf(s,"b %d p %02x%02x%02x%02x", i, pwd[0],pwd[1],pwd[2],pwd[3]);                           \r
+                       }\r
                } else {\r
-                       sprintf(s,"%d", i);\r
+                       sprintf(s,"%d", i);\r
                }\r
-               CmdT55xxReadBlock(s);\r
+               CmdT55xxReadBlock(s);*/\r
        }\r
-       return 0;\r
+       PrintAndLog("Reading Page 1:"); \r
+       PrintAndLog("blk | hex data | binary");\r
+       for ( uint8_t   i = 0; i<4; i++){\r
+               T55xxReadBlock(i, 1, usepwd, override, password);               \r
+       }\r
+       return 1;\r
 }\r
 \r
-int AquireData( uint8_t block ){\r
-\r
-       UsbCommand c;\r
-       \r
-       if ( block == CONFIGURATION_BLOCK ) \r
-               c.cmd = CMD_T55XX_READ_BLOCK;\r
-       else if (block == TRACE_BLOCK )\r
-               c.cmd = CMD_T55XX_READ_TRACE;\r
-               \r
-       c.arg[0] = 0x00;\r
-       c.arg[1] = 0x00;\r
-       c.arg[2] = 0x00;\r
-       c.d.asBytes[0] = 0x0; \r
+int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){\r
 \r
-       //Password mode\r
-       // if ( res == 2 ) {\r
-               // c.arg[2] = password;\r
-               // c.d.asBytes[0] = 0x1; \r
-       // }\r
+       uint8_t arg0 = (page<<1) | pwdmode;\r
+       UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};\r
 \r
        clearCommandBuffer();\r
        SendCommand(&c);\r
        if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
                PrintAndLog("command execution time out");\r
-               return 1;\r
+               return 0;\r
        }\r
 \r
        uint8_t got[12000];\r
        GetFromBigBuf(got,sizeof(got),0);\r
        WaitForResponse(CMD_ACK,NULL);\r
-       setGraphBuf(got, 12000);\r
-       return 0;\r
+       setGraphBuf(got, sizeof(got));\r
+       return 1;\r
 }\r
 \r
 char * GetBitRateStr(uint32_t id){\r
@@ -1072,17 +1172,36 @@ uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){
        return tmp;\r
 }\r
 \r
+int CmdResetRead(const char *Cmd) {\r
+       UsbCommand c = {CMD_T55XX_RESET_READ, {0,0,0}};\r
+\r
+       clearCommandBuffer();\r
+       SendCommand(&c);\r
+       if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {\r
+               PrintAndLog("command execution time out");\r
+               return 0;\r
+       }\r
+\r
+       uint8_t got[BIGBUF_SIZE-1];\r
+       GetFromBigBuf(got,sizeof(got),0);\r
+       WaitForResponse(CMD_ACK,NULL);\r
+       setGraphBuf(got, sizeof(got));\r
+       return 1;\r
+}\r
+\r
 static command_t CommandTable[] =\r
 {\r
-  {"help",   CmdHelp,           1, "This help"},\r
-  {"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},\r
-  {"detect", CmdT55xxDetect,    0, "[1] Try detecting the tag modulation from reading the configuration block."},\r
-  {"read",   CmdT55xxReadBlock, 0, "<block> [password] -- Read T55xx block data (page 0) [optional password]"},\r
-  {"write",  CmdT55xxWriteBlock,0, "<block> <data> [password] -- Write T55xx block data (page 0) [optional password]"},\r
-  {"trace",  CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"},\r
-  {"info",   CmdT55xxInfo,      0, "[1] Show T55xx configuration data (page 0/ blk 0)"},\r
-  {"dump",   CmdT55xxDump,      0, "[password] Dump T55xx card block 0-7. [optional password]"},\r
-  {"special", special,          0, "Show block changes with 64 different offsets"},\r
+  {"help",     CmdHelp,           1, "This help"},\r
+  {"config",   CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},\r
+  {"detect",   CmdT55xxDetect,    0, "[1] Try detecting the tag modulation from reading the configuration block."},\r
+  {"read",     CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},\r
+  {"resetread",CmdResetRead,      0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},\r
+  {"write",    CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},\r
+  {"trace",    CmdT55xxReadTrace, 0, "[1] Show T55xx traceability data (page 1/ blk 0-1)"},\r
+  {"info",     CmdT55xxInfo,      0, "[1] Show T55xx configuration data (page 0/ blk 0)"},\r
+  {"dump",     CmdT55xxDump,      0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},\r
+  {"special",  special,           0, "Show block changes with 64 different offsets"},\r
+  {"wakeup",   CmdT55xxWakeUp,    0, "Send AOR wakeup command"},\r
   {NULL, NULL, 0, NULL}\r
 };\r
 \r
index 364f0271f472d18ef3f9a39d80e94ab816b81d0a..d513407987280dece9cebd78cf8905af3f5c09cb 100644 (file)
@@ -39,6 +39,9 @@ typedef struct {
                RF_128 = 0x07,\r
        } bitrate;\r
 } t55xx_conf_block_t;\r
+t55xx_conf_block_t Get_t55xx_Config();\r
+void Set_t55xx_Config(t55xx_conf_block_t conf);\r
+\r
 \r
 int CmdLFT55XX(const char *Cmd);\r
 int CmdT55xxSetConfig(const char *Cmd);\r
@@ -47,6 +50,7 @@ int CmdT55xxWriteBlock(const char *Cmd);
 int CmdT55xxReadTrace(const char *Cmd);\r
 int CmdT55xxInfo(const char *Cmd);\r
 int CmdT55xxDetect(const char *Cmd);\r
+int CmdResetRead(const char *Cmd);\r
 \r
 char * GetBitRateStr(uint32_t id);\r
 char * GetSaferStr(uint32_t id);\r
@@ -55,12 +59,12 @@ char * GetModelStrFromCID(uint32_t cid);
 char * GetSelectedModulationStr( uint8_t id);\r
 uint32_t PackBits(uint8_t start, uint8_t len, uint8_t *bitstream);\r
 void printT55xxBlock(const char *demodStr);\r
-void printConfiguration( t55xx_conf_block_t b);\r
+int printConfiguration( t55xx_conf_block_t b);\r
 \r
 bool DecodeT55xxBlock();\r
 bool tryDetectModulation();\r
 bool test(uint8_t mode, uint8_t *offset, int *fndBitRate);\r
 int special(const char *Cmd);\r
-int AquireData( uint8_t block );\r
+int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );\r
 \r
 #endif\r
index 2f521f62a983376b4036f508300bc70c2374cc61..c8b576fdb06c6cd4b00e77da1269c244e66a3409 100644 (file)
@@ -73,7 +73,7 @@ typedef struct {
 #define CMD_INDALA_CLONE_TAG_L                                            0x0213
 #define CMD_T55XX_READ_BLOCK                                              0x0214
 #define CMD_T55XX_WRITE_BLOCK                                             0x0215
-#define CMD_T55XX_READ_TRACE                                              0x0216
+#define CMD_T55XX_RESET_READ                                              0x0216
 #define CMD_PCF7931_READ                                                  0x0217
 #define CMD_EM4X_READ_WORD                                                0x0218
 #define CMD_EM4X_WRITE_WORD                                               0x0219
@@ -85,6 +85,7 @@ typedef struct {
 #define CMD_ASK_SIM_TAG                                                   0x021F
 #define CMD_PSK_SIM_TAG                                                   0x0220
 #define CMD_AWID_DEMOD_FSK                                                0x0221
+#define CMD_T55XX_WAKEUP                                                  0x0224
 
 /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
 
index 5f34976fa41141748d41f531435ae45460f98f13..8cdcfb349025f303d5f42cbff2bcf0eeae020109 100644 (file)
@@ -44,7 +44,7 @@ local _commands = {
        CMD_INDALA_CLONE_TAG_L =                                             0x0213,
        CMD_T55XX_READ_BLOCK =                                               0x0214,
        CMD_T55XX_WRITE_BLOCK =                                              0x0215,
-       CMD_T55XX_READ_TRACE =                                               0x0216,
+       CMD_T55XX_RESET_READ =                                               0x0216,
        CMD_PCF7931_READ =                                                   0x0217,
        CMD_EM4X_READ_WORD =                                                 0x0218,
        CMD_EM4X_WRITE_WORD =                                                0x0219,
@@ -56,7 +56,7 @@ local _commands = {
        CMD_ASK_SIM_TAG =                                                    0x021F,
        CMD_PSK_SIM_TAG =                                                    0x0220,
        CMD_AWID_DEMOD_FSK =                                                 0x0221,
-
+       CMD_T55XX_WAKEUP =                                                   0x0224,
        --/* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
 
        --// For the 13.56 MHz tags
index 6b26ec59ca119eeae71c2cf0b132fa50566b87e4..a188ecf047de8eda6c35bd4e5434ed3845c14147 100644 (file)
@@ -18,6 +18,7 @@
 #include "util.h"
 #include "nonce2key/nonce2key.h"
 #include "../common/iso15693tools.h"
+#include "iso14443crc.h"
 #include "../common/crc16.h"
 #include "../common/crc64.h"
 #include "../common/sha1.h"
@@ -228,6 +229,27 @@ static int l_iso15693_crc(lua_State *L)
        return 1;
 }
 
+static int l_iso14443b_crc(lua_State *L)
+{
+       /* void ComputeCrc14443(int CrcType,
+                     const unsigned char *Data, int Length,
+                     unsigned char *TransmitFirst,
+                     unsigned char *TransmitSecond)
+       */
+       unsigned char buf[USB_CMD_DATA_SIZE];
+       size_t len = 0;
+       const char *data = luaL_checklstring(L, 1, &len);
+       if (USB_CMD_DATA_SIZE < len)
+               len =  USB_CMD_DATA_SIZE-2;
+
+       for (int i = 0; i < len; i += 2) {
+               sscanf(&data[i], "%02x", (unsigned int *)&buf[i / 2]);
+       }
+       ComputeCrc14443(CRC_14443_B, buf, len, &buf[len], &buf[len+1]);
+
+       lua_pushlstring(L, (const char *)&buf, len+2);
+       return 1;
+}
 /*
  Simple AES 128 cbc hook up to OpenSSL.
  params:  key, input
@@ -426,6 +448,7 @@ int set_pm3_libraries(lua_State *L)
                {"clearCommandBuffer",          l_clearCommandBuffer},
                {"console",                     l_CmdConsole},
                {"iso15693_crc",                l_iso15693_crc},
+               {"iso14443b_crc",               l_iso14443b_crc},
                {"aes128_decrypt",              l_aes128decrypt_cbc},
                {"aes128_decrypt_ecb",          l_aes128decrypt_ecb},
                {"aes128_encrypt",              l_aes128encrypt_cbc},
index a3a7a50087727fc1f85a7a5a8df881537e21e04e..32feab6a6589934fd7cb291b883337915e7a027d 100644 (file)
@@ -282,6 +282,16 @@ int manrawdecode(uint8_t * BitStream, size_t *size, uint8_t invert)
        return bestErr;
 }
 
+uint32_t manchesterEncode2Bytes(uint16_t datain) {
+       uint32_t output = 0;
+       uint8_t curBit = 0;
+       for (uint8_t i=0; i<16; i++) {
+               curBit = (datain >> (15-i) & 1);
+               output |= (1<<(((15-i)*2)+curBit));
+       }
+       return output;
+}
+
 //by marshmellow
 //encode binary data into binary manchester 
 int ManchesterEncode(uint8_t *BitStream, size_t size)
@@ -369,7 +379,9 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow
        if (fclow==0) fclow=8;
        //set the threshold close to 0 (graph) or 128 std to avoid static
        uint8_t threshold_value = 123; 
-
+       size_t preLastSample = 0;
+       size_t LastSample = 0;
+       size_t currSample = 0;
        // sync to first lo-hi transition, and threshold
 
        // Need to threshold first sample
@@ -389,13 +401,22 @@ size_t fsk_wave_demod(uint8_t * dest, size_t size, uint8_t fchigh, uint8_t fclow
 
                // Check for 0->1 transition
                if (dest[idx-1] < dest[idx]) { // 0 -> 1 transition
-                       if ((idx-last_transition)<(fclow-2)){            //0-5 = garbage noise
+                       preLastSample = LastSample;
+                       LastSample = currSample;
+                       currSample = idx-last_transition;
+                       if (currSample < (fclow-2)){            //0-5 = garbage noise
                                //do nothing with extra garbage
-                       } else if ((idx-last_transition) < (fchigh-1)) { //6-8 = 8 waves
+                       } else if (currSample < (fchigh-1)) { //6-8 = 8 sample waves
+                               if (LastSample > (fchigh-2) && preLastSample < (fchigh-1)){
+                                       dest[numBits-1]=1;  //correct last 9 wave surrounded by 8 waves
+                               }
                                dest[numBits++]=1;
-                       } else if ((idx-last_transition) > (fchigh+1) && !numBits) { //12 + and first bit = garbage 
+
+                       } else if (currSample > (fchigh+1) && !numBits) { //12 + and first bit = garbage 
                                //do nothing with beginning garbage
-                       } else {                                         //9+ = 10 waves
+                       } else if (currSample == (fclow+1) && LastSample == (fclow-1)) { // had a 7 then a 9 should be two 8's
+                               dest[numBits++]=1;
+                       } else {                                         //9+ = 10 sample waves
                                dest[numBits++]=0;
                        }
                        last_transition = idx;
@@ -576,6 +597,25 @@ int IOdemodFSK(uint8_t *dest, size_t size)
                return (int) startIdx;
        }
        return -5;
+} 
+
+// by marshmellow
+// find viking preamble 0xF200 in already demoded data
+int VikingDemod_AM(uint8_t *dest, size_t *size) {
+       //make sure buffer has data
+       if (*size < 64*2) return -2;
+
+       size_t startIdx = 0;
+       uint8_t preamble[] = {1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+       uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
+       if (errChk == 0) return -4; //preamble not found
+       uint32_t checkCalc = bytebits_to_byte(dest+startIdx,8) ^ bytebits_to_byte(dest+startIdx+8,8) ^ bytebits_to_byte(dest+startIdx+16,8)
+           ^ bytebits_to_byte(dest+startIdx+24,8) ^ bytebits_to_byte(dest+startIdx+32,8) ^ bytebits_to_byte(dest+startIdx+40,8) 
+           ^ bytebits_to_byte(dest+startIdx+48,8) ^ bytebits_to_byte(dest+startIdx+56,8);
+       if ( checkCalc != 0xA8 ) return -5;
+       if (*size != 64) return -6;
+       //return start position
+       return (int) startIdx;
 }
 
 // by marshmellow
@@ -1033,63 +1073,20 @@ void psk2TOpsk1(uint8_t *BitStream, size_t size)
 int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert)
 {
        //26 bit 40134 format  (don't know other formats)
-       int i;
-       int long_wait=29;//29 leading zeros in format
-       int start;
-       int first = 0;
-       int first2 = 0;
-       int bitCnt = 0;
-       int ii;
-       // Finding the start of a UID
-       for (start = 0; start <= *size - 250; start++) {
-               first = bitStream[start];
-               for (i = start; i < start + long_wait; i++) {
-                       if (bitStream[i] != first) {
-                               break;
-                       }
-               }
-               if (i == (start + long_wait)) {
-                       break;
-               }
-       }
-       if (start == *size - 250 + 1) {
-               // did not find start sequence
-               return -1;
-       }
-       // Inverting signal if needed
-       if (first == 1) {
-               for (i = start; i < *size; i++) {
-                       bitStream[i] = !bitStream[i];
-               }
-               *invert = 1;
-       }else *invert=0;
-
-       int iii;
-       //found start once now test length by finding next one
-       for (ii=start+29; ii <= *size - 250; ii++) {
-               first2 = bitStream[ii];
-               for (iii = ii; iii < ii + long_wait; iii++) {
-                       if (bitStream[iii] != first2) {
-                               break;
-                       }
-               }
-               if (iii == (ii + long_wait)) {
-                       break;
-               }
-       }
-       if (ii== *size - 250 + 1){
-               // did not find second start sequence
-               return -2;
-       }
-       bitCnt=ii-start;
+       uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
+       uint8_t preamble_i[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0};
+       size_t startidx = 0; 
+       if (!preambleSearch(bitStream, preamble, sizeof(preamble), size, &startidx)){
+               // if didn't find preamble try again inverting
+               if (!preambleSearch(bitStream, preamble_i, sizeof(preamble_i), size, &startidx)) return -1;
+               *invert ^= 1;
+       } 
+       if (*size != 64 && *size != 224) return -2;
+       if (*invert==1)
+               for (size_t i = startidx; i < *size; i++)
+                       bitStream[i] ^= 1;
 
-       // Dumping UID
-       i = start;
-       for (ii = 0; ii < bitCnt; ii++) {
-               bitStream[ii] = bitStream[i++];
-       }
-       *size=bitCnt;
-       return 1;
+       return (int) startidx;
 }
 
 // by marshmellow - demodulate NRZ wave (both similar enough)
index d16aab9eb4205ff1f34a1438411ad04bc1f0820e..cc4fa27a3b07a12fcc5e6911a13ea41de8832c96 100644 (file)
@@ -27,9 +27,9 @@ uint8_t  detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t f
 int      DetectNRZClock(uint8_t dest[], size_t size, int clock);
 int      DetectPSKClock(uint8_t dest[], size_t size, int clock);
 int      DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low);
-uint8_t  Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
 int      fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
 int      getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
+uint32_t manchesterEncode2Bytes(uint16_t datain);
 int      ManchesterEncode(uint8_t *BitStream, size_t size);
 int      manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert);
 int      nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int maxErr);
@@ -41,13 +41,15 @@ void     psk1TOpsk2(uint8_t *BitStream, size_t size);
 size_t   removeParity(uint8_t *BitStream, size_t startIdx, uint8_t pLen, uint8_t pType, size_t bLen);
 
 //tag specific
-int FDXBdemodBI(uint8_t *dest, size_t *size);
 int AWIDdemodFSK(uint8_t *dest, size_t *size);
+uint8_t  Em410xDecode(uint8_t *BitStream, size_t *size, size_t *startIdx, uint32_t *hi, uint64_t *lo);
+int FDXBdemodBI(uint8_t *dest, size_t *size);
 int gProxII_Demod(uint8_t BitStream[], size_t *size);
 int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
 int IOdemodFSK(uint8_t *dest, size_t size);
 int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
-int PyramiddemodFSK(uint8_t *dest, size_t *size);
 int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
+int PyramiddemodFSK(uint8_t *dest, size_t *size);
+int VikingDemod_AM(uint8_t *dest, size_t *size);
 
 #endif
index 0a523da3ab993021fc13318903c3114a9326c16c..0d95cf08852a3184a0a401c451d13de7ca8e3596 100644 (file)
@@ -3,13 +3,36 @@
 #include <stdint.h>
 #include <stdarg.h>
 #include "protocols.h"
+
+// ATA55xx shared presets & routines
+uint32_t GetT55xxClockBit(uint32_t clock) {
+       switch (clock) {
+               case 128:
+                       return T55x7_BITRATE_RF_128;
+               case 100:
+                       return T55x7_BITRATE_RF_100;
+               case 64:
+                       return T55x7_BITRATE_RF_64;
+               case 50:
+                       return T55x7_BITRATE_RF_50;
+               case 40:
+                       return T55x7_BITRATE_RF_40;
+               case 32:
+                       return T55x7_BITRATE_RF_32;
+               case 16:
+                       return T55x7_BITRATE_RF_16;
+               case 8:
+                       return T55x7_BITRATE_RF_8;
+               default:
+                       return 0;
+       }
+}
+
 #ifndef ON_DEVICE
 #include "ui.h"
 #define prnt PrintAndLog
-#endif
-
-
 
+// iclass / picopass chip config structures and shared routines
 typedef struct {
        uint8_t app_limit;      //[8]
        uint8_t otp[2];         //[9-10]
@@ -18,8 +41,7 @@ typedef struct {
        uint8_t mem_config;     //[13]
        uint8_t eas;            //[14]
        uint8_t fuses;          //[15]
-}picopass_conf_block;
-
+} picopass_conf_block;
 
 typedef struct {
        uint8_t csn[8];
@@ -28,32 +50,17 @@ typedef struct {
        uint8_t key_d[8];
        uint8_t key_c[8];
        uint8_t app_issuer_area[8];
+} picopass_hdr;
 
-}picopass_hdr;
-
-
-//#define prnt printf
-/*void prnt(char *fmt,...)
-{
-       va_list argptr;
-       va_start(argptr, fmt);
-       vprintf(fmt, argptr);
-       printf("          "); // cleaning prompt
-       va_end(argptr);
-       printf("\n");
-}
-*/
-uint8_t isset(uint8_t val, uint8_t mask)
-{
+uint8_t isset(uint8_t val, uint8_t mask) {
        return (val & mask);
 }
 
-uint8_t notset(uint8_t val, uint8_t mask){
+uint8_t notset(uint8_t val, uint8_t mask) {
        return !(val & mask);
 }
 
-void fuse_config(const picopass_hdr *hdr)
-{
+void fuse_config(const picopass_hdr *hdr) {
        uint8_t fuses = hdr->conf.fuses;
 
        if (isset(fuses,FUSE_FPERS))prnt("      Mode: Personalization [Programmable]");
@@ -104,8 +111,7 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *
        }
 }
 
-void mem_app_config(const picopass_hdr *hdr)
-{
+void mem_app_config(const picopass_hdr *hdr) {
        uint8_t mem = hdr->conf.mem_config;
        uint8_t chip = hdr->conf.chip_config;
        uint8_t applimit = hdr->conf.app_limit;
@@ -118,28 +124,25 @@ void mem_app_config(const picopass_hdr *hdr)
        prnt("  AA1: blocks 06-%02X", applimit);
        prnt("  AA2: blocks %02X-%02X", applimit+1, max_blk);
 }
-void print_picopass_info(const picopass_hdr *hdr)
-{
+void print_picopass_info(const picopass_hdr *hdr) {
        fuse_config(hdr);
        mem_app_config(hdr);
 }
-void printIclassDumpInfo(uint8_t* iclass_dump)
-{
-//     picopass_hdr hdr;
-//     memcpy(&hdr, iclass_dump, sizeof(picopass_hdr));
+void printIclassDumpInfo(uint8_t* iclass_dump) {
        print_picopass_info((picopass_hdr *) iclass_dump);
 }
 
 /*
-void test()
-{
+void test() {
        picopass_hdr hdr = {0x27,0xaf,0x48,0x01,0xf9,0xff,0x12,0xe0,0x12,0xff,0xff,0xff,0x7f,0x1f,0xff,0x3c};
        prnt("Picopass configuration:");
        print_picopass_info(&hdr);
 }
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
        test();
        return 0;
 }
 */
+
+#endif
+//ON_DEVICE
index dd023bb8f403b4c19e6491adeb33049a719ef183..cdcf720b8b2546dfbd80fbe99d5f7335d0cd1bfc 100644 (file)
@@ -210,8 +210,60 @@ NXP/Philips CUSTOM COMMANDS
 #define FUSE_FPROD0  0x02
 #define FUSE_RA      0x01
 
-
 void printIclassDumpInfo(uint8_t* iclass_dump);
 void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *app_areas, uint8_t *kb);
 
-#endif // PROTOCOLS_H
+/* T55x7 configuration register definitions */
+#define T55x7_POR_DELAY             0x00000001
+#define T55x7_ST_TERMINATOR         0x00000008
+#define T55x7_PWD                   0x00000010
+#define T55x7_MAXBLOCK_SHIFT        5
+#define T55x7_AOR                   0x00000200
+#define T55x7_PSKCF_RF_2            0
+#define T55x7_PSKCF_RF_4            0x00000400
+#define T55x7_PSKCF_RF_8            0x00000800
+#define T55x7_MODULATION_DIRECT     0
+#define T55x7_MODULATION_PSK1       0x00001000
+#define T55x7_MODULATION_PSK2       0x00002000
+#define T55x7_MODULATION_PSK3       0x00003000
+#define T55x7_MODULATION_FSK1       0x00004000
+#define T55x7_MODULATION_FSK2       0x00005000
+#define T55x7_MODULATION_FSK1a      0x00006000
+#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 T55x7_BITRATE_RF_40         0x000C0000
+#define T55x7_BITRATE_RF_50         0x00100000
+#define T55x7_BITRATE_RF_64         0x00140000
+#define T55x7_BITRATE_RF_100        0x00180000
+#define T55x7_BITRATE_RF_128        0x001C0000
+
+/* T5555 (Q5) configuration register definitions */
+#define T5555_ST_TERMINATOR         0x00000001
+#define T5555_MAXBLOCK_SHIFT        0x00000001
+#define T5555_MODULATION_MANCHESTER 0
+#define T5555_MODULATION_PSK1       0x00000010
+#define T5555_MODULATION_PSK2       0x00000020
+#define T5555_MODULATION_PSK3       0x00000030
+#define T5555_MODULATION_FSK1       0x00000040
+#define T5555_MODULATION_FSK2       0x00000050
+#define T5555_MODULATION_BIPHASE    0x00000060
+#define T5555_MODULATION_DIRECT     0x00000070
+#define T5555_INVERT_OUTPUT         0x00000080
+#define T5555_PSK_RF_2              0
+#define T5555_PSK_RF_4              0x00000100
+#define T5555_PSK_RF_8              0x00000200
+#define T5555_USE_PWD               0x00000400
+#define T5555_USE_AOR               0x00000800
+#define T5555_BITRATE_SHIFT         12 //(RF=2n+2)   ie 64=2*0x1F+2   or n = (RF-2)/2
+#define T5555_FAST_WRITE            0x00004000
+#define T5555_PAGE_SELECT           0x00008000
+
+uint32_t GetT55xxClockBit(uint32_t clock);
+
+#endif 
+// PROTOCOLS_H
index 88e2afe3c1e0a5fee8ecf6bf2d0aa6b11e448b5a..b8a1296640f9319ed6231f7021be54fe19231dbb 100644 (file)
@@ -85,7 +85,7 @@ typedef struct{
 #define CMD_INDALA_CLONE_TAG_L                                            0x0213
 #define CMD_T55XX_READ_BLOCK                                              0x0214
 #define CMD_T55XX_WRITE_BLOCK                                             0x0215
-#define CMD_T55XX_READ_TRACE                                              0x0216
+#define CMD_T55XX_RESET_READ                                              0x0216
 #define CMD_PCF7931_READ                                                  0x0217
 #define CMD_PCF7931_WRITE                                                 0x0222
 #define CMD_EM4X_READ_WORD                                                0x0218
@@ -99,6 +99,7 @@ typedef struct{
 #define CMD_ASK_SIM_TAG                                                   0x021F
 #define CMD_PSK_SIM_TAG                                                   0x0220
 #define CMD_AWID_DEMOD_FSK                                                0x0221
+#define CMD_T55XX_WAKEUP                                                  0x0224
 
 
 /* CMD_SET_ADC_MUX: ext1 is 0 for lopkd, 1 for loraw, 2 for hipkd, 3 for hiraw */
Impressum, Datenschutz