Always enable fast response mode (was enabled for flasher only)
authorpwpiwi <pwpiwi@users.noreply.github.com>
Thu, 23 Jan 2020 21:07:17 +0000 (22:07 +0100)
committerpwpiwi <pwpiwi@users.noreply.github.com>
Thu, 23 Jan 2020 21:18:51 +0000 (22:18 +0100)
* ensure that CMD_ACK is used exclusively for the very last response of each PM3 operation. All Dbprintf() must be before.
* always switch off field before exiting
* append null packet for USB transfers % 64 bytes
* reformatting and whitespace fixes

17 files changed:
armsrc/epa.c
armsrc/iclass.c
armsrc/iso14443a.c
armsrc/mifarecmd.c
armsrc/mifaresniff.c
client/cmdhf14a.c
client/cmdhficlass.c
client/cmdhfmf.c
client/comms.c
client/comms.h
client/flash.c
client/flasher.c
client/mifare/mifarehost.c
client/proxmark3.c
common/usb_cdc.c
uart/uart.h
uart/uart_win32.c

index ac907f6bbd87300b700d86fd7060610d2942e63e..fe32e4971b25eb5ad55526ce4e4a49860631391e 100644 (file)
@@ -453,20 +453,17 @@ int EPA_PACE_MSE_Set_AT(pace_version_info_t pace_version_info, uint8_t password)
 //-----------------------------------------------------------------------------
 // Perform the PACE protocol by replaying given APDUs
 //-----------------------------------------------------------------------------
-void EPA_PACE_Replay(UsbCommand *c)
-{
+void EPA_PACE_Replay(UsbCommand *c) {
        uint32_t timings[sizeof(apdu_lengths_replay) / sizeof(apdu_lengths_replay[0])] = {0};
 
-       // if an APDU has been passed, save it
+       // if an APDU has been passed, just save it
        if (c->arg[0] != 0) {
                // make sure it's not too big
-               if(c->arg[2] > apdus_replay[c->arg[0] - 1].len)
-               {
+               if(c->arg[2] > apdus_replay[c->arg[0] - 1].len) {
                        cmd_send(CMD_ACK, 1, 0, 0, NULL, 0);
+                       return;
                }
-               memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1],
-                  c->d.asBytes,
-                  c->arg[2]);
+               memcpy(apdus_replay[c->arg[0] - 1].data + c->arg[1], c->d.asBytes, c->arg[2]);
                // save/update APDU length
                if (c->arg[1] == 0) {
                        apdu_lengths_replay[c->arg[0] - 1] = c->arg[2];
index 1f814609e74107c176f4e200a56f31cccd417543..afe1a607e9e1e823372bfdc285761409327915b4 100644 (file)
@@ -674,14 +674,14 @@ static bool selectIclassTag(uint8_t *card_data, uint32_t *eof_time) {
        // Send act_all
        ReaderTransmitIClass(act_all, 1, &start_time);
        // Card present?
-       if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_ACTALL, eof_time) < 0) return false;//Fail
+       if (GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_ACTALL, eof_time) < 0) return false; //Fail
 
        //Send Identify
        start_time = *eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
        ReaderTransmitIClass(identify, 1, &start_time);
        //We expect a 10-byte response here, 8 byte anticollision-CSN and 2 byte CRC
        uint8_t len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time);
-       if (len != 10) return false;//Fail
+       if (len != 10) return false; //Fail
 
        //Copy the Anti-collision CSN to our select-packet
        memcpy(&select[1], resp, 8);
