]> git.zerfleddert.de Git - proxmark3-svn/blobdiff - armsrc/iso14443a.c
small improvements, added new command `hf mf sniff` (there will be cool sniffer)...
[proxmark3-svn] / armsrc / iso14443a.c
index 7eca7977a5d6dba114fe95eb24c194f6208e3321..a82c2899195aceb39f07cc535788487d9ed614bb 100644 (file)
@@ -1,5 +1,5 @@
 //-----------------------------------------------------------------------------
-// Merlok - June 2011
+// Merlok - June 2011, 2012
 // Gerhard de Koning Gans - May 2008
 // Hagen Fritsch - June 2010
 //
@@ -129,32 +129,7 @@ int LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity,
 // The software UART that receives commands from the reader, and its state
 // variables.
 //-----------------------------------------------------------------------------
-static struct {
-    enum {
-        STATE_UNSYNCD,
-        STATE_START_OF_COMMUNICATION,
-               STATE_MILLER_X,
-               STATE_MILLER_Y,
-               STATE_MILLER_Z,
-        STATE_ERROR_WAIT
-    }       state;
-    uint16_t    shiftReg;
-    int     bitCnt;
-    int     byteCnt;
-    int     byteCntMax;
-    int     posCnt;
-    int     syncBit;
-       int     parityBits;
-       int     samples;
-    int     highCnt;
-    int     bitBuffer;
-       enum {
-               DROP_NONE,
-               DROP_FIRST_HALF,
-               DROP_SECOND_HALF
-       }               drop;
-    uint8_t   *output;
-} Uart;
+static tUart Uart;
 
 static RAMFUNC int MillerDecoding(int bit)
 {
@@ -393,32 +368,7 @@ static RAMFUNC int MillerDecoding(int bit)
 //=============================================================================
 // ISO 14443 Type A - Manchester
 //=============================================================================
-
-static struct {
-    enum {
-        DEMOD_UNSYNCD,
-               DEMOD_START_OF_COMMUNICATION,
-               DEMOD_MANCHESTER_D,
-               DEMOD_MANCHESTER_E,
-               DEMOD_MANCHESTER_F,
-        DEMOD_ERROR_WAIT
-    }       state;
-    int     bitCount;
-    int     posCount;
-       int     syncBit;
-       int     parityBits;
-    uint16_t    shiftReg;
-       int     buffer;
-       int     buff;
-       int     samples;
-    int     len;
-       enum {
-               SUB_NONE,
-               SUB_FIRST_HALF,
-               SUB_SECOND_HALF
-       }               sub;
-    uint8_t   *output;
-} Demod;
+static tDemod Demod;
 
 static RAMFUNC int ManchesterDecoding(int v)
 {
@@ -1042,52 +992,12 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
        response3a[0] = sak & 0xFB;
        ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
 
+       uint8_t response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce
+       uint8_t response6[] = { 0x03, 0x3B, 0x00, 0x00, 0x00 }; // dummy ATS (pseudo-ATR), answer to RATS
+       ComputeCrc14443(CRC_14443_A, response6, 3, &response6[3], &response6[4]);
 
-/*
-       // Check if the uid uses the (optional) second part
-       if (uid_2nd) {
-               // Configure the ATQA and SAK accordingly
-               response1[0] |= 0x40;
-               sak |= 0x04;
-       }
-*/
-
-//static const uint8_t response2a[] = { 0x51, 0x48, 0x1d, 0x80, 0x84 }; //  uid - cascade2 - 2nd half (4 bytes) of UID+ BCCheck
-
-
-       // Prepare protocol messages
-    // static const uint8_t cmd1[] = { 0x26 };
-//     static const uint8_t response1[] = { 0x02, 0x00 }; // Says: I am Mifare 4k - original line - greg
-//
-//     uint8_t response1[] = { 0x44, 0x03 }; // Says: I am a DESFire Tag, ph33r me
-//     static const uint8_t response1[] = { 0x44, 0x00 }; // Says: I am a ULTRALITE Tag, 0wn me
-
-       // UID response
-    // static const uint8_t cmd2[] = { 0x93, 0x20 };
-    //static const uint8_t response2[] = { 0x9a, 0xe5, 0xe4, 0x43, 0xd8 }; // original value - greg
-
-// my desfire
-//     uint8_t response2[] = { 0x88, 0x04, 0x21, 0x3f, 0x4d }; // known uid - note cascade (0x88), 2nd byte (0x04) = NXP/Phillips
-
-
-// When reader selects us during cascade1 it will send cmd3
-//uint8_t response3[] = { 0x04, 0x00, 0x00 }; // SAK Select (cascade1) successful response (ULTRALITE)
-//uint8_t response3[] = { 0x24, 0x00, 0x00 }; // SAK Select (cascade1) successful response (DESFire)
-//ComputeCrc14443(CRC_14443_A, response3, 1, &response3[1], &response3[2]);
-
-// send cascade2 2nd half of UID
-//static const uint8_t response2a[] = { 0x51, 0x48, 0x1d, 0x80, 0x84 }; //  uid - cascade2 - 2nd half (4 bytes) of UID+ BCCheck
-// NOTE : THE CRC on the above may be wrong as I have obfuscated the actual UID
-
-// When reader selects us during cascade2 it will send cmd3a
-//uint8_t response3a[] = { 0x00, 0x00, 0x00 }; // SAK Select (cascade2) successful response (ULTRALITE)
-//uint8_t response3a[] = { 0x20, 0x00, 0x00 }; // SAK Select (cascade2) successful response (DESFire)
-//ComputeCrc14443(CRC_14443_A, response3a, 1, &response3a[1], &response3a[2]);
-
-    static const uint8_t response5[] = { 0x00, 0x00, 0x00, 0x00 }; // Very random tag nonce
-
-    uint8_t *resp;
-    int respLen;
+       uint8_t *resp;
+       int respLen;
 
   // Longest possible response will be 16 bytes + 2 CRC = 18 bytes
        // This will need
@@ -1102,42 +1012,41 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
        // 166 bytes, since every bit that needs to be send costs us a byte
        //
 
-    // Respond with card type
-    uint8_t *resp1 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
-    int resp1Len;
+       // Respond with card type
+       uint8_t *resp1 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET);
+       int resp1Len;
 
-    // Anticollision cascade1 - respond with uid
-    uint8_t *resp2 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 166);
-    int resp2Len;
+       // Anticollision cascade1 - respond with uid
+       uint8_t *resp2 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + 166);
+       int resp2Len;
 
