#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
        }\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
                // 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
                        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
        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
                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
                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
                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
 //* \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
 //* \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
        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
        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
 \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