@@ -690,7 +690,7 @@ static bool selectIclassTag(uint8_t *card_data, uint32_t *eof_time) {
        ReaderTransmitIClass(select, sizeof(select), &start_time);
        //We expect a 10-byte response here, 8 byte CSN and 2 byte CRC
        len = GetIso15693AnswerFromTag(resp, sizeof(resp), ICLASS_READER_TIMEOUT_OTHERS, eof_time);
-       if (len != 10) return false;//Fail
+       if (len != 10) return false; //Fail
 
        //Success - we got CSN
        //Save CSN in response data
@@ -733,42 +733,42 @@ void ReaderIClass(uint8_t flags) {
        if (selectIclassTag(resp, &eof_time)) {
                result_status = FLAG_ICLASS_READER_CSN;
                memcpy(card_data, resp, 8);
-       }
 
-       start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
+               start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
 
-       //Read block 1, config
-       if (flags & FLAG_ICLASS_READER_CONF) {
-               if (sendCmdGetResponseWithRetries(readConf, sizeof(readConf), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
-                       result_status |= FLAG_ICLASS_READER_CONF;
-                       memcpy(card_data+8, resp, 8);
-               } else {
-                       Dbprintf("Failed to read config block");
+               //Read block 1, config
+               if (flags & FLAG_ICLASS_READER_CONF) {
+                       if (sendCmdGetResponseWithRetries(readConf, sizeof(readConf), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
+                               result_status |= FLAG_ICLASS_READER_CONF;
+                               memcpy(card_data+8, resp, 8);
+                       } else {
+                               Dbprintf("Failed to read config block");
+                       }
+                       start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
                }
-               start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
-       }
 
-       //Read block 2, e-purse
-       if (flags & FLAG_ICLASS_READER_CC) {
-               if (sendCmdGetResponseWithRetries(readEpurse, sizeof(readEpurse), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
-                       result_status |= FLAG_ICLASS_READER_CC;
-                       memcpy(card_data + (8*2), resp, 8);
-               } else {
-                       Dbprintf("Failed to read e-purse");
+               //Read block 2, e-purse
+               if (flags & FLAG_ICLASS_READER_CC) {
+                       if (sendCmdGetResponseWithRetries(readEpurse, sizeof(readEpurse), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
+                               result_status |= FLAG_ICLASS_READER_CC;
+                               memcpy(card_data + (8*2), resp, 8);
+                       } else {
+                               Dbprintf("Failed to read e-purse");
+                       }
+                       start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
                }
-               start_time = eof_time + DELAY_ICLASS_VICC_TO_VCD_READER;
-       }
 
-       //Read block 5, AA
-       if (flags & FLAG_ICLASS_READER_AA) {
-               if (sendCmdGetResponseWithRetries(readAA, sizeof(readAA), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
-                       result_status |= FLAG_ICLASS_READER_AA;
-                       memcpy(card_data + (8*5), resp, 8);
-               } else {
-                       Dbprintf("Failed to read AA block");
+               //Read block 5, AA
+               if (flags & FLAG_ICLASS_READER_AA) {
+                       if (sendCmdGetResponseWithRetries(readAA, sizeof(readAA), resp, sizeof(resp), 10, 10, start_time, ICLASS_READER_TIMEOUT_OTHERS, &eof_time)) {
+                               result_status |= FLAG_ICLASS_READER_AA;
+                               memcpy(card_data + (8*5), resp, 8);
+                       } else {
+                               Dbprintf("Failed to read AA block");
+                       }
                }
        }
-
+       
        cmd_send(CMD_ACK, result_status, 0, 0, card_data, sizeof(card_data));
 
        LED_A_OFF();
@@ -819,9 +819,9 @@ void iClass_ReadBlk(uint8_t blockno) {
 
        uint8_t readblockdata[10];
        bool isOK = iClass_ReadBlock(blockno, readblockdata);
-       cmd_send(CMD_ACK, isOK, 0, 0, readblockdata, 8);
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LED_D_OFF();
+       cmd_send(CMD_ACK, isOK, 0, 0, readblockdata, 8);
 
        LED_A_OFF();
 }
@@ -899,11 +899,10 @@ void iClass_WriteBlock(uint8_t blockNo, uint8_t *data) {
        } else {
                Dbprintf("Write block [%02x] failed", blockNo);
        }
-       cmd_send(CMD_ACK, isOK, 0, 0, 0, 0);
-
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
        LED_D_OFF();
 
+       cmd_send(CMD_ACK, isOK, 0, 0, 0, 0);
        LED_A_OFF();
 }
 
@@ -934,6 +933,5 @@ void iClass_Clone(uint8_t startblock, uint8_t endblock, uint8_t *data) {
        LED_D_OFF();
 
        cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
-
        LED_A_OFF();
 }
index a24e7a4704d3b73a381a0c1ab47a64fb425dd3e8..0de5ea6f67789ebdf40981cbf8892c085e1603f1 100644 (file)
@@ -2026,15 +2026,15 @@ void ReaderIso14443a(UsbCommand *c) {
 
        set_tracing(true);
 
-       if(param & ISO14A_CLEAR_TRACE) {
+       if (param & ISO14A_CLEAR_TRACE) {
                clear_trace();
        }
 
-       if(param & ISO14A_REQUEST_TRIGGER) {
+       if (param & ISO14A_REQUEST_TRIGGER) {
                iso14a_set_trigger(true);
        }
 
-       if(param & ISO14A_CONNECT) {
+       if (param & ISO14A_CONNECT) {
                LED_A_ON();
                iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
                if(!(param & ISO14A_NO_SELECT)) {
@@ -2048,16 +2048,16 @@ void ReaderIso14443a(UsbCommand *c) {
                        }
                        FpgaDisableTracing();
                        LED_B_ON();
-                       cmd_send(CMD_ACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
+                       cmd_send(CMD_NACK,arg0,card->uidlen,0,buf,sizeof(iso14a_card_select_t));
                        LED_B_OFF();
                }
        }
 
-       if(param & ISO14A_SET_TIMEOUT) {
+       if (param & ISO14A_SET_TIMEOUT) {
                iso14a_set_timeout(timeout);
        }
 
-       if(param & ISO14A_APDU && !cantSELECT) {
+       if (param & ISO14A_APDU && !cantSELECT) {
                uint8_t res;
                arg0 = iso14_apdu(cmd, len, (param & ISO14A_SEND_CHAINING), buf, &res);
                FpgaDisableTracing();
@@ -2066,8 +2066,8 @@ void ReaderIso14443a(UsbCommand *c) {
                LED_B_OFF();
        }
 
-       if(param & ISO14A_RAW && !cantSELECT) {
-               if(param & ISO14A_APPEND_CRC) {
+       if (param & ISO14A_RAW && !cantSELECT) {
+               if (param & ISO14A_APPEND_CRC) {
                        if(param & ISO14A_TOPAZMODE) {
                                AppendCrc14443b(cmd,len);
                        } else {
@@ -2076,8 +2076,8 @@ void ReaderIso14443a(UsbCommand *c) {
                        len += 2;
                        if (lenbits) lenbits += 16;
                }
-               if(lenbits>0) {             // want to send a specific number of bits (e.g. short commands)
-                       if(param & ISO14A_TOPAZMODE) {
+               if (lenbits > 0) {             // want to send a specific number of bits (e.g. short commands)
+                       if (param & ISO14A_TOPAZMODE) {
                                int bits_to_send = lenbits;
                                uint16_t i = 0;
                                ReaderTransmitBitsPar(&cmd[i++], MIN(bits_to_send, 7), NULL, NULL);     // first byte is always short (7bits) and no parity
@@ -2091,7 +2091,7 @@ void ReaderIso14443a(UsbCommand *c) {
                                ReaderTransmitBitsPar(cmd, lenbits, par, NULL);                         // bytes are 8 bit with odd parity
                        }
                } else {                    // want to send complete bytes only
-                       if(param & ISO14A_TOPAZMODE) {
+                       if (param & ISO14A_TOPAZMODE) {
                                uint16_t i = 0;
                                ReaderTransmitBitsPar(&cmd[i++], 7, NULL, NULL);                        // first byte: 7 bits, no paritiy
                                while (i < len) {
@@ -2105,15 +2105,15 @@ void ReaderIso14443a(UsbCommand *c) {
                FpgaDisableTracing();
 
                LED_B_ON();
-               cmd_send(CMD_ACK,arg0,0,0,buf,sizeof(buf));
+               cmd_send(CMD_ACK, arg0, 0, 0, buf, sizeof(buf));
                LED_B_OFF();
        }
 
-       if(param & ISO14A_REQUEST_TRIGGER) {
+       if (param & ISO14A_REQUEST_TRIGGER) {
                iso14a_set_trigger(false);
        }
 
-       if(param & ISO14A_NO_DISCONNECT) {
+       if (param & ISO14A_NO_DISCONNECT) {
                return;
        }
 
index e30a5639aee9273209d4c8d846ccfa4e7830264d..27b1cf1923456be7248e1065471bc0fdc5b96ad6 100644 (file)
@@ -111,11 +111,12 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= 2)   DbpString("READ BLOCK FINISHED");\r
 \r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16);\r
        LED_B_OFF();\r
 \r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
@@ -202,9 +203,10 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
                return;\r
        }\r
 \r
-       cmd_send(CMD_ACK,1,0,0,dataout,16);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LED_D_OFF();\r
+\r
+       cmd_send(CMD_ACK,1,0,0,dataout,16);\r
        LED_A_OFF();\r
 }\r
 \r
@@ -266,12 +268,13 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= 2) DbpString("READ SECTOR FINISHED");\r
 \r
+       // Thats it...\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,16*NumBlocksPerSector(sectorNo));\r
        LED_B_OFF();\r
 \r
-       // Thats it...\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
@@ -362,10 +365,11 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= MF_DBG_DEBUG) Dbprintf("Blocks read %d", countblocks);\r
 \r
-       cmd_send(CMD_ACK, 1, countblocks*4, BigBuf_max_traceLen(), 0, 0);\r
-\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LED_D_OFF();\r
+\r
+       cmd_send(CMD_ACK, 1, countblocks*4, BigBuf_max_traceLen(), 0, 0);\r
+\r
        BigBuf_free();\r
        LED_A_OFF();\r
 }\r
@@ -431,13 +435,14 @@ void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");\r
 \r
+       // Thats it...\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,0,0);\r
        LED_B_OFF();\r
 \r
 \r
-       // Thats it...\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
@@ -475,8 +480,9 @@ void MifareUWriteBlockCompat(uint8_t arg0, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= 2)   DbpString("WRITE BLOCK FINISHED");\r
 \r
-       cmd_send(CMD_ACK,1,0,0,0,0);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+       cmd_send(CMD_ACK,1,0,0,0,0);\r
        LEDsoff();\r
 }\r
 */\r
@@ -544,8 +550,9 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
 \r
        if (MF_DBGLEVEL >= 2) DbpString("WRITE BLOCK FINISHED");\r
 \r
-       cmd_send(CMD_ACK,1,0,0,0,0);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+       cmd_send(CMD_ACK,1,0,0,0,0);\r
        LEDsoff();\r
 }\r
 \r
@@ -613,8 +620,9 @@ void MifareUSetPwd(uint8_t arg0, uint8_t *datain){
                return;\r
        };\r
 \r
-       cmd_send(CMD_ACK,1,0,0,0,0);\r
        FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+       cmd_send(CMD_ACK,1,0,0,0,0);\r
        LEDsoff();\r
 }\r
 \r
@@ -743,16 +751,17 @@ void MifareAcquireEncryptedNonces(uint32_t arg0, uint32_t arg1, uint32_t flags,
 \r
        crypto1_destroy(pcs);\r
 \r
+       if (field_off) {\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+               LEDsoff();\r
+       }\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK, isOK, cuid, num_nonces, buf, sizeof(buf));\r
        LED_B_OFF();\r
 \r
        if (MF_DBGLEVEL >= 3)   DbpString("AcquireEncryptedNonces finished");\r
 \r
-       if (field_off) {\r
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-               LEDsoff();\r
-       }\r
 }\r
 \r
 \r
@@ -978,13 +987,14 @@ void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t calibrate, uint8_t *dat
        memcpy(buf+16, &target_ks[1], 4);\r
        memcpy(buf+20, &authentication_timeout, 4);\r
 \r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
+       if (MF_DBGLEVEL >= 3)   DbpString("NESTED FINISHED");\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK, isOK, 0, targetBlockNo + (targetKeyType * 0x100), buf, sizeof(buf));\r
        LED_B_OFF();\r
 \r
-       if (MF_DBGLEVEL >= 3)   DbpString("NESTED FINISHED");\r
-\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
@@ -1352,13 +1362,14 @@ void MifareCWipe(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){
                break;\r
        }\r
 \r
+       // reset fpga\r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        // send USB response\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,NULL,0);\r
        LED_B_OFF();\r
 \r
-       // reset fpga\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 \r
        return;\r
@@ -1490,14 +1501,15 @@ void MifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                break;\r
        }\r
 \r
+       if ((workFlags & 0x10) || (!isOK)) {\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       }\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,uid,4);\r
        LED_B_OFF();\r
 \r
-       if ((workFlags & 0x10) || (!isOK)) {\r
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-               LEDsoff();\r
-       }\r
+       LEDsoff();\r
 }\r
 \r
 \r
@@ -1574,6 +1586,10 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                break;\r
        }\r
 \r
+       if ((workFlags & 0x10) || (!isOK)) {\r
+               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+       }\r
+\r
        LED_B_ON();\r
        if (workFlags & 0x20) {\r
                if (isOK)\r
@@ -1583,10 +1599,7 @@ void MifareCGetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datai
                cmd_send(CMD_ACK,isOK,0,0,data,18);\r
        LED_B_OFF();\r
 \r
-       if ((workFlags & 0x10) || (!isOK)) {\r
-               FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
-               LEDsoff();\r
-       }\r
+       LEDsoff();\r
 }\r
 \r
 void MifareCIdent(){\r
@@ -1622,11 +1635,12 @@ void MifareCIdent(){
        // From iceman1001: removed the if,  since some magic tags misbehavies and send an answer to it.\r
        mifare_classic_halt(NULL, 0);\r
 \r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        LED_B_ON();\r
        cmd_send(CMD_ACK,isOK,0,0,0,0);\r
        LED_B_OFF();\r
 \r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
@@ -1657,7 +1671,8 @@ void Mifare_DES_Auth1(uint8_t arg0, uint8_t *datain){
        }\r
 \r
        if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 1 FINISHED");\r
-       cmd_send(CMD_ACK,1,cuid,0,dataout, sizeof(dataout));\r
+\r
+       cmd_send(CMD_ACK, 1, cuid, 0, dataout, sizeof(dataout));\r
 }\r
 \r
 void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){\r
@@ -1671,16 +1686,17 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
 \r
        isOK = mifare_desfire_des_auth2(cuid, key, dataout);\r
 \r
-       ifisOK) {\r
+       if (isOK) {\r
                if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Authentication part2: Failed");\r
                OnError(4);\r
                return;\r
        }\r
 \r
+       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
+\r
        if (MF_DBGLEVEL >= MF_DBG_EXTENDED) DbpString("AUTH 2 FINISHED");\r
 \r
        cmd_send(CMD_ACK, isOK, 0, 0, dataout, sizeof(dataout));\r
-       FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
        LEDsoff();\r
 }\r
 \r
index b867c58242d36ac807055fd3e18ff9aed2840c0d..f3ee4a3f79dde9566b23a92581be5fd7ee829278 100644 (file)
@@ -152,7 +152,7 @@ bool intMfSniffSend() {
        while (pckLen > 0) {
                pckSize = MIN(USB_CMD_DATA_SIZE, pckLen);
                LED_B_ON();
-               cmd_send(CMD_ACK, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize);
+               cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, 1, BigBuf_get_traceLen(), pckSize, trace + BigBuf_get_traceLen() - pckLen, pckSize);
                LED_B_OFF();
 
                pckLen -= pckSize;
@@ -160,7 +160,7 @@ bool intMfSniffSend() {
        }
 
        LED_B_ON();
-       cmd_send(CMD_ACK,2,0,0,0,0);
+       cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K,2,0,0,0,0);
        LED_B_OFF();
 
        clear_trace();
index eba33947fd33ac19efd693e7101ed3f0dd5aa0d8..58315582742ed8850c15e1277f7f9f065cfa0791 100644 (file)
@@ -46,28 +46,28 @@ int CmdHF14AList(const char *Cmd)
        return 0;
 }
 
-int Hf14443_4aGetCardData(iso14a_card_select_t * card) {
+int Hf14443_4aGetCardData(iso14a_card_select_t *card) {
        UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT, 0, 0}};
        SendCommand(&c);
 
        UsbCommand resp;
-       WaitForResponse(CMD_ACK,&resp);
+       WaitForResponse(CMD_NACK, &resp);
 
        memcpy(card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
 
        uint64_t select_status = resp.arg[0];       // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
 
-       if(select_status == 0) {
+       if (select_status == 0) {
                PrintAndLog("E->iso14443a card select failed");
                return 1;
        }
 
-       if(select_status == 2) {
+       if (select_status == 2) {
                PrintAndLog("E->Card doesn't support iso14443-4 mode");
                return 1;
        }
 
-       if(select_status == 3) {
+       if (select_status == 3) {
                PrintAndLog("E->Card doesn't support standard iso14443-3 anticollision");
                PrintAndLog("\tATQA : %02x %02x", card->atqa[1], card->atqa[0]);
                return 1;
@@ -156,20 +156,24 @@ int CmdHF14AReader(const char *Cmd) {
        return 0;
 }
 
-int CmdHF14AInfo(const char *Cmd)
-{
+
+int CmdHF14AInfo(const char *Cmd) {
+
        UsbCommand c = {CMD_READER_ISO_14443a, {ISO14A_CONNECT | ISO14A_NO_DISCONNECT, 0, 0}};
        SendCommand(&c);
 
        UsbCommand resp;
-       WaitForResponse(CMD_ACK,&resp);
-
+       if (!WaitForResponseTimeout(CMD_NACK, &resp, 500)) {
+               if (Cmd[0] != 's') PrintAndLog("Error: No response from Proxmark.\n");
+               return 0;
+       }
+       
        iso14a_card_select_t card;
        memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
 
        uint64_t select_status = resp.arg[0];       // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS, 3: proprietary Anticollision
 
-       if(select_status == 0) {
+       if (select_status == 0) {
                if (Cmd[0] != 's') PrintAndLog("iso14443a card select failed");
                // disconnect
                c.arg[0] = 0;
@@ -217,13 +221,13 @@ int CmdHF14AInfo(const char *Cmd)
                        SendCommand(&c);
 
                        UsbCommand resp;
-                       WaitForResponse(CMD_ACK,&resp);
+                       WaitForResponse(CMD_NACK,&resp);
 
                        memcpy(&card, (iso14a_card_select_t *)resp.d.asBytes, sizeof(iso14a_card_select_t));
 
                        select_status = resp.arg[0];        // 0: couldn't read, 1: OK, with ATS, 2: OK, no ATS
 
-                       if(select_status == 0) {
+                       if (select_status == 0) {
                                //PrintAndLog("iso14443a card select failed");
                                // disconnect
                                c.arg[0] = 0;
@@ -272,7 +276,7 @@ int CmdHF14AInfo(const char *Cmd)
 
        // Double & triple sized UID, can be mapped to a manufacturer.
        // HACK: does this apply for Ultralight cards?
-       if ( card.uidlen > 4 ) {
+       if (card.uidlen > 4) {
                PrintAndLog("MANUFACTURER : %s", getManufacturerName(card.uid[0]));
        }
 
@@ -430,7 +434,7 @@ int CmdHF14AInfo(const char *Cmd)
        (void)mfCIdentify();
 
        if (isMifareClassic) {
-               switch(DetectClassicPrng()) {
+               switch (DetectClassicPrng()) {
                case 0:
                        PrintAndLog("Prng detection: HARDENED (hardnested)");
                        break;
@@ -462,7 +466,7 @@ int CmdHF14ACUIDs(const char *Cmd)
                SendCommand(&c);
 
                UsbCommand resp;
-               WaitForResponse(CMD_ACK,&resp);
+               WaitForResponse(CMD_NACK,&resp);
 
                iso14a_card_select_t *card = (iso14a_card_select_t *) resp.d.asBytes;
 
index 1400395aa8dbb97ca1b78d23ce54ddab3175de3f..93e46b679e7a43c007bdfcde7f6af95c46a4c2b6 100644 (file)
@@ -333,7 +333,7 @@ int HFiClassReader(bool loop, bool verbose) {
 
        while (!ukbhit()) {
                SendCommand(&c);
-               if (WaitForResponseTimeout(CMD_ACK,&resp, 4500)) {
+               if (WaitForResponseTimeout(CMD_ACK, &resp, 1000)) {
                        uint8_t readStatus = resp.arg[0] & 0xff;
                        uint8_t *data = resp.d.asBytes;
 
@@ -368,7 +368,8 @@ int HFiClassReader(bool loop, bool verbose) {
 
                        if (tagFound && !loop) return 1;
                } else {
-                       if (verbose) PrintAndLog("Command execute timeout");
+                       if (verbose) PrintAndLog("Error: No response from Proxmark.");
+                       break;
                }
                if (!loop) break;
        }
index 93c3ea65c37a00026b8b4d2b6012c6f23178d25d..33790230fa7324ccae4529f0400fd1f3d26154fa 100644 (file)
@@ -2672,7 +2672,7 @@ int CmdHF14AMfSniff(const char *Cmd){
                }\r
 \r
                UsbCommand resp;\r
-               if (WaitForResponseTimeoutW(CMD_ACK, &resp, 2000, false)) {\r
+               if (WaitForResponseTimeoutW(CMD_UNKNOWN, &resp, 2000, false)) {\r
                        res = resp.arg[0] & 0xff;\r
                        uint16_t traceLen = resp.arg[1];\r
                        len = resp.arg[2];\r
index d7f4265f9b76dd6f129ad35bbfce6b07d5659c2d..409eaba32d787885d466df36b16a2f42452f0fb4 100644 (file)
 
 #include "comms.h"
 
+#include <stdio.h>
 #include <pthread.h>
 #include <inttypes.h>
 
 #if defined(__linux__) && !defined(NO_UNLINK)
-#include <unistd.h>            // for unlink()
+#include <unistd.h>     // for unlink()
 #endif
 #include "uart.h"
 #include "ui.h"
@@ -33,7 +34,6 @@ static bool offline;
 
 typedef struct {
        bool run; // If TRUE, continue running the uart_communication thread
-       bool block_after_ACK; // if true, block after receiving an ACK package
 } communication_arg_t;
 
 static communication_arg_t conn;
@@ -78,11 +78,11 @@ void SendCommand(UsbCommand *c) {
        if (offline) {
                PrintAndLog("Sending bytes to proxmark failed - offline");
                return;
-    }
+       }
 
        pthread_mutex_lock(&txBufferMutex);
        /**
-       This causes hangups at times, when the pm3 unit is unresponsive or disconnected. The main console thread is alive, 
+       This causes hangups at times, when the pm3 unit is unresponsive or disconnected. The main console thread is alive,
        but comm thread just spins here. Not good.../holiman
        **/
        while (txBuffer_pending) {
@@ -183,7 +183,7 @@ static void UsbCommandReceived(UsbCommand *UC)
                } break;
 
                default:
-                       storeCommand(UC);
+                       storeCommand(UC);
                        break;
        }
 
@@ -195,21 +195,23 @@ static bool receive_from_serial(serial_port sp, uint8_t *rx_buf, size_t len, siz
        *received_len = 0;
        // we eventually need to call uart_receive several times if it times out in the middle of a transfer
        while (uart_receive(sp, rx_buf + *received_len, len - *received_len, &bytes_read) && bytes_read && *received_len < len) {
+               #ifdef COMMS_DEBUG
                if (bytes_read != len - *received_len) {
                        printf("uart_receive() returned true but not enough bytes could be received. received: %d, wanted to receive: %d, already received before: %d\n",
                                bytes_read, len - *received_len, *received_len);
                }
+               #endif
                *received_len += bytes_read;
                bytes_read = 0;
        }
        return (*received_len == len);
 }
-       
+
 
 static void
 #ifdef __has_attribute
 #if __has_attribute(force_align_arg_pointer)
-__attribute__((force_align_arg_pointer)) 
+__attribute__((force_align_arg_pointer))
 #endif
 #endif
 *uart_communication(void *targ) {
@@ -231,12 +233,12 @@ __attribute__((force_align_arg_pointer))
                if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) {
                        prx += rxlen;
                        if (response->cmd & CMD_VARIABLE_SIZE_FLAG) { // new style response with variable size
-                               // printf("received new style response %04" PRIx16 ", datalen = %d, arg[0] = %08" PRIx32 ", arg[1] = %08" PRIx32 ", arg[2] = %08" PRIx32 "\n",
+                               // PrintAndLog("received new style response %04" PRIx16 ", datalen = %d, arg[0] = %08" PRIx32 ", arg[1] = %08" PRIx32 ", arg[2] = %08" PRIx32 "\n",
                                        // response->cmd, response->datalen, response->arg[0], response->arg[1], response->arg[2]);
                                bytes_to_read = response->datalen;
                                if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) {
                                        UsbCommand resp;
-                                       resp.cmd = response->cmd & ~CMD_VARIABLE_SIZE_FLAG;
+                                       resp.cmd = response->cmd & ~CMD_VARIABLE_SIZE_FLAG;  // remove the flag
                                        resp.arg[0] = response->arg[0];
                                        resp.arg[1] = response->arg[1];
                                        resp.arg[2] = response->arg[2];
@@ -247,9 +249,9 @@ __attribute__((force_align_arg_pointer))
                                        }
                                }
                        } else { // old style response uses same data structure as commands. Fixed size.
-                               // printf("received old style response %016" PRIx64 ", arg[0] = %016" PRIx64 "\n", command->cmd, command->arg[0]);
+                               // PrintAndLog("received old style response %016" PRIx64 ", arg[0] = %016" PRIx64 "\n", command->cmd, command->arg[0]);
                                bytes_to_read = sizeof(UsbCommand) - bytes_to_read;
-                               if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) { 
+                               if (receive_from_serial(sp, prx, bytes_to_read, &rxlen)) {
                                        UsbCommandReceived(command);
                                        if (command->cmd == CMD_ACK) {
                                                ACK_received = true;
@@ -257,26 +259,23 @@ __attribute__((force_align_arg_pointer))
                                }
                        }
                }
-               
-               pthread_mutex_lock(&txBufferMutex);
 
-               if (conn->block_after_ACK) {
-                       // if we just received an ACK, wait here until a new command is to be transmitted
-                       if (ACK_received) {
-                               while (!txBuffer_pending) {
-                                       pthread_cond_wait(&txBufferSig, &txBufferMutex);
-                               }
+               pthread_mutex_lock(&txBufferMutex);
+               // if we received an ACK the PM has done its job and waits for another command.
+               // We therefore can wait here as well until a new command is to be transmitted.
+               // The advantage is that the next command will be transmitted immediately without the need to wait for a receive timeout
+               if (ACK_received) {
+                       while (!txBuffer_pending) {
+                               pthread_cond_wait(&txBufferSig, &txBufferMutex);
                        }
                }
-                               
-               if(txBuffer_pending) {
+               if (txBuffer_pending) {
                        if (!uart_send(sp, (uint8_t*) &txBuffer, sizeof(UsbCommand))) {
                                PrintAndLog("Sending bytes to proxmark failed");
                        }
                        txBuffer_pending = false;
-                       pthread_cond_signal(&txBufferSig); // tell main thread that txBuffer is empty
                }
-
+               pthread_cond_signal(&txBufferSig); // tell main thread that txBuffer is empty
                pthread_mutex_unlock(&txBufferMutex);
        }
 
@@ -309,7 +308,7 @@ bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *respon
        uint64_t start_time = msclock();
 
        UsbCommand resp;
-       if (response == NULL) {
+       if (response == NULL) {
                response = &resp;
        }
 
@@ -339,7 +338,7 @@ bool GetFromBigBuf(uint8_t *dest, int bytes, int start_index, UsbCommand *respon
        return false;
 }
 
-       
+
 bool GetFromFpgaRAM(uint8_t *dest, int bytes)
 {
        UsbCommand c = {CMD_HF_PLOT, {0, 0, 0}};
@@ -348,7 +347,7 @@ bool GetFromFpgaRAM(uint8_t *dest, int bytes)
        uint64_t start_time = msclock();
 
        UsbCommand response;
-       
+
        int bytes_completed = 0;
        bool show_warning = true;
        while(true) {
@@ -373,7 +372,7 @@ bool GetFromFpgaRAM(uint8_t *dest, int bytes)
 }
 
 
-bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode) {
+bool OpenProxmark(void *port, bool wait_for_port, int timeout) {
        char *portname = (char *)port;
        if (!wait_for_port) {
                sp = uart_open(portname);
@@ -405,7 +404,6 @@ bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode)
                // start the USB communication thread
                serial_port_name = portname;
                conn.run = true;
-               conn.block_after_ACK = flash_mode;
                pthread_create(&USB_communication_thread, NULL, &uart_communication, &conn);
                return true;
        }
@@ -477,7 +475,7 @@ bool WaitForResponseTimeoutW(uint32_t cmd, UsbCommand* response, size_t ms_timeo
 
        // Wait until the command is received
        while (true) {
-               while(getCommand(response)) {
+               while (getCommand(response)) {
                        if (cmd == CMD_UNKNOWN || response->cmd == cmd) {
                                return true;
                        }
index c35c4f254ae1ee9393f93c184c5dd8fcd9671a77..11df1d547090a27d0ad83e2b04dbd5ce214551b1 100644 (file)
@@ -17,7 +17,7 @@
 
 extern void SetOffline(bool new_offline);
 extern bool IsOffline();
-extern bool OpenProxmark(void *port, bool wait_for_port, int timeout, bool flash_mode);
+extern bool OpenProxmark(void *port, bool wait_for_port, int timeout);
 extern void CloseProxmark(void);
 extern void SendCommand(UsbCommand *c);
 extern void clearCommandBuffer();
index 9a443cb84fce8df45ee0ec70ca3d6e9b26753b36..67e371a20b2900591b35d91214c330c07ceb5cc2 100644 (file)
@@ -336,7 +336,7 @@ static int enter_bootloader(char *serial_port_name)
                msleep(100);
                CloseProxmark();
 
-               bool opened = OpenProxmark(serial_port_name, true, 120, true);   // wait for 2 minutes
+               bool opened = OpenProxmark(serial_port_name, true, 120);   // wait for 2 minutes
                if (opened) {
                        fprintf(stderr," Found.\n");
                        return 0;
index 7691fb3fa7a602433ea3d934d9bac724c8fd75de..d7fa0b5e866ee098ed0dbb79fc86d69b8f19f281 100644 (file)
@@ -83,7 +83,7 @@ int main(int argc, char **argv)
 
        char* serial_port_name = argv[1];
 
-       if (!OpenProxmark(serial_port_name, true, 120, true)) {   // wait for 2 minutes
+       if (!OpenProxmark(serial_port_name, true, 120)) {   // wait for 2 minutes
                fprintf(stderr, "Could not find Proxmark on %s.\n\n", serial_port_name);
                return -1;
        } else {
index 7b7107105aa92b9ff000b1221b6cabc4d578ba1a..bc53e1fe8731f88ba6363f564c53af1d12f57574 100644 (file)
@@ -1164,7 +1164,7 @@ int DetectClassicPrng(void){
 
        clearCommandBuffer();
        SendCommand(&c);
-       if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
+       if (!WaitForResponseTimeout(CMD_NACK, &resp, 2000)) {
         PrintAndLog("PRNG UID: Reply timeout.");
                return -1;
        }
index 6b1e23933464901a4d508cb60f24685b26b6b648..fb17d13d13ce94501a35cb3f14145504ce6b5868 100644 (file)
@@ -286,7 +286,7 @@ int main(int argc, char* argv[]) {
        set_my_executable_path();
 
        // try to open USB connection to Proxmark
-       usb_present = OpenProxmark(argv[1], waitCOMPort, 20, false);
+       usb_present = OpenProxmark(argv[1], waitCOMPort, 20);
 
 #ifdef HAVE_GUI
 #ifdef _WIN32
@@ -309,8 +309,10 @@ int main(int argc, char* argv[]) {
        main_loop(script_cmds_file, script_cmd, usb_present);
 #endif 
 
-       // Clean up the port
+       // Switch off field and clean up the port
        if (usb_present) {
+               UsbCommand c = {CMD_FPGA_MAJOR_MODE_OFF};
+               SendCommand(&c);
                CloseProxmark();
        }
 
index fa26ea7d8e85323620f8d9ecd16726af0b18ff08..acd16b4e704b689b8d7156d194144c6580b810ee 100644 (file)
@@ -222,28 +222,26 @@ static const char* getStringDescriptor(uint8_t idx) {
 \r
 \r
 // Bitmap for all status bits in CSR which must be written as 1 to cause no effect\r
-#define REG_NO_EFFECT_1_ALL      AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \\r
-                                                               |AT91C_UDP_STALLSENT   | AT91C_UDP_RXSETUP \\r
-                                                               |AT91C_UDP_TXCOMP\r
+#define REG_NO_EFFECT_1_ALL     (AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 | AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP | AT91C_UDP_TXCOMP)\r
 \r
 \r
 // Clear flags in the UDP_CSR register\r
 #define UDP_CLEAR_EP_FLAGS(endpoint, flags) { \\r
        volatile unsigned int reg; \\r
-       reg = pUdp->UDP_CSR[(endpoint)]; \\r
+       reg = AT91C_BASE_UDP->UDP_CSR[(endpoint)]; \\r
        reg |= REG_NO_EFFECT_1_ALL; \\r
        reg &= ~(flags); \\r
-       pUdp->UDP_CSR[(endpoint)] = reg; \\r
+       AT91C_BASE_UDP->UDP_CSR[(endpoint)] = reg; \\r
 }\r
 \r
 \r
 // Set flags in the UDP_CSR register\r
 #define UDP_SET_EP_FLAGS(endpoint, flags) { \\r
        volatile unsigned int reg; \\r
-       reg = pUdp->UDP_CSR[(endpoint)]; \\r
+       reg = AT91C_BASE_UDP->UDP_CSR[(endpoint)]; \\r
        reg |= REG_NO_EFFECT_1_ALL; \\r
        reg |= (flags); \\r
-       pUdp->UDP_CSR[(endpoint)] = reg; \\r
+       AT91C_BASE_UDP->UDP_CSR[(endpoint)] = reg; \\r
 }\r
 \r
 \r
@@ -283,19 +281,16 @@ typedef struct {
 } AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;\r
 \r
 \r
-AT91S_CDC_LINE_CODING line = {\r
+static AT91S_CDC_LINE_CODING line = {\r
        115200, // baudrate\r
        0,      // 1 Stop Bit\r
        0,      // None Parity\r
        8};     // 8 Data bits\r
 \r
 \r
-static void AT91F_CDC_Enumerate();\r
-\r
-AT91PS_UDP pUdp = AT91C_BASE_UDP;\r
-uint8_t btConfiguration = 0;\r
-uint8_t btConnection    = 0;\r
-uint8_t btReceiveBank   = AT91C_UDP_RX_DATA_BK0;\r
+static uint8_t btConfiguration = 0;\r
+static uint8_t btConnection    = 0;\r
+static uint8_t btReceiveBank   = AT91C_UDP_RX_DATA_BK0;\r
 \r
 \r
 //*----------------------------------------------------------------------------\r
@@ -307,8 +302,8 @@ void usb_disable() {
        AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;\r
 \r
        // Clear all lingering interrupts\r
-       if (pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {\r
-               pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
+       if (AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {\r
+               AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
        }\r
 }\r
 \r
@@ -347,128 +342,16 @@ void usb_enable() {
 \r
 \r
 //*----------------------------------------------------------------------------\r
-//* \fn    usb_check\r
-//* \brief Test if the device is configured and handle enumeration\r
-//*----------------------------------------------------------------------------\r
-static bool usb_check() {\r
-       AT91_REG isr = pUdp->UDP_ISR;\r
-\r
-       if (isr & AT91C_UDP_ENDBUSRES) {\r
-               pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
-               // reset all endpoints\r
-               pUdp->UDP_RSTEP  = (unsigned int)-1;\r
-               pUdp->UDP_RSTEP  = 0;\r
-               // Enable the function\r
-               pUdp->UDP_FADDR = AT91C_UDP_FEN;\r
-               // Configure endpoint 0\r
-               pUdp->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);\r
-       } else if (isr & AT91C_UDP_EPINT0) {\r
-               pUdp->UDP_ICR = AT91C_UDP_EPINT0;\r
-               AT91F_CDC_Enumerate();\r
-       }\r
-       return (btConfiguration) ? true : false;\r
-}\r
-\r
-\r
-bool usb_poll() {\r
-       if (!usb_check()) return false;\r
-       return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);\r
-}\r
-\r
-\r
-/**\r
-       In github PR #129, some users appears to get a false positive from\r
-       usb_poll, which returns true, but the usb_read operation\r
-       still returns 0.\r
-       This check is basically the same as above, but also checks\r
-       that the length available to read is non-zero, thus hopefully fixes the\r
-       bug.\r
-**/\r
-bool usb_poll_validate_length() {\r
-       if (!usb_check()) return false;\r
-       if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;\r
-       return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) >  0;\r
-}\r
-\r
-\r
-//*----------------------------------------------------------------------------\r
-//* \fn    usb_read\r
-//* \brief Read available data from Endpoint OUT\r
-//*----------------------------------------------------------------------------\r
-static uint32_t usb_read(uint8_t* data, size_t len) {\r
-       uint8_t bank = btReceiveBank;\r
-       uint32_t packetSize, nbBytesRcv = 0;\r
-       uint32_t time_out = 0;\r
-\r
-       while (len)  {\r
-               if (!usb_check()) break;\r
-\r
-               if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {\r
-                       packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);\r
-                       len -= packetSize;\r
-                       while (packetSize--)\r
-                               data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];\r
-                       UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank);\r
-                       if (bank == AT91C_UDP_RX_DATA_BK0) {\r
-                               bank = AT91C_UDP_RX_DATA_BK1;\r
-                       } else {\r
-                               bank = AT91C_UDP_RX_DATA_BK0;\r
-                       }\r
-               }\r
-               if (time_out++ == 0x1fff) break;\r
-       }\r
-\r
-       btReceiveBank = bank;\r
-       return nbBytesRcv;\r
-}\r
-\r
-\r
-//*----------------------------------------------------------------------------\r
-//* \fn    usb_write\r
-//* \brief Send through endpoint 2\r
+//* \fn    AT91F_USB_SendZlp\r
+//* \brief Send zero length packet through an endpoint\r
 //*----------------------------------------------------------------------------\r
-static uint32_t usb_write(const uint8_t* data, const size_t len) {\r
-       size_t length = len;\r
-       uint32_t cpt = 0;\r
-\r
-       if (!length) return 0;\r
-       if (!usb_check()) return 0;\r
-\r
-       // Send the first packet\r
-       cpt = MIN(length, AT91C_EP_IN_SIZE);\r
-       length -= cpt;\r
-       while (cpt--) {\r
-               pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\r
-       }\r
-       UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
-\r
-       while (length) {\r
-               // Fill the next bank\r
-               cpt = MIN(length, AT91C_EP_IN_SIZE);\r
-               length -= cpt;\r
-               while (cpt--) {\r
-                       pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\r
-               }\r
-               // Wait for the previous bank to be sent\r
-               while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
-                       if (!usb_check()) return length;\r
-               }\r
-               UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
-               while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)\r
-                       /* wait */;\r
-               UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
-       }\r
-\r
-       // Wait for the end of transfer\r
-       while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
-               if (!usb_check()) return length;\r
-       }\r
-\r
-       UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
-       while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)\r
+static void AT91F_USB_SendZlp(uint8_t endpoint) {\r
+       UDP_SET_EP_FLAGS(endpoint, AT91C_UDP_TXPKTRDY);\r
+       while (!(AT91C_BASE_UDP->UDP_CSR[endpoint] & AT91C_UDP_TXCOMP))\r
+               /* wait */;\r
+       UDP_CLEAR_EP_FLAGS(endpoint, AT91C_UDP_TXCOMP);\r
+       while (AT91C_BASE_UDP->UDP_CSR[endpoint] & AT91C_UDP_TXCOMP)\r
                /* wait */;\r
-\r
-       return length;\r
 }\r
 \r
 \r
@@ -476,7 +359,7 @@ static uint32_t usb_write(const uint8_t* data, const size_t len) {
 //* \fn    AT91F_USB_SendData\r
 //* \brief Send Data through the control endpoint\r
 //*----------------------------------------------------------------------------\r
-static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {\r
+static void AT91F_USB_SendData(const char *pData, uint32_t length) {\r
        uint32_t cpt = 0;\r
        AT91_REG csr;\r
 \r
@@ -485,17 +368,17 @@ static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t leng
                length -= cpt;\r
 \r
                while (cpt--)\r
-                       pUdp->UDP_FDR[0] = *pData++;\r
+                       AT91C_BASE_UDP->UDP_FDR[0] = *pData++;\r
 \r
-               if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
+               if (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
                        UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);\r
-                       while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
+                       while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
                                /* wait */;\r
                }\r
 \r
                UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);\r
                do {\r
-                       csr = pUdp->UDP_CSR[AT91C_EP_CONTROL];\r
+                       csr = AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL];\r
 \r
                        // Data IN stage has been stopped by a status OUT\r
                        if (csr & AT91C_UDP_RX_DATA_BK0) {\r
@@ -506,38 +389,24 @@ static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t leng
 \r
        } while (length);\r
 \r
-       if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
+       if (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {\r
                UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);\r
-               while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
+               while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
                        /* wait */;\r
        }\r
 }\r
 \r
 \r
-//*----------------------------------------------------------------------------\r
-//* \fn    AT91F_USB_SendZlp\r
-//* \brief Send zero length packet through the control endpoint\r
-//*----------------------------------------------------------------------------\r
-static void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {\r
-       UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);\r
-       while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP))\r
-               /* wait */;\r
-       UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);\r
-       while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)\r
-               /* wait */;\r
-}\r
-\r
-\r
 //*----------------------------------------------------------------------------\r
 //* \fn    AT91F_USB_SendStall\r
 //* \brief Stall the control endpoint\r
 //*----------------------------------------------------------------------------\r
-static void AT91F_USB_SendStall(AT91PS_UDP pUdp) {\r
+static void AT91F_USB_SendStall(void) {\r
        UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL);\r
-       while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR))\r
+       while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR))\r
                /* wait */;\r
        UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);\r
-       while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR))\r
+       while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR))\r
                /* wait */;\r
 }\r
 \r
@@ -550,137 +419,270 @@ static void AT91F_CDC_Enumerate() {
        uint8_t bmRequestType, bRequest;\r
        uint16_t wValue, wIndex, wLength, wStatus;\r
 \r
-       if (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP))\r
+       if (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP))\r
                return;\r
 \r
-       bmRequestType = pUdp->UDP_FDR[AT91C_EP_CONTROL];\r
-       bRequest      = pUdp->UDP_FDR[AT91C_EP_CONTROL];\r
-       wValue        = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
-       wValue       |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
-       wIndex        = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
-       wIndex       |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
-       wLength       = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
-       wLength      |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
+       bmRequestType = AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL];\r
+       bRequest      = AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL];\r
+       wValue        = (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
+       wValue       |= (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
+       wIndex        = (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
+       wIndex       |= (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
+       wLength       = (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);\r
+       wLength      |= (AT91C_BASE_UDP->UDP_FDR[AT91C_EP_CONTROL] << 8);\r
 \r
        if (bmRequestType & 0x80) { // Data Phase Transfer Direction Device to Host\r
                UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_DIR);\r
-               while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR))\r
+               while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR))\r
                        /* wait */;\r
        }\r
        UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP);\r
-       while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP)\r
+       while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP)\r
                /* wait */;\r
 \r
        // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1\r
        switch ((bRequest << 8) | bmRequestType) {\r
        case STD_GET_DESCRIPTOR:\r
                if (wValue == 0x100)       // Return Device Descriptor\r
-                       AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength));\r
+                       AT91F_USB_SendData(devDescriptor, MIN(sizeof(devDescriptor), wLength));\r
                else if (wValue == 0x200)  // Return Configuration Descriptor\r
-                       AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));\r
+                       AT91F_USB_SendData(cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength));\r
                else if ((wValue & 0xF00) == 0x300) { // Return String Descriptor\r
                        const char *strDescriptor = getStringDescriptor(wValue & 0xff);\r
                        if (strDescriptor != NULL) {\r
-                               AT91F_USB_SendData(pUdp, strDescriptor, MIN(strDescriptor[0], wLength));\r
+                               AT91F_USB_SendData(strDescriptor, MIN(strDescriptor[0], wLength));\r
                        } else {\r
-                               AT91F_USB_SendStall(pUdp);\r
+                               AT91F_USB_SendStall();\r
                        }\r
                }\r
                else\r
-                       AT91F_USB_SendStall(pUdp);\r
+                       AT91F_USB_SendStall();\r
                break;\r
        case STD_SET_ADDRESS:\r
-               AT91F_USB_SendZlp(pUdp);\r
-               pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue);\r
-               pUdp->UDP_GLBSTATE  = (wValue) ? AT91C_UDP_FADDEN : 0;\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
+               AT91C_BASE_UDP->UDP_FADDR = (AT91C_UDP_FEN | wValue);\r
+               AT91C_BASE_UDP->UDP_GLBSTATE  = (wValue) ? AT91C_UDP_FADDEN : 0;\r
                break;\r
        case STD_SET_CONFIGURATION:\r
                btConfiguration = wValue;\r
-               AT91F_USB_SendZlp(pUdp);\r
-               pUdp->UDP_GLBSTATE  = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;\r
-               pUdp->UDP_CSR[AT91C_EP_OUT]    = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;\r
-               pUdp->UDP_CSR[AT91C_EP_IN]     = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN)  : 0;\r
-               pUdp->UDP_CSR[AT91C_EP_NOTIFY] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN)   : 0;\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
+               AT91C_BASE_UDP->UDP_GLBSTATE  = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;\r
+               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT]    = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;\r
+               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN]     = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN)  : 0;\r
+               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_NOTIFY] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN)   : 0;\r
                break;\r
        case STD_GET_CONFIGURATION:\r
-               AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));\r
+               AT91F_USB_SendData((char *) &(btConfiguration), sizeof(btConfiguration));\r
                break;\r
        case STD_GET_STATUS_ZERO:\r
                wStatus = 0;    // Device is Bus powered, remote wakeup disabled\r
-               AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+               AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
                break;\r
        case STD_GET_STATUS_INTERFACE:\r
                wStatus = 0;    // reserved for future use\r
-               AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+               AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
                break;\r
        case STD_GET_STATUS_ENDPOINT:\r
                wStatus = 0;\r
                wIndex &= 0x0F;\r
-               if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= AT91C_EP_NOTIFY)) {\r
-                       wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
-                       AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
-               } else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == AT91C_EP_CONTROL)) {\r
-                       wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
-                       AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));\r
+               if ((AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= AT91C_EP_NOTIFY)) {\r
+                       wStatus = (AT91C_BASE_UDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
+                       AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
+               } else if ((AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == AT91C_EP_CONTROL)) {\r
+                       wStatus = (AT91C_BASE_UDP->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;\r
+                       AT91F_USB_SendData((char *) &wStatus, sizeof(wStatus));\r
                } else\r
-                       AT91F_USB_SendStall(pUdp);\r
+                       AT91F_USB_SendStall();\r
                break;\r
        case STD_SET_FEATURE_ZERO:\r
-               AT91F_USB_SendStall(pUdp);\r
+               AT91F_USB_SendStall();\r
                break;\r
        case STD_SET_FEATURE_INTERFACE:\r
-               AT91F_USB_SendZlp(pUdp);\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                break;\r
        case STD_SET_FEATURE_ENDPOINT:\r
                wIndex &= 0x0F;\r
                if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) {\r
-                       pUdp->UDP_CSR[wIndex] = 0;\r
-                       AT91F_USB_SendZlp(pUdp);\r
+                       AT91C_BASE_UDP->UDP_CSR[wIndex] = 0;\r
+                       AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                } else\r
-                       AT91F_USB_SendStall(pUdp);\r
+                       AT91F_USB_SendStall();\r
                break;\r
        case STD_CLEAR_FEATURE_ZERO:\r
-               AT91F_USB_SendStall(pUdp);\r
+               AT91F_USB_SendStall();\r
                break;\r
        case STD_CLEAR_FEATURE_INTERFACE:\r
-               AT91F_USB_SendZlp(pUdp);\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                break;\r
        case STD_CLEAR_FEATURE_ENDPOINT:\r
                wIndex &= 0x0F;\r
                if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) {\r
                        if (wIndex == AT91C_EP_OUT)\r
-                               pUdp->UDP_CSR[AT91C_EP_OUT] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);\r
+                               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);\r
                        else if (wIndex == AT91C_EP_IN)\r