-    // Anticollision cascade2 - respond with 2nd half of uid if asked
-    // we're only going to be asked if we set the 1st byte of the UID (during cascade1) to 0x88
-    uint8_t *resp2a = (((uint8_t *)BigBuf) + 1140);
-    int resp2aLen;
+       // Anticollision cascade2 - respond with 2nd half of uid if asked
+       // we're only going to be asked if we set the 1st byte of the UID (during cascade1) to 0x88
+       uint8_t *resp2a = (((uint8_t *)BigBuf) + 1140);
+       int resp2aLen;
 
-    // Acknowledge select - cascade 1
-    uint8_t *resp3 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*2));
-    int resp3Len;
+       // Acknowledge select - cascade 1
+       uint8_t *resp3 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*2));
+       int resp3Len;
 
-    // Acknowledge select - cascade 2
-    uint8_t *resp3a = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*3));
-    int resp3aLen;
+       // Acknowledge select - cascade 2
+       uint8_t *resp3a = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*3));
+       int resp3aLen;
 
-    // Response to a read request - not implemented atm
-    uint8_t *resp4 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*4));
-    int resp4Len;
+       // Response to a read request - not implemented atm
+       uint8_t *resp4 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*4));
+       int resp4Len;
 
-    // Authenticate response - nonce
-    uint8_t *resp5 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*5));
-    int resp5Len;
+       // Authenticate response - nonce
+       uint8_t *resp5 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*5));
+       int resp5Len;
 
-    uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
-//             uint8_t *receivedCmd = (uint8_t *)BigBuf;
-    int len;
+       // Authenticate response - nonce
+       uint8_t *resp6 = (((uint8_t *)BigBuf) + FREE_BUFFER_OFFSET + (166*6));
+       int resp6Len;
 
