more fixes to USB communication
[proxmark3-svn] / common / usb_cdc.c
index 5577e354965215f72c3f56fe03217ce364a744d1..84aa2c06e6dbea6639e3d1606e68a7a0288dd424 100644 (file)
@@ -36,6 +36,8 @@
 #include "at91sam7s512.h"\r
 #include "config_gpio.h"\r
 \r
+\r
+#define AT91C_EP_CONTROL     0\r
 #define AT91C_EP_IN_SIZE  0x40\r
 #define AT91C_EP_OUT         1\r
 #define AT91C_EP_OUT_SIZE 0x40\r
@@ -197,7 +199,30 @@ const char* getStringDescriptor(uint8_t idx)
        }\r
 }\r
 \r
-/* USB standard request code */\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
+\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 |= REG_NO_EFFECT_1_ALL; \\r
+       reg &= ~(flags); \\r
+       pUdp->UDP_CSR[(endpoint)] = reg; \\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 |= REG_NO_EFFECT_1_ALL; \\r
+       reg |= (flags); \\r
+       pUdp->UDP_CSR[(endpoint)] = reg; \\r
+}\r
+\r
+/* USB standard request codes */\r
 #define STD_GET_STATUS_ZERO           0x0080\r
 #define STD_GET_STATUS_INTERFACE      0x0081\r
 #define STD_GET_STATUS_ENDPOINT       0x0082\r
@@ -305,7 +330,7 @@ bool usb_check() {
                // Enable the function\r
                pUdp->UDP_FADDR = AT91C_UDP_FEN;\r
                // Configure endpoint 0\r
-               pUdp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);\r
+               pUdp->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);\r
        }\r
        else if (isr & AT91C_UDP_EPINT0) {\r
                pUdp->UDP_ICR = AT91C_UDP_EPINT0;\r
@@ -354,7 +379,7 @@ uint32_t usb_read(byte_t* data, size_t len) {
                        len -= packetSize;\r
                        while(packetSize--)\r
                                data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];\r
-                       pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank);\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
@@ -383,7 +408,7 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
        cpt = MIN(length, AT91C_EP_IN_SIZE-1);\r
        length -= cpt;\r
        while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++;\r
-       pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;\r
+       UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
 \r
        while (length) {\r
                // Fill the second bank\r
@@ -394,9 +419,9 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
                while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {\r
                        if (!usb_check()) return length;\r
     }\r
-               pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);\r
+               UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
                while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);\r
-               pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY;\r
+               UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);\r
        }\r
   \r
        // Wait for the end of transfer\r
@@ -404,7 +429,7 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
                if (!usb_check()) return length;\r
   }\r
   \r
-       pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP);\r
+       UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);\r
        while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP);\r
 \r
        return length;\r
@@ -428,27 +453,27 @@ static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t leng
                while (cpt--)\r
                        pUdp->UDP_FDR[0] = *pData++;\r
 \r
-               if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {\r
-                       pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);\r
-                       while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);\r
+               if (pUdp->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
                }\r
 \r
-               pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;\r
+               UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);\r
                do {\r
-                       csr = pUdp->UDP_CSR[0];\r
+                       csr = pUdp->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
-                               pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);\r
+                               UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);\r
                                return;\r
                        }\r
                } while ( !(csr & AT91C_UDP_TXCOMP) );\r
 \r
        } while (length);\r
 \r
-       if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) {\r
-               pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);\r
-               while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);\r
+       if (pUdp->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
        }\r
 }\r
 \r
@@ -457,10 +482,10 @@ static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t leng
 //* \brief Send zero length packet through the control endpoint\r
 //*----------------------------------------------------------------------------\r
 void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {\r
-       pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;\r
-       while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) );\r
-       pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);\r
-       while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP);\r
+       UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);\r
+       while ( !(pUdp->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
 }\r
 \r
 //*----------------------------------------------------------------------------\r
@@ -468,10 +493,10 @@ void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {
 //* \brief Stall the control endpoint\r
 //*----------------------------------------------------------------------------\r
 void AT91F_USB_SendStall(AT91PS_UDP pUdp) {\r
-       pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;\r
-       while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR) );\r
-       pUdp->UDP_CSR[0] &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);\r
-       while (pUdp->UDP_CSR[0] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));\r
+       UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL);\r
+       while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR) );\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
 }\r
 \r
 //*----------------------------------------------------------------------------\r
@@ -482,7 +507,7 @@ void AT91F_CDC_Enumerate() {
        byte_t bmRequestType, bRequest;\r
        uint16_t wValue, wIndex, wLength, wStatus;\r
 \r
-       if ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) )\r
+       if ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP) )\r
                return;\r
 \r
        bmRequestType = pUdp->UDP_FDR[0];\r
@@ -495,11 +520,11 @@ void AT91F_CDC_Enumerate() {
        wLength      |= (pUdp->UDP_FDR[0] << 8);\r
 \r
        if (bmRequestType & 0x80) {\r
-               pUdp->UDP_CSR[0] |= AT91C_UDP_DIR;\r
-               while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_DIR) );\r
+               UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_DIR);\r
+               while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR) );\r
        }\r
-       pUdp->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;\r
-       while ( (pUdp->UDP_CSR[0]  & AT91C_UDP_RXSETUP)  );\r
+       UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP);\r
+       while ( (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP)  );\r
 \r
        // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1\r
        switch ((bRequest << 8) | bmRequestType) {\r
@@ -595,8 +620,8 @@ void AT91F_CDC_Enumerate() {
 \r
        // handle CDC class requests\r
        case SET_LINE_CODING:\r
-               while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) );\r
-               pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0);\r
+               while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0) );\r
+               UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);\r
                AT91F_USB_SendZlp(pUdp);\r
                break;\r
        case GET_LINE_CODING:\r
Impressum, Datenschutz