-                               pUdp->UDP_CSR[AT91C_EP_IN] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);\r
+                               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);\r
                        else if (wIndex == AT91C_EP_NOTIFY)\r
-                               pUdp->UDP_CSR[AT91C_EP_NOTIFY] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);\r
-                       AT91F_USB_SendZlp(pUdp);\r
+                               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_NOTIFY] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);\r
+                       AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                }\r
                else\r
-                       AT91F_USB_SendStall(pUdp);\r
+                       AT91F_USB_SendStall();\r
                break;\r
 \r
        // handle CDC class requests\r
        case SET_LINE_CODING:\r
-               while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0))\r
+               while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0))\r
                        /* wait */;\r
                UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);\r
-               AT91F_USB_SendZlp(pUdp);\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                break;\r
        case GET_LINE_CODING:\r
-               AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength));\r
+               AT91F_USB_SendData((char *) &line, MIN(sizeof(line), wLength));\r
                break;\r
        case SET_CONTROL_LINE_STATE:\r
                btConnection = wValue;\r
-               AT91F_USB_SendZlp(pUdp);\r
+               AT91F_USB_SendZlp(AT91C_EP_CONTROL);\r
                break;\r
        default:\r
-               AT91F_USB_SendStall(pUdp);\r
+               AT91F_USB_SendStall();\r
                break;\r
        }\r
 }\r
 \r
 \r