-    //int i;
-       //int u;
-       //uint8_t b;
+       uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
+       int len;
 
        // To control where we are in the protocol
        int order = 0;
@@ -1152,8 +1061,6 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
        int respsize = 0;
        uint8_t nack = 0x04;
 
-       //int fdt_indicator;
-
        memset(receivedCmd, 0x44, RECV_CMD_SIZE);
 
        // Prepare the responses of the anticollision phase
@@ -1161,23 +1068,23 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
 
        // Answer to request
        CodeIso14443aAsTag(response1, sizeof(response1));
-    memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;
+       memcpy(resp1, ToSend, ToSendMax); resp1Len = ToSendMax;
 
        // Send our UID (cascade 1)
        CodeIso14443aAsTag(response2, sizeof(response2));
-    memcpy(resp2, ToSend, ToSendMax); resp2Len = ToSendMax;
+       memcpy(resp2, ToSend, ToSendMax); resp2Len = ToSendMax;
 
        // Answer to select (cascade1)
        CodeIso14443aAsTag(response3, sizeof(response3));
-    memcpy(resp3, ToSend, ToSendMax); resp3Len = ToSendMax;
+       memcpy(resp3, ToSend, ToSendMax); resp3Len = ToSendMax;
 
        // Send the cascade 2 2nd part of the uid
        CodeIso14443aAsTag(response2a, sizeof(response2a));
-    memcpy(resp2a, ToSend, ToSendMax); resp2aLen = ToSendMax;
+       memcpy(resp2a, ToSend, ToSendMax); resp2aLen = ToSendMax;
 
        // Answer to select (cascade 2)
        CodeIso14443aAsTag(response3a, sizeof(response3a));
-    memcpy(resp3a, ToSend, ToSendMax); resp3aLen = ToSendMax;
+       memcpy(resp3a, ToSend, ToSendMax); resp3aLen = ToSendMax;
 
        // Strange answer is an example of rare message size (3 bits)
        CodeStrangeAnswerAsTag();
@@ -1185,101 +1092,74 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
 
        // Authentication answer (random nonce)
        CodeIso14443aAsTag(response5, sizeof(response5));
-    memcpy(resp5, ToSend, ToSendMax); resp5Len = ToSendMax;
+       memcpy(resp5, ToSend, ToSendMax); resp5Len = ToSendMax;
 
-    // We need to listen to the high-frequency, peak-detected path.
-    SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
-    FpgaSetupSsc();
+       // dummy ATS (pseudo-ATR), answer to RATS
+       CodeIso14443aAsTag(response6, sizeof(response6));
+       memcpy(resp6, ToSend, ToSendMax); resp6Len = ToSendMax;
 
-    cmdsRecvd = 0;
+       // We need to listen to the high-frequency, peak-detected path.
+       SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+       FpgaSetupSsc();
 
