2  * at91sam7s USB CDC device implementation 
   4  * Copyright (c) 2012, Roel Verdult 
   7  * Redistribution and use in source and binary forms, with or without 
   8  * modification, are permitted provided that the following conditions are met: 
   9  * 1. Redistributions of source code must retain the above copyright 
  10  * notice, this list of conditions and the following disclaimer. 
  11  * 2. Redistributions in binary form must reproduce the above copyright 
  12  * notice, this list of conditions and the following disclaimer in the 
  13  * documentation and/or other materials provided with the distribution. 
  14  * 3. Neither the name of the copyright holders nor the 
  15  * names of its contributors may be used to endorse or promote products 
  16  * derived from this software without specific prior written permission. 
  18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY 
  19  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
  20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
  21  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY 
  22  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
  23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
  24  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 
  25  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
  26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
  27  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
  29  * based on the "Basic USB Example" from ATMEL (doc6123.pdf) 
  36 #include "at91sam7s512.h" 
  37 #include "config_gpio.h" 
  40 #define AT91C_EP_CONTROL     0 
  41 #define AT91C_EP_IN_SIZE  0x40 
  42 #define AT91C_EP_OUT         1 
  43 #define AT91C_EP_OUT_SIZE 0x40 
  46 static const char devDescriptor