+//*----------------------------------------------------------------------------\r
+//* \fn    usb_check\r
+//* \brief Test if the device is configured and handle enumeration\r
+//*----------------------------------------------------------------------------\r
+static bool usb_check() {\r
+       AT91_REG isr = AT91C_BASE_UDP->UDP_ISR;\r
+\r
+       if (isr & AT91C_UDP_ENDBUSRES) {\r
+               AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
+               // reset all endpoints\r
+               AT91C_BASE_UDP->UDP_RSTEP  = (unsigned int)-1;\r
+               AT91C_BASE_UDP->UDP_RSTEP  = 0;\r
+               // Enable the function\r
+               AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN;\r
+               // Configure endpoint 0\r
+               AT91C_BASE_UDP->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);\r
+       } else if (isr & AT91C_UDP_EPINT0) {\r
+               AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_EPINT0;\r
+               AT91F_CDC_Enumerate();\r
+       }\r
+       return (btConfiguration) ? true : false;\r
+}\r
+\r
+\r
+bool usb_poll() {\r
+       if (!usb_check()) return false;\r
+       return (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);\r
+}\r
+\r
+\r
+/**\r
+       In github PR #129, some users appears to get a false positive from\r
+       usb_poll, which returns true, but the usb_read operation\r
+       still returns 0.\r
+       This check is basically the same as above, but also checks\r
+       that the length available to read is non-zero, thus hopefully fixes the\r
+       bug.\r
+**/\r
+bool usb_poll_validate_length() {\r
+       if (!usb_check()) return false;\r
+       if (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;\r
+       return (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] >> 16) >  0;\r
+}\r
+\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn    usb_read\r
+//* \brief Read available data from Endpoint OUT\r
+//*----------------------------------------------------------------------------\r
+static uint32_t usb_read(uint8_t* data, size_t len) {\r
+       uint8_t bank = btReceiveBank;\r
+       uint32_t packetSize, nbBytesRcv = 0;\r
+       uint32_t time_out = 0;\r
+\r
+       while (len)  {\r
+               if (!usb_check()) break;\r
+\r
+               if ( AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] & bank ) {\r
+                       packetSize = MIN(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_OUT] >> 16, len);\r
+                       len -= packetSize;\r
+                       while (packetSize--)\r
+                               data[nbBytesRcv++] = AT91C_BASE_UDP->UDP_FDR[AT91C_EP_OUT];\r
+                       UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank);\r
+                       if (bank == AT91C_UDP_RX_DATA_BK0) {\r
+                               bank = AT91C_UDP_RX_DATA_BK1;\r
+                       } else {\r
+                               bank = AT91C_UDP_RX_DATA_BK0;\r
+                       }\r
+               }\r
+               if (time_out++ == 0x1fff) break;\r
+       }\r
+\r
+       btReceiveBank = bank;\r
+       return nbBytesRcv;\r
+}\r
+\r
+\r
+//*----------------------------------------------------------------------------\r
+//* \fn    usb_write\r
+//* \brief Send through endpoint 2\r
+//*----------------------------------------------------------------------------\r
+static uint32_t usb_write(const uint8_t* data, const size_t len) {\r
+       size_t length = len;\r
+       uint32_t cpt = 0;\r
+\r
+       if (!length) return 0;\r
+       if (!usb_check()) return 0;\r
+\r
+       // Send the first packet\r
+       cpt = MIN(length, AT91C_EP_IN_SIZE);\r
+       length -= cpt;\r
+       while (cpt--) {\r
+               AT91C_BASE_UDP->UDP_FDR[AT91C_EP_IN] = *data++;\r
+       }\r
+       UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
+       while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY))\r
+               /* wait */;\r
+\r
+       while (length) {\r
+               // Fill the next bank\r
+               cpt = MIN(length, AT91C_EP_IN_SIZE);\r
+               length -= cpt;\r
+               while (cpt--) {\r
+                       AT91C_BASE_UDP->UDP_FDR[AT91C_EP_IN] = *data++;\r
+               }\r
+               // Wait for the previous bank to be sent\r
+               while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
+                       if (!usb_check()) return length;\r
+               }\r
+               UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
+               while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY))\r
+                       /* wait */;\r
+               UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
+               while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)\r
+                       /* wait */;\r
+       }\r
+\r
+       // Wait for the end of transfer\r
+       while (!(AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
+               if (!usb_check()) return length;\r
+       }\r
+       UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
+       while (AT91C_BASE_UDP->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)\r
+               /* wait */;\r
+\r
+       if (len % AT91C_EP_IN_SIZE == 0) { // need to send a zero length packet to complete the transfer\r
+               AT91F_USB_SendZlp(AT91C_EP_IN);\r
+       }\r
+\r
+       return length;\r
+}\r
+\r
+\r
 //***************************************************************************\r
 // Interface to the main program\r
 //***************************************************************************\r