-    LED_A_ON();
-       for(;;) {
+       cmdsRecvd = 0;
 
+       LED_A_ON();
+       for(;;) {
+       
                if(!GetIso14443aCommandFromReader(receivedCmd, &len, RECV_CMD_SIZE)) {
-            DbpString("button press");
-            break;
-        }
-       // doob - added loads of debug strings so we can see what the reader is saying to us during the sim as hi14alist is not populated
-        // Okay, look at the command now.
-        lastorder = order;
-               //i = 1; // first byte transmitted
-        if(receivedCmd[0] == 0x26) {
-                       // Received a REQUEST
+                       DbpString("button press");
+                       break;
+               }
+               // doob - added loads of debug strings so we can see what the reader is saying to us during the sim as hi14alist is not populated
+               // Okay, look at the command now.
+               lastorder = order;
+               if(receivedCmd[0] == 0x26) { // Received a REQUEST
                        resp = resp1; respLen = resp1Len; order = 1;
                        respdata = response1;
                        respsize = sizeof(response1);
-                       //DbpString("Hello request from reader:");
-               } else if(receivedCmd[0] == 0x52) {
-                       // Received a WAKEUP
+               } else if(receivedCmd[0] == 0x52) { // Received a WAKEUP
                        resp = resp1; respLen = resp1Len; order = 6;
-//                     //DbpString("Wakeup request from reader:");
                        respdata = response1;
                        respsize = sizeof(response1);
-               } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x93) {   // greg - cascade 1 anti-collision
-                       // Received request for UID (cascade 1)
+               } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x93) {   // Received request for UID (cascade 1)
                        resp = resp2; respLen = resp2Len; order = 2;
-//                     DbpString("UID (cascade 1) request from reader:");
-//                     DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);
                        respdata = response2;
                        respsize = sizeof(response2);
-               } else if(receivedCmd[1] == 0x20 && receivedCmd[0] ==0x95) {    // greg - cascade 2 anti-collision
-                       // Received request for UID (cascade 2)
+               } else if(receivedCmd[1] == 0x20 && receivedCmd[0] == 0x95) { // Received request for UID (cascade 2)
                        resp = resp2a; respLen = resp2aLen; order = 20;
-//                     DbpString("UID (cascade 2) request from reader:");
-//                     DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);
                        respdata = response2a;
                        respsize = sizeof(response2a);
-
-               } else if(receivedCmd[1] == 0x70 && receivedCmd[0] ==0x93) {    // greg - cascade 1 select
-                       // Received a SELECT
+               } else if(receivedCmd[1] == 0x70 && receivedCmd[0] == 0x93) {   // Received a SELECT (cascade 1)
                        resp = resp3; respLen = resp3Len; order = 3;
-//                     DbpString("Select (cascade 1) request from reader:");
-//                     DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);
                        respdata = response3;
                        respsize = sizeof(response3);
-
-               } else if(receivedCmd[1] == 0x70 && receivedCmd[0] ==0x95) {    // greg - cascade 2 select
-                       // Received a SELECT
+               } else if(receivedCmd[1] == 0x70 && receivedCmd[0] == 0x95) {   // Received a SELECT (cascade 2)
                        resp = resp3a; respLen = resp3aLen; order = 30;
-//                     DbpString("Select (cascade 2) request from reader:");
-//                     DbpIntegers(receivedCmd[0], receivedCmd[1], receivedCmd[2]);
                        respdata = response3a;
                        respsize = sizeof(response3a);
-
-               } else if(receivedCmd[0] == 0x30) {
-                       // Received a READ
+               } else if(receivedCmd[0] == 0x30) {     // Received a (plain) READ
                        resp = resp4; respLen = resp4Len; order = 4; // Do nothing
-                       Dbprintf("Read request from reader: %x %x %x",
-                               receivedCmd[0], receivedCmd[1], receivedCmd[2]);
+                       Dbprintf("Read request from reader: %x %x",receivedCmd[0],receivedCmd[1]);
                        respdata = &nack;
                        respsize = sizeof(nack); // 4-bit answer
-
-               } else if(receivedCmd[0] == 0x50) {
-                       // Received a HALT
-                       resp = resp1; respLen = 0; order = 5; // Do nothing
+               } else if(receivedCmd[0] == 0x50) {     // Received a HALT
                        DbpString("Reader requested we HALT!:");
+                       // Do not respond
+                       resp = resp1; respLen = 0; order = 0;
                        respdata = NULL;
                        respsize = 0;
-
-               } else if(receivedCmd[0] == 0x60) {
-                       // Received an authentication request
+               } else if(receivedCmd[0] == 0x60 || receivedCmd[0] == 0x61) {   // Received an authentication request
                        resp = resp5; respLen = resp5Len; order = 7;
-                       Dbprintf("Authenticate request from reader: %x %x %x",
-                               receivedCmd[0], receivedCmd[1], receivedCmd[2]);
-                       respdata = NULL;
-                       respsize = 0;
-
-               } else if(receivedCmd[0] == 0xE0) {
-                       // Received a RATS request
-                       resp = resp1; respLen = 0;order = 70;
-                       Dbprintf("RATS request from reader: %x %x %x",
-                               receivedCmd[0], receivedCmd[1], receivedCmd[2]);
-                       respdata = NULL;
-                       respsize = 0;
+                       respdata = response5;
+                       respsize = sizeof(response5);
+               } else if(receivedCmd[0] == 0xE0) {     // Received a RATS request
+                       resp = resp6; respLen = resp6Len; order = 70;
+                       respdata = response6;
+                       respsize = sizeof(response6);
                } else {
                        // Never seen this command before
-                       Dbprintf("Unknown command received from reader (len=%d): %x %x %x %x %x %x %x %x %x",
+                       Dbprintf("Received (len=%d): %02x %02x %02x %02x %02x %02x %02x %02x %02x",
                        len,
                        receivedCmd[0], receivedCmd[1], receivedCmd[2],
                        receivedCmd[3], receivedCmd[4], receivedCmd[5],
@@ -1302,20 +1182,14 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
                        //i = 0;
                }
 
-
                if(cmdsRecvd > 999) {
                        DbpString("1000 commands later...");
-            break;
-        }
-               else {
+                       break;
+               } else {
                        cmdsRecvd++;
                }
 
                if(respLen > 0) {
-                       //----------------------------
-                       //u = 0;
-                       //b = 0x00;
-                       //fdt_indicator = FALSE;
                        EmSendCmd14443aRaw(resp, respLen, receivedCmd[0] == 0x52);
                }
                
@@ -1331,40 +1205,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd)
                }
 
                memset(receivedCmd, 0x44, RECV_CMD_SIZE);