[] = { 
  47         /* Device descriptor */ 
  49         0x01,      // bDescriptorType 
  50         0x00,0x02, // Complies with USB Spec. Release (0200h = release 2.0) 
  51         0x02,      // bDeviceClass:    CDC class code 
  52         0x00,      // bDeviceSubclass: CDC class sub code 
  53         0x00,      // bDeviceProtocol: CDC Device protocol 
  54         0x08,      // bMaxPacketSize0 
  55         0xc4,0x9a, // Vendor ID (0x9ac4 = J. Westhues) 
  56         0x8f,0x4b, // Product ID (0x4b8f = Proxmark-3 RFID Instrument) 
  57         0x01,0x00, // Device release number (0001) 
  58         0x01,      // iManufacturer 
  60         0x00,      // iSerialNumber 
  64 static const char cfgDescriptor
[] = { 
  65         /* ============== CONFIGURATION 1 =========== */ 
  66         /* Configuration 1 descriptor */ 
  68         0x02,   // CbDescriptorType 
  69         0x43,   // CwTotalLength 2 EP + Control 
  71         0x02,   // CbNumInterfaces 
  72         0x01,   // CbConfigurationValue 
  73         0x00,   // CiConfiguration 
  74         0xC0,   // CbmAttributes 0xA0 
  77         /* Communication Class Interface Descriptor Requirement */ 
  79         0x04, // bDescriptorType 
  80         0x00, // bInterfaceNumber 
  81         0x00, // bAlternateSetting 
  82         0x01, // bNumEndpoints 
  83         0x02, // bInterfaceClass 
  84         0x02, // bInterfaceSubclass 
  85         0x01, // bInterfaceProtocol 
  88         /* Header Functional Descriptor */ 
  89         0x05, // bFunction Length 
  90         0x24, // bDescriptor type: CS_INTERFACE 
  91         0x00, // bDescriptor subtype: Header Func Desc 
  95         /* ACM Functional Descriptor */ 
  96         0x04, // bFunctionLength 
  97         0x24, // bDescriptor Type: CS_INTERFACE 
  98         0x02, // bDescriptor Subtype: ACM Func Desc 
  99         0x02, // bmCapabilities 
 101         /* Union Functional Descriptor */ 
 102         0x05, // bFunctionLength 
 103         0x24, // bDescriptorType: CS_INTERFACE 
 104         0x06, // bDescriptor Subtype: Union Func Desc 
 105         0x00, // bMasterInterface: Communication Class Interface 
 106         0x01, // bSlaveInterface0: Data Class Interface 
 108         /* Call Management Functional Descriptor */ 
 109         0x05, // bFunctionLength 
 110         0x24, // bDescriptor Type: CS_INTERFACE 
 111         0x01, // bDescriptor Subtype: Call Management Func Desc 
 112         0x00, // bmCapabilities: D1 + D0 
 113         0x01, // bDataInterface: Data Class Interface 1 
 115         /* Endpoint 1 descriptor */ 
 117         0x05,   // bDescriptorType 
 118         0x83,   // bEndpointAddress, Endpoint 03 - IN 
 119         0x03,   // bmAttributes      INT 
 120         0x08,   // wMaxPacketSize 
 124         /* Data Class Interface Descriptor Requirement */ 
 126         0x04, // bDescriptorType 
 127         0x01, // bInterfaceNumber 
 128         0x00, // bAlternateSetting 
 129         0x02, // bNumEndpoints 
 130         0x0A, // bInterfaceClass 
 131         0x00, // bInterfaceSubclass 
 132         0x00, // bInterfaceProtocol 
 135         /* First alternate setting */ 
 136         /* Endpoint 1 descriptor */ 
 138         0x05,   // bDescriptorType 
 139         0x01,   // bEndpointAddress, Endpoint 01 - OUT 
 140         0x02,   // bmAttributes      BULK 
 141         AT91C_EP_OUT_SIZE
,   // wMaxPacketSize 
 145         /* Endpoint 2 descriptor */ 
 147         0x05,   // bDescriptorType 
 148         0x82,   // bEndpointAddress, Endpoint 02 - IN 
 149         0x02,   // bmAttributes      BULK 
 150         AT91C_EP_IN_SIZE
,   // wMaxPacketSize 
 155 static const char StrDescLanguageCodes
[] = { 
 157   0x03,                 // Type is string 
 158   0x09, 0x04    // supported language Code 0 = 0x0409 (English) 
 161 static const char StrDescManufacturer
[] = { 
 163   0x03,                 // Type is string 
 178 static const char StrDescProduct
[] = { 
 180   0x03,                 // Type is string 
 186 static const char* const pStrings
[] = 
 188     StrDescLanguageCodes
, 
 193 const char* getStringDescriptor(uint8_t idx
) 
 195     if(idx 
>= (sizeof(pStrings
) / sizeof(pStrings
[0]))) { 
 198                 return(pStrings
[idx
]); 
 202 // Bitmap for all status bits in CSR which must be written as 1 to cause no effect 
 203 #define REG_NO_EFFECT_1_ALL      AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \ 
 204                                 |AT91C_UDP_STALLSENT   | AT91C_UDP_RXSETUP \ 
 207 // Clear flags in the UDP_CSR register 
 208 #define UDP_CLEAR_EP_FLAGS(endpoint, flags) { \ 
 209         volatile unsigned int reg; \ 
 210         reg = pUdp->UDP_CSR[(endpoint)]; \ 
 211         reg |= REG_NO_EFFECT_1_ALL; \ 
 213         pUdp->UDP_CSR[(endpoint)] = reg; \ 
 216 // Set flags in the UDP_CSR register 
 217 #define UDP_SET_EP_FLAGS(endpoint, flags) { \ 
 218         volatile unsigned int reg; \ 
 219         reg = pUdp->UDP_CSR[(endpoint)]; \ 
 220         reg |= REG_NO_EFFECT_1_ALL; \ 
 222         pUdp->UDP_CSR[(endpoint)] = reg; \ 
 225 /* USB standard request codes */ 
 226 #define STD_GET_STATUS_ZERO           0x0080 
 227 #define STD_GET_STATUS_INTERFACE      0x0081 
 228 #define STD_GET_STATUS_ENDPOINT       0x0082 
 230 #define STD_CLEAR_FEATURE_ZERO        0x0100 
 231 #define STD_CLEAR_FEATURE_INTERFACE   0x0101 
 232 #define STD_CLEAR_FEATURE_ENDPOINT    0x0102 
 234 #define STD_SET_FEATURE_ZERO          0x0300 
 235 #define STD_SET_FEATURE_INTERFACE     0x0301 
 236 #define STD_SET_FEATURE_ENDPOINT      0x0302 
 238 #define STD_SET_ADDRESS               0x0500 
 239 #define STD_GET_DESCRIPTOR            0x0680 
 240 #define STD_SET_DESCRIPTOR            0x0700 
 241 #define STD_GET_CONFIGURATION         0x0880 
 242 #define STD_SET_CONFIGURATION         0x0900 
 243 #define STD_GET_INTERFACE             0x0A81 
 244 #define STD_SET_INTERFACE             0x0B01 
 245 #define STD_SYNCH_FRAME               0x0C82 
 247 /* CDC Class Specific Request Code */ 
 248 #define GET_LINE_CODING               0x21A1 
 249 #define SET_LINE_CODING               0x2021 
 250 #define SET_CONTROL_LINE_STATE        0x2221 
 253         unsigned int dwDTERRate
; 
 257 } AT91S_CDC_LINE_CODING
, *AT91PS_CDC_LINE_CODING
; 
 259 AT91S_CDC_LINE_CODING line 
= { 
 265 void AT91F_CDC_Enumerate(); 
 267 AT91PS_UDP pUdp 
= AT91C_BASE_UDP
; 
 268 byte_t btConfiguration 
= 0; 
 269 byte_t btConnection    
= 0; 
 270 byte_t btReceiveBank   
= AT91C_UDP_RX_DATA_BK0
; 
 272 //*---------------------------------------------------------------------------- 
 274 //* \brief This function deactivates the USB device 
 275 //*---------------------------------------------------------------------------- 
 277   // Disconnect the USB device 
 278   AT91C_BASE_PIOA
->PIO_ODR 
= GPIO_USB_PU
; 
 280   // Clear all lingering interrupts 
 281   if(pUdp
->UDP_ISR 
& AT91C_UDP_ENDBUSRES
) { 
 282     pUdp
->UDP_ICR 
= AT91C_UDP_ENDBUSRES
; 
 286 //*---------------------------------------------------------------------------- 
 288 //* \brief This function Activates the USB device 
 289 //*---------------------------------------------------------------------------- 
 291   // Set the PLL USB Divider 
 292   AT91C_BASE_CKGR
->CKGR_PLLR 
|= AT91C_CKGR_USBDIV_1 
; 
 294   // Specific Chip USB Initialisation 
 295   // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock 
 296   AT91C_BASE_PMC
->PMC_SCER 
= AT91C_PMC_UDP
; 
 297   AT91C_BASE_PMC
->PMC_PCER 
= (1 << AT91C_ID_UDP
); 
 299   // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO 
 300   // Set in PIO mode and Configure in Output 
 301   AT91C_BASE_PIOA
->PIO_PER 
= GPIO_USB_PU
; // Set in PIO mode 
 302         AT91C_BASE_PIOA
->PIO_OER 
= GPIO_USB_PU
; // Configure as Output 
 304   // Clear for set the Pullup resistor 
 305         AT91C_BASE_PIOA
->PIO_CODR 
= GPIO_USB_PU
; 
 307   // Disconnect and reconnect USB controller for 100ms 
 310   // Wait for a short while 
 311   for (volatile size_t i
=0; i
<0x100000; i
++); 
 313   // Reconnect USB reconnect 
 314   AT91C_BASE_PIOA
->PIO_SODR 
= GPIO_USB_PU
; 
 315   AT91C_BASE_PIOA
->PIO_OER 
= GPIO_USB_PU
; 
 318 //*---------------------------------------------------------------------------- 
 320 //* \brief Test if the device is configured and handle enumeration 
 321 //*---------------------------------------------------------------------------- 
 323         AT91_REG isr 
= pUdp
->UDP_ISR
; 
 325         if (isr 
& AT91C_UDP_ENDBUSRES
) { 
 326                 pUdp
->UDP_ICR 
= AT91C_UDP_ENDBUSRES
; 
 327                 // reset all endpoints 
 328                 pUdp
->UDP_RSTEP  
= (unsigned int)-1; 
 330                 // Enable the function 
 331                 pUdp
->UDP_FADDR 
= AT91C_UDP_FEN
; 
 332                 // Configure endpoint 0 
 333                 pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] = (AT91C_UDP_EPEDS 
| AT91C_UDP_EPTYPE_CTRL
); 
 335         else if (isr 
& AT91C_UDP_EPINT0
) { 
 336                 pUdp
->UDP_ICR 
= AT91C_UDP_EPINT0
; 
 337                 AT91F_CDC_Enumerate(); 
 339         return (btConfiguration
) ? true : false; 
 345   if (!usb_check()) return false; 
 346   return (pUdp
->UDP_CSR
[AT91C_EP_OUT
] & btReceiveBank
); 
 350         In github PR #129, some users appears to get a false positive from 
 351         usb_poll, which returns true, but the usb_read operation 
 353         This check is basically the same as above, but also checks 
 354         that the length available to read is non-zero, thus hopefully fixes the 
 357 bool usb_poll_validate_length() 
 360         if (!usb_check()) return false; 
 361         if (!(pUdp
->UDP_CSR
[AT91C_EP_OUT
] & btReceiveBank
)) return false; 
 362         return (pUdp
->UDP_CSR
[AT91C_EP_OUT
] >> 16) >  0; 
 365 //*---------------------------------------------------------------------------- 
 367 //* \brief Read available data from Endpoint OUT 
 368 //*---------------------------------------------------------------------------- 
 369 uint32_t usb_read(byte_t
* data
, size_t len
) { 
 370         byte_t bank 
= btReceiveBank
; 
 371         uint32_t packetSize
, nbBytesRcv 
= 0; 
 372         uint32_t time_out 
= 0; 
 375                 if (!usb_check()) break; 
 377                 if ( pUdp
->UDP_CSR
[AT91C_EP_OUT
] & bank 
) { 
 378                         packetSize 
= MIN(pUdp
->UDP_CSR
[AT91C_EP_OUT
] >> 16, len
); 
 381                                 data
[nbBytesRcv
++] = pUdp
->UDP_FDR
[AT91C_EP_OUT
]; 
 382                         UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT
, bank
); 
 383                         if (bank 
== AT91C_UDP_RX_DATA_BK0
) { 
 384                                 bank 
= AT91C_UDP_RX_DATA_BK1
; 
 386                                 bank 
= AT91C_UDP_RX_DATA_BK0
; 
 389                 if (time_out
++ == 0x1fff) break; 
 392         btReceiveBank 
= bank
; 
 396 //*---------------------------------------------------------------------------- 
 398 //* \brief Send through endpoint 2 
 399 //*---------------------------------------------------------------------------- 
 400 uint32_t usb_write(const byte_t
* data
, const size_t len
) { 
 404   if (!length
) return 0; 
 405   if (!usb_check()) return 0; 
 407         // Send the first packet 
 408         cpt 
= MIN(length
, AT91C_EP_IN_SIZE
-1); 
 410         while (cpt
--) pUdp
->UDP_FDR
[AT91C_EP_IN
] = *data
++; 
 411         UDP_SET_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXPKTRDY
); 
 414                 // Fill the second bank 
 415                 cpt 
= MIN(length
, AT91C_EP_IN_SIZE
-1); 
 417                 while (cpt
--) pUdp
->UDP_FDR
[AT91C_EP_IN
] = *data
++; 
 418                 // Wait for the first bank to be sent 
 419                 while (!(pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
)) { 
 420                         if (!usb_check()) return length
; 
 422                 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXCOMP
); 
 423                 while (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
); 
 424                 UDP_SET_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXPKTRDY
); 
 427         // Wait for the end of transfer 
 428         while (!(pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
)) { 
 429                 if (!usb_check()) return length
; 
 432         UDP_CLEAR_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXCOMP
); 
 433         while (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
); 
 438 //*---------------------------------------------------------------------------- 
 439 //* \fn    AT91F_USB_SendData 
 440 //* \brief Send Data through the control endpoint 
 441 //*---------------------------------------------------------------------------- 
 442 unsigned int csrTab
[100] = {0x00}; 
 443 unsigned char csrIdx 
= 0; 
 445 static void AT91F_USB_SendData(AT91PS_UDP pUdp
, const char *pData
, uint32_t length
) { 
 450                 cpt 
= MIN(length
, 8); 
 454                         pUdp
->UDP_FDR
[0] = *pData
++; 
 456                 if (pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
) { 
 457                         UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_TXCOMP
); 
 458                         while (pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
); 
 461                 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_TXPKTRDY
); 
 463                         csr 
= pUdp
->UDP_CSR
[AT91C_EP_CONTROL
]; 
 465                         // Data IN stage has been stopped by a status OUT 
 466                         if (csr 
& AT91C_UDP_RX_DATA_BK0
) { 
 467                                 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_RX_DATA_BK0
); 
 470                 } while ( !(csr 
& AT91C_UDP_TXCOMP
) ); 
 474         if (pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
) { 
 475                 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_TXCOMP
); 
 476                 while (pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
); 
 480 //*---------------------------------------------------------------------------- 
 481 //* \fn    AT91F_USB_SendZlp 
 482 //* \brief Send zero length packet through the control endpoint 
 483 //*---------------------------------------------------------------------------- 
 484 void AT91F_USB_SendZlp(AT91PS_UDP pUdp
) { 
 485         UDP_SET_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_TXPKTRDY
); 
 486         while ( !(pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
) ); 
 487         UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_TXCOMP
); 
 488         while (pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
); 
 491 //*---------------------------------------------------------------------------- 
 492 //* \fn    AT91F_USB_SendStall 
 493 //* \brief Stall the control endpoint 
 494 //*---------------------------------------------------------------------------- 
 495 void AT91F_USB_SendStall(AT91PS_UDP pUdp
) { 
 496         UDP_SET_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_FORCESTALL
); 
 497         while ( !(pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_ISOERROR
) ); 
 498         UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_FORCESTALL 
| AT91C_UDP_ISOERROR
); 
 499         while (pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & (AT91C_UDP_FORCESTALL 
| AT91C_UDP_ISOERROR
)); 
 502 //*---------------------------------------------------------------------------- 
 503 //* \fn    AT91F_CDC_Enumerate 
 504 //* \brief This function is a callback invoked when a SETUP packet is received 
 505 //*---------------------------------------------------------------------------- 
 506 void AT91F_CDC_Enumerate() { 
 507         byte_t bmRequestType
, bRequest
; 
 508         uint16_t wValue
, wIndex
, wLength
, wStatus
; 
 510         if ( !(pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_RXSETUP
) ) 
 513         bmRequestType 
= pUdp
->UDP_FDR
[0]; 
 514         bRequest      
= pUdp
->UDP_FDR
[0]; 
 515         wValue        
= (pUdp
->UDP_FDR
[0] & 0xFF); 
 516         wValue       
|= (pUdp
->UDP_FDR
[0] << 8); 
 517         wIndex        
= (pUdp
->UDP_FDR
[0] & 0xFF); 
 518         wIndex       
|= (pUdp
->UDP_FDR
[0] << 8); 
 519         wLength       
= (pUdp
->UDP_FDR
[0] & 0xFF); 
 520         wLength      
|= (pUdp
->UDP_FDR
[0] << 8); 
 522         if (bmRequestType 
& 0x80) { 
 523                 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_DIR
); 
 524                 while ( !(pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_DIR
) ); 
 526         UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_RXSETUP
); 
 527         while ( (pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_RXSETUP
)  ); 
 529         // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1 
 530         switch ((bRequest 
<< 8) | bmRequestType
) { 
 531         case STD_GET_DESCRIPTOR
: 
 532                 if (wValue 
== 0x100)       // Return Device Descriptor 
 533                         AT91F_USB_SendData(pUdp
, devDescriptor
, MIN(sizeof(devDescriptor
), wLength
)); 
 534                 else if (wValue 
== 0x200)  // Return Configuration Descriptor 
 535                         AT91F_USB_SendData(pUdp
, cfgDescriptor
, MIN(sizeof(cfgDescriptor
), wLength
)); 
 536                 else if ((wValue 
& 0xF00) == 0x300) { // Return String Descriptor 
 537                         const char *strDescriptor 
= getStringDescriptor(wValue 
& 0xff); 
 538                         if (strDescriptor 
!= NULL
) { 
 539                                 AT91F_USB_SendData(pUdp
, strDescriptor
, MIN(strDescriptor
[0], wLength
)); 
 541                                 AT91F_USB_SendStall(pUdp
); 
 545                         AT91F_USB_SendStall(pUdp
); 
 547         case STD_SET_ADDRESS
: 
 548                 AT91F_USB_SendZlp(pUdp
); 
 549                 pUdp
->UDP_FADDR 
= (AT91C_UDP_FEN 
| wValue
); 
 550                 pUdp
->UDP_GLBSTATE  
= (wValue
) ? AT91C_UDP_FADDEN 
: 0; 
 552         case STD_SET_CONFIGURATION
: 
 553                 btConfiguration 
= wValue
; 
 554                 AT91F_USB_SendZlp(pUdp
); 
 555                 pUdp
->UDP_GLBSTATE  
= (wValue
) ? AT91C_UDP_CONFG 
: AT91C_UDP_FADDEN
; 
 556                 pUdp
->UDP_CSR
[1] = (wValue
) ? (AT91C_UDP_EPEDS 
| AT91C_UDP_EPTYPE_BULK_OUT
) : 0; 
 557                 pUdp
->UDP_CSR
[2] = (wValue
) ? (AT91C_UDP_EPEDS 
| AT91C_UDP_EPTYPE_BULK_IN
)  : 0; 
 558                 pUdp
->UDP_CSR
[3] = (wValue
) ? (AT91C_UDP_EPEDS 
| AT91C_UDP_EPTYPE_INT_IN
)   : 0; 
 560         case STD_GET_CONFIGURATION
: 
 561                 AT91F_USB_SendData(pUdp
, (char *) &(btConfiguration
), sizeof(btConfiguration
)); 
 563         case STD_GET_STATUS_ZERO
: 
 565                 AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
)); 
 567         case STD_GET_STATUS_INTERFACE
: 
 569                 AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
)); 
 571         case STD_GET_STATUS_ENDPOINT
: 
 574                 if ((pUdp
->UDP_GLBSTATE 
& AT91C_UDP_CONFG
) && (wIndex 
<= 3)) { 
 575                         wStatus 
= (pUdp
->UDP_CSR
[wIndex
] & AT91C_UDP_EPEDS
) ? 0 : 1; 
 576                         AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
)); 
 578                 else if ((pUdp
->UDP_GLBSTATE 
& AT91C_UDP_FADDEN
) && (wIndex 
== 0)) { 
 579                         wStatus 
= (pUdp
->UDP_CSR
[wIndex
] & AT91C_UDP_EPEDS
) ? 0 : 1; 
 580                         AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
)); 
 583                         AT91F_USB_SendStall(pUdp
); 
 585         case STD_SET_FEATURE_ZERO
: 
 586                 AT91F_USB_SendStall(pUdp
); 
 588         case STD_SET_FEATURE_INTERFACE
: 
 589                 AT91F_USB_SendZlp(pUdp
); 
 591         case STD_SET_FEATURE_ENDPOINT
: 
 593                 if ((wValue 
== 0) && wIndex 
&& (wIndex 
<= 3)) { 
 594                         pUdp
->UDP_CSR
[wIndex
] = 0; 
 595                         AT91F_USB_SendZlp(pUdp
); 
 598                         AT91F_USB_SendStall(pUdp
); 
 600         case STD_CLEAR_FEATURE_ZERO
: 
 601                 AT91F_USB_SendStall(pUdp
); 
 603         case STD_CLEAR_FEATURE_INTERFACE
: 
 604                 AT91F_USB_SendZlp(pUdp
); 
 606         case STD_CLEAR_FEATURE_ENDPOINT
: 
 608                 if ((wValue 
== 0) && wIndex 
&& (wIndex 
<= 3)) { 
 610                                 pUdp
->UDP_CSR
[1] = (AT91C_UDP_EPEDS 
| AT91C_UDP_EPTYPE_BULK_OUT
); 
 611                         else if (wIndex 
== 2) 
 612                                 pUdp
->UDP_CSR
[2] = (AT91C_UDP_EPEDS 
| AT91C_UDP_EPTYPE_BULK_IN
); 
 613                         else if (wIndex 
== 3) 
 614                                 pUdp
->UDP_CSR
[3] = (AT91C_UDP_EPEDS 
| AT91C_UDP_EPTYPE_INT_IN
); 
 615                         AT91F_USB_SendZlp(pUdp
); 
 618                         AT91F_USB_SendStall(pUdp
); 
 621         // handle CDC class requests 
 622         case SET_LINE_CODING
: 
 623                 while ( !(pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_RX_DATA_BK0
) ); 
 624                 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_RX_DATA_BK0
); 
 625                 AT91F_USB_SendZlp(pUdp
); 
 627         case GET_LINE_CODING
: 
 628                 AT91F_USB_SendData(pUdp
, (char *) &line
, MIN(sizeof(line
), wLength
)); 
 630         case SET_CONTROL_LINE_STATE
: 
 631                 btConnection 
= wValue
; 
 632                 AT91F_USB_SendZlp(pUdp
); 
 635                 AT91F_USB_SendStall(pUdp
);