@@ -752,7 +754,7 @@ bool cmd_send_old(uint16_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, voi
                        txcmd.d.asBytes[i] = ((uint8_t*)data)[i];\r
                }\r
        }\r
-       \r
+\r
        // Send frame and make sure all bytes are transmitted\r
        if (usb_write((uint8_t*)&txcmd, sizeof(UsbCommand)) != 0) return false;\r
 \r
index 3b563be2120c803848df7cbad01cbf5f1258cee3..ce00bc0b773b94dbd8bad0f39e7e1d2b37b44ffe 100644 (file)
  * @file uart.h
  */
 
-#ifndef _PM3_UART_H_
-#define _PM3_UART_H_
+#ifndef PM3_UART_H__
+#define PM3_UART_H__
 
-#include <stdio.h>
-#include <string.h>
 #include <stdlib.h>
-
 #include <stdint.h>
 #include <stdbool.h>
 
 /* Used to substitute for an example serial port path on each platform.
  */
 #ifdef _WIN32
-#define SERIAL_PORT_H  "com3"
+#define SERIAL_PORT_H   "com3"
 #elif __APPLE__
-#define SERIAL_PORT_H  "/dev/tty.usbmodem*"
+#define SERIAL_PORT_H   "/dev/tty.usbmodem*"
 #else