-/*        // Modulate Manchester
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_TAGSIM_MOD);
-        AT91C_BASE_SSC->SSC_THR = 0x00;
-        FpgaSetupSsc();
-
-               // ### Transmit the response ###
-               u = 0;
-               b = 0x00;
-               fdt_indicator = FALSE;
-        for(;;) {
-            if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
-                               volatile uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
-                (void)b;
-            }
-            if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
-                               if(i > respLen) {
-                                       b = 0x00;
-                                       u++;
-                               } else {
-                                       b = resp[i];
-                                       i++;
-                               }
-                               AT91C_BASE_SSC->SSC_THR = b;
-
-                if(u > 4) {
-                    break;
-                }
-            }
-                       if(BUTTON_PRESS()) {
-                           break;
-                       }
-        }
-*/
-    }
+  }
 
        Dbprintf("%x %x %x", happened, happened2, cmdsRecvd);
        LED_A_OFF();
@@ -2034,7 +1875,7 @@ void ReaderMifare(uint32_t parameter)
                {
                        if ( (parameter != 0) && (memcmp(nt, nt_noattack, 4) == 0) ) continue;
 
-                       isNULL = (nt_attacked[0] == 0) && (nt_attacked[1] == 0) && (nt_attacked[2] == 0) && (nt_attacked[3] == 0);
+                       isNULL = !(nt_attacked[0] == 0) && (nt_attacked[1] == 0) && (nt_attacked[2] == 0) && (nt_attacked[3] == 0);
                        if ( (isNULL != 0 ) && (memcmp(nt, nt_attacked, 4) != 0) ) continue;
 
                        if (nt_diff == 0)
@@ -2511,9 +2352,7 @@ lbWORK:   if (len == 0) break;
                                cardSTATE = MFEMUL_WORK;
                                break;
                        }
-               
                }
-       
        }
 
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -2525,3 +2364,132 @@ lbWORK: if (len == 0) break;
 
        if (MF_DBGLEVEL >= 1)   Dbprintf("Emulator stopped. Tracing: %d  trace length: %d ",    tracing, traceLen);
 }