-#define SERIAL_PORT_H  "/dev/ttyACM0"
+#define SERIAL_PORT_H   "/dev/ttyACM0"
 #endif
 
 /* serial_port is declared as a void*, which you should cast to whatever type
@@ -69,11 +66,11 @@ typedef void* serial_port;
  *
  * On errors, this method returns INVALID_SERIAL_PORT or CLAIMED_SERIAL_PORT.
  */
-serial_port uart_open(const char* pcPortName);
+extern serial_port uart_open(const char* pcPortName);
 
 /* Closes the given port.
  */
-void uart_close(const serial_port sp);
+extern void uart_close(const serial_port sp);
 
 /* Reads from the given serial port for up to 30ms.
  *   pbtRx: A pointer to a buffer for the returned data to be written to.
@@ -84,15 +81,15 @@ void uart_close(const serial_port sp);
  *
  * Returns FALSE if there was an error reading from the device. Note that a
  * partial read may have completed into the buffer by the corresponding
- * implementation, so pszRxLen should be checked to see if any data was written. 
+ * implementation, so pszRxLen should be checked to see if any data was written.
  */
-bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen);
+extern bool uart_receive(const serial_port sp, uint8_t* pbtRx, size_t pszMaxRxLen, size_t* pszRxLen);
 
 /* Sends a buffer to a given serial port.
  *   pbtTx: A pointer to a buffer containing the data to send.
  *   szTxLen: The amount of data to be sent.
  */
-bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen);
+extern bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen);
 
 /* Sets the current speed of the serial port, in baud.
  */
@@ -100,7 +97,7 @@ bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
 
 /* Gets the current speed of the serial port, in baud.
  */
-uint32_t uart_get_speed(const serial_port sp);
+extern uint32_t uart_get_speed(const serial_port sp);
 
 #endif // _PM3_UART_H_
 
index b15e87860e2bbcb1ac3e901084de2d7cfef35895..0e4227de4caf0929fc3d175b8d8ecc6dfc970b3d 100644 (file)
 
 #include "uart.h"
 
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+
 // The windows serial port implementation
 #ifdef _WIN32
 #include <windows.h>
 
 typedef struct {
-  HANDLE hPort;     // Serial port handle
-  DCB dcb;          // Device control settings
-  COMMTIMEOUTS ct;  // Serial port time-out configuration
+       HANDLE hPort;     // Serial port handle
+       DCB dcb;          // Device control settings
+       COMMTIMEOUTS ct;  // Serial port time-out configuration
 } serial_port_windows;
 
+
 void upcase(char *p) {
-  while(*p != '\0') {
-    if(*p >= 97 && *p <= 122) {
-      *p -= 32;
-    }
-    ++p;
-  }
+       while(*p != '\0') {
+               if(*p >= 97 && *p <= 122) {
+                       *p -= 32;
+               }
+               ++p;
+       }
 }
 
-serial_port uart_open(const char* pcPortName) {
-  char acPortName[255];
-  serial_port_windows* sp = malloc(sizeof(serial_port_windows));
-  
-  // Copy the input "com?" to "\\.\COM?" format
-  sprintf(acPortName,"\\\\.\\%s",pcPortName);
-  upcase(acPortName);
-  
-  // Try to open the serial port
-  sp->hPort = CreateFileA(acPortName,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
-  if (sp->hPort == INVALID_HANDLE_VALUE) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-  
-  // Prepare the device control
-  memset(&sp->dcb, 0, sizeof(DCB));
-  sp->dcb.DCBlength = sizeof(DCB);
-  if(!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp->dcb)) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-  
-  // Update the active serial port
-  if(!SetCommState(sp->hPort,&sp->dcb)) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-  
-  sp->ct.ReadIntervalTimeout         = 0;
-  sp->ct.ReadTotalTimeoutMultiplier  = 0;
-  sp->ct.ReadTotalTimeoutConstant    = 30;
-  sp->ct.WriteTotalTimeoutMultiplier = 0;
-  sp->ct.WriteTotalTimeoutConstant   = 30;
-  
-  if(!SetCommTimeouts(sp->hPort,&sp->ct)) {
-    uart_close(sp);
-    return INVALID_SERIAL_PORT;
-  }
-  
-  PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
-  
-  return sp;
-}
 
 void uart_close(const serial_port sp) {
-  CloseHandle(((serial_port_windows*)sp)->hPort);
-  free(sp);
+       CloseHandle(((serial_port_windows*)sp)->hPort);
+       free(sp);
 }
 
+
+serial_port uart_open(const char* pcPortName) {
+       char acPortName[255];
+       serial_port_windows* sp = malloc(sizeof(serial_port_windows));
+
+       // Copy the input "com?" to "\\.\COM?" format
+       sprintf(acPortName,"\\\\.\\%s",pcPortName);
+       upcase(acPortName);
+
+       // Try to open the serial port
+       sp->hPort = CreateFileA(acPortName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
+       if (sp->hPort == INVALID_HANDLE_VALUE) {
+               uart_close(sp);
+               return INVALID_SERIAL_PORT;
+       }
+
+       // Prepare the device control
+       memset(&sp->dcb, 0, sizeof(DCB));
+       sp->dcb.DCBlength = sizeof(DCB);
+       if (!BuildCommDCBA("baud=9600 data=8 parity=N stop=1",&sp->dcb)) {
+               uart_close(sp);
+               return INVALID_SERIAL_PORT;
+       }
+
+       // Update the active serial port
+       if (!SetCommState(sp->hPort,&sp->dcb)) {
+               uart_close(sp);
+               return INVALID_SERIAL_PORT;
+       }
+
+       sp->ct.ReadIntervalTimeout         = 0;
+       sp->ct.ReadTotalTimeoutMultiplier  = 0;
+       sp->ct.ReadTotalTimeoutConstant    = 30;
+       sp->ct.WriteTotalTimeoutMultiplier = 0;
+       sp->ct.WriteTotalTimeoutConstant   = 30;
+
+       if (!SetCommTimeouts(sp->hPort, &sp->ct)) {
+               uart_close(sp);
+               return INVALID_SERIAL_PORT;
+       }
+
+       PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR);
+
+       return sp;
+}
+
+
 bool uart_receive(const serial_port sp, uint8_t *pbtRx, size_t pszMaxRxLen, size_t *pszRxLen) {
-  return ReadFile(((serial_port_windows*)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
+       return ReadFile(((serial_port_windows*)sp)->hPort, pbtRx, pszMaxRxLen, (LPDWORD)pszRxLen, NULL);
 }
 
+
 bool uart_send(const serial_port sp, const uint8_t* pbtTx, const size_t szTxLen) {
-  DWORD dwTxLen = 0;
-  return WriteFile(((serial_port_windows*)sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL);
+       DWORD dwTxLen = 0;
+       return WriteFile(((serial_port_windows*)sp)->hPort, pbtTx, szTxLen, &dwTxLen, NULL);
 }
 
+
 bool uart_set_speed(serial_port sp, const uint32_t uiPortSpeed) {
-  serial_port_windows* spw;
-  spw = (serial_port_windows*)sp;
-  spw->dcb.BaudRate = uiPortSpeed;
-  return SetCommState(spw->hPort, &spw->dcb);
+       serial_port_windows* spw;
+       spw = (serial_port_windows*)sp;
+       spw->dcb.BaudRate = uiPortSpeed;
+       return SetCommState(spw->hPort, &spw->dcb);
 }
 
+
 uint32_t uart_get_speed(const serial_port sp) {
-  const serial_port_windows* spw = (serial_port_windows*)sp;
-  if (!GetCommState(spw->hPort, (serial_port)&spw->dcb)) {
-    return spw->dcb.BaudRate;
-  }
-  return 0;
+       const serial_port_windows* spw = (serial_port_windows*)sp;
+       if (!GetCommState(spw->hPort, (serial_port)&spw->dcb)) {
+               return spw->dcb.BaudRate;
+       }
+       return 0;
 }
 
 #endif
Impressum, Datenschutz