+
+//-----------------------------------------------------------------------------
+// MIFARE sniffer. 
+// 
+//-----------------------------------------------------------------------------
+void RAMFUNC SniffMifare(void) {
+       LEDsoff();
+       // init trace buffer
+       traceLen = 0;
+       memset(trace, 0x44, TRACE_SIZE);
+
+       // We won't start recording the frames that we acquire until we trigger;
+       // a good trigger condition to get started is probably when we see a
+       // response from the tag.
+       int triggered = FALSE; // FALSE to wait first for card
+
+       // The command (reader -> tag) that we're receiving.
+       // The length of a received command will in most cases be no more than 18 bytes.
+       // So 32 should be enough!
+       uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
+       // The response (tag -> reader) that we're receiving.
+       uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
+
+       // As we receive stuff, we copy it from receivedCmd or receivedResponse
+       // into trace, along with its length and other annotations.
+       //uint8_t *trace = (uint8_t *)BigBuf;
+       
+       // The DMA buffer, used to stream samples from the FPGA
+       int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET;
+       int lastRxCounter;
+       int8_t *upTo;
+       int smpl;
+       int maxBehindBy = 0;
+
+       // Set up the demodulator for tag -> reader responses.
+       Demod.output = receivedResponse;
+       Demod.len = 0;
+       Demod.state = DEMOD_UNSYNCD;
+
+       // Set up the demodulator for the reader -> tag commands
+       memset(&Uart, 0, sizeof(Uart));
+       Uart.output = receivedCmd;
+       Uart.byteCntMax = 32; // was 100 (greg)//////////////////
+       Uart.state = STATE_UNSYNCD;
+
+       // Setup for the DMA.
+       FpgaSetupSsc();
+       upTo = dmaBuf;
+       lastRxCounter = DMA_BUFFER_SIZE;
+       FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
+
+       // And put the FPGA in the appropriate mode
+       // Signal field is off with the appropriate LED
+       LED_D_OFF();
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);
+       SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
+
+       // Count of samples received so far, so that we can include timing
+       // information in the trace buffer.
+       rsamples = 0;
+       // And now we loop, receiving samples.
+       while(true) {
+               LED_A_ON();
+               WDT_HIT();
+               int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
+                                                                       (DMA_BUFFER_SIZE-1);
+               if(behindBy > maxBehindBy) {
+                       maxBehindBy = behindBy;
+                       if(behindBy > 400) {
+                               Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
+                               goto done;
+                       }
+               }
+               if(behindBy < 1) continue;
+
+               LED_A_OFF();
+               
+               smpl = upTo[0];
+               upTo++;
+               lastRxCounter -= 1;
+               if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
+                       upTo -= DMA_BUFFER_SIZE;
+                       lastRxCounter += DMA_BUFFER_SIZE;
+                       AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
+                       AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
+               }
+               
+               rsamples += 4;
+               if(MillerDecoding((smpl & 0xF0) >> 4)) {
+                       LED_C_ON();
+                       if(triggered) {
+                               if (!LogTrace(receivedCmd, Uart.byteCnt, -1 * Uart.samples, Uart.parityBits, TRUE)) break;
+                       }
+                       /* And ready to receive another command. */
+                       Uart.state = STATE_UNSYNCD;
+                       /* And also reset the demod code, which might have been */
+                       /* false-triggered by the commands from the reader. */
+                       Demod.state = DEMOD_UNSYNCD;
+                       LED_B_OFF();
+               }
+
+               if(ManchesterDecoding(smpl & 0x0F)) {
+                       LED_B_ON();
+
+                       if (!LogTrace(receivedResponse, Demod.len, -1 * Demod.samples, Demod.parityBits, FALSE)) break;
+
+                       triggered = TRUE;
+
+                       // And ready to receive another response.
+                       memset(&Demod, 0, sizeof(Demod));
+                       Demod.output = receivedResponse;
+                       Demod.state = DEMOD_UNSYNCD;
+                       LED_C_OFF();
+               }
+
+               if(BUTTON_PRESS()) {
+                       DbpString("button cancelled");
+                       goto done;
+               }
+       } // main cycle
+
+       DbpString("COMMAND FINISHED");
+
+done:
+       AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
+       Dbprintf("maxBehindBy=%x, Uart.state=%x, Uart.byteCnt=%x", maxBehindBy, Uart.state, Uart.byteCnt);
+       Dbprintf("Uart.byteCntMax=%x, traceLen=%x, Uart.output[0]=%x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
+       LEDsoff();
+}
\ No newline at end of file
Impressum, Datenschutz