1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // at91sam7s USB CDC device implementation
17 // based on the "Basic USB Example" from ATMEL (doc6123.pdf)
18 //-----------------------------------------------------------------------------
21 #include "proxmark3_arm.h"
22 #include "usart_defs.h"
25 AT91SAM7S256 USB Device Port
26 • Embedded 328-byte dual-port RAM for endpoints
29 – Endpoint 1 and 2: 64 bytes ping-pong
30 – Endpoint 3: 64 bytes
31 – Ping-pong Mode (two memory banks) for bulk endpoints
35 #define AT91C_EP_CONTROL 0
36 #define AT91C_EP_OUT 1 // cfg bulk out
37 #define AT91C_EP_IN 2 // cfg bulk in
38 #define AT91C_EP_NOTIFY 3 // cfg cdc notification interrup
40 // The endpoint size is defined in usb_cdc.h
42 // Section: USB Descriptors
43 #define USB_DESCRIPTOR_DEVICE 0x01 // DescriptorType for a Device Descriptor.
44 #define USB_DESCRIPTOR_CONFIGURATION 0x02 // DescriptorType for a Configuration Descriptor.
45 #define USB_DESCRIPTOR_STRING 0x03 // DescriptorType for a String Descriptor.
46 #define USB_DESCRIPTOR_INTERFACE 0x04 // DescriptorType for an Interface Descriptor.
47 #define USB_DESCRIPTOR_ENDPOINT 0x05 // DescriptorType for an Endpoint Descriptor.
48 #define USB_DESCRIPTOR_DEVICE_QUALIFIER 0x06 // DescriptorType for a Device Qualifier.
49 #define USB_DESCRIPTOR_OTHER_SPEED 0x07 // DescriptorType for a Other Speed Configuration.
50 #define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // DescriptorType for Interface Power.
51 #define USB_DESCRIPTOR_OTG 0x09 // DescriptorType for an OTG Descriptor.
52 #define USB_DESCRIPTOR_IAD 0x0B // DescriptorType for a Interface Association Descriptor
53 #define USB_DESCRIPTOR_TYPE_BO 0x0F // DescriptorType for a BOS Descriptor.
55 /* Configuration Attributes */
56 #define _DEFAULT (0x01<<7) //Default Value (Bit 7 is set)
57 #define _SELF (0x01<<6) //Self-powered (Supports if set)
58 #define _RWU (0x01<<5) //Remote Wakeup (Supports if set)
59 #define _HNP (0x01 << 1) //HNP (Supports if set)
60 #define _SRP (0x01) //SRP (Supports if set)
62 /* Endpoint Transfer Type */
63 #define _CTRL 0x00 //Control Transfer
64 #define _ISO 0x01 //Isochronous Transfer
65 #define _BULK 0x02 //Bulk Transfer
66 #define _INTERRUPT 0x03 //Interrupt Transfer
68 // (bit7 | 0 = OUT, 1 = IN)
71 #define _EP01_OUT 0x01
73 #define _EP02_OUT 0x02
75 #define _EP03_OUT 0x03
79 /* WCID specific Request Code */
80 #define MS_OS_DESCRIPTOR_INDEX 0xEE
81 #define MS_VENDOR_CODE 0x1C
82 #define MS_EXTENDED_COMPAT_ID 0x04
83 #define MS_EXTENDED_PROPERTIES 0x05
84 #define MS_WCID_GET_DESCRIPTOR 0xC0
85 #define MS_WCID_GET_FEATURE_DESCRIPTOR 0xC1
87 /* USB standard request code */
88 #define STD_GET_STATUS_ZERO 0x0080
89 #define STD_GET_STATUS_INTERFACE 0x0081
90 #define STD_GET_STATUS_ENDPOINT 0x0082
92 #define STD_CLEAR_FEATURE_ZERO 0x0100
93 #define STD_CLEAR_FEATURE_INTERFACE 0x0101
94 #define STD_CLEAR_FEATURE_ENDPOINT 0x0102
96 #define STD_SET_FEATURE_ZERO 0x0300
97 #define STD_SET_FEATURE_INTERFACE 0x0301
98 #define STD_SET_FEATURE_ENDPOINT 0x0302
100 #define STD_SET_ADDRESS 0x0500
101 #define STD_GET_DESCRIPTOR 0x0680
102 #define STD_SET_DESCRIPTOR 0x0700
103 #define STD_GET_CONFIGURATION 0x0880
104 #define STD_SET_CONFIGURATION 0x0900
105 #define STD_GET_INTERFACE 0x0A81
106 #define STD_SET_INTERFACE 0x0B01
107 #define STD_SYNCH_FRAME 0x0C82
109 /* CDC Class Specific Request Code */
110 #define GET_LINE_CODING 0x21A1
111 #define SET_LINE_CODING 0x2021
112 #define SET_CONTROL_LINE_STATE 0x2221
114 static bool isAsyncRequestFinished
= false;
115 static AT91PS_UDP pUdp
= AT91C_BASE_UDP
;
116 static uint8_t btConfiguration
= 0;
117 static uint8_t btConnection
= 0;
118 static uint8_t btReceiveBank
= AT91C_UDP_RX_DATA_BK0
;
120 static const char devDescriptor
[] = {
121 /* Device descriptor */
123 USB_DESCRIPTOR_DEVICE
, // Descriptor Type (DEVICE)
124 0x00, 0x02, // Complies with USB Spec. Release (0200h = release 2.00) 0210 == release 2.10
125 2, // Device Class: Communication Device Class
126 0, // Device Subclass: CDC class sub code ACM [ice 0x02 = win10 virtual comport ]
127 0, // Device Protocol: CDC Device protocol (unused)
128 AT91C_USB_EP_CONTROL_SIZE
, // MaxPacketSize0
129 0xc4, 0x9a, // Vendor ID [0x9ac4 = J. Westhues]
130 0x8f, 0x4b, // Product ID [0x4b8f = Proxmark-3 RFID Instrument]
131 0x00, 0x01, // BCD Device release number (1.00)
132 1, // index Manufacturer
134 3, // index SerialNumber
135 1 // Number of Configs
138 static const char cfgDescriptor
[] = {
140 /* Configuration 1 descriptor */
141 // -----------------------------
143 USB_DESCRIPTOR_CONFIGURATION
, // Descriptor Type
144 (9 + 9 + 5 + 5 + 4 + 5 + 7 + 9 + 7 + 7), 0, // Total Length 2 EP + Control
145 2, // Number of Interfaces
146 1, // Index value of this Configuration (used in SetConfiguration from Host)
147 0, // Configuration string index
148 _DEFAULT
, // Attributes 0xA0
149 0xFA, // Max Power consumption
151 // IAD to associate the one CDC interface
152 // --------------------------------------
155 USB_DESCRIPTOR_IAD, // IAD_DESCRIPTOR (0x0B)
156 0, // CDC_INT_INTERFACE NUMBER (
157 2, // IAD INTERFACE COUNT (two interfaces)
158 2, // Function Class: CDC_CLASS
159 2, // Function SubClass: ACM
160 1, // Function Protocol: v.25term
164 /* Interface 0 Descriptor */
165 /* CDC Communication Class Interface Descriptor Requirement for Notification*/
166 // -----------------------------------------------------------
168 USB_DESCRIPTOR_INTERFACE
, // Descriptor Type
169 0, // Interface Number
170 0, // Alternate Setting
171 1, // Number of Endpoints in this interface
172 2, // Interface Class code (Communication Interface Class)
173 2, // Interface Subclass code (Abstract Control Model)
174 1, // InterfaceProtocol (Common AT Commands, V.25term)
177 /* Header Functional Descriptor */
178 5, // Function Length
179 0x24, // Descriptor type: CS_INTERFACE
180 0, // Descriptor subtype: Header Functional Descriptor
181 0x10, 0x01, // bcd CDC:1.1
183 /* ACM Functional Descriptor */
184 4, // Function Length
185 0x24, // Descriptor Type: CS_INTERFACE
186 2, // Descriptor Subtype: Abstract Control Management Functional Descriptor
187 2, // Capabilities D1, Device supports the request combination of Set_Line_Coding, Set_Control_Line_State, Get_Line_Coding, and the notification Serial_State
189 /* Union Functional Descriptor */
190 5, // Function Length
191 0x24, // Descriptor Type: CS_INTERFACE
192 6, // Descriptor Subtype: Union Functional Descriptor
193 0, // MasterInterface: Communication Class Interface
194 1, // SlaveInterface0: Data Class Interface
196 /* Call Management Functional Descriptor */
197 5, // Function Length
198 0x24, // Descriptor Type: CS_INTERFACE
199 1, // Descriptor Subtype: Call Management Functional Descriptor
200 0, // Capabilities: Device sends/receives call management information only over the Communication Class interface. Device does not handle call management itself
201 1, // Data Interface: Data Class Interface
203 /* Protocol Functional Descriptor */
206 0x24, // Descriptor Type: CS_INTERFACE
207 0x0B, // Descriptor Subtype: Protocol Unit functional Descriptor
208 0xDD, // constant uniq ID of unit
212 /* CDC Notification Endpoint descriptor */
213 // ---------------------------------------
215 USB_DESCRIPTOR_ENDPOINT
, // Descriptor Type
216 _EP03_IN
, // EndpointAddress: Endpoint 03 - IN
217 _INTERRUPT
, // Attributes
218 AT91C_USB_EP_CONTROL_SIZE
, 0x00, // MaxPacket Size: EP0 - 8
219 0xFF, // Interval polling
222 /* Interface 1 Descriptor */
223 /* CDC Data Class Interface 1 Descriptor Requirement */
225 USB_DESCRIPTOR_INTERFACE
, // Descriptor Type
226 1, // Interface Number
227 0, // Alternate Setting
228 2, // Number of Endpoints
229 0x0A, // Interface Class: CDC Data interface class
230 0, // Interface Subclass: not used
231 0, // Interface Protocol: No class specific protocol required (usb spec)
234 /* Endpoint descriptor */
236 USB_DESCRIPTOR_ENDPOINT
, // Descriptor Type
237 _EP01_OUT
, // Endpoint Address: Endpoint 01 - OUT
238 _BULK
, // Attributes: BULK
239 AT91C_USB_EP_OUT_SIZE
, 0x00, // MaxPacket Size: 64 bytes
240 0, // Interval: ignored for bulk
242 /* Endpoint descriptor */
244 USB_DESCRIPTOR_ENDPOINT
, // Descriptor Type
245 _EP02_IN
, // Endpoint Address: Endpoint 02 - IN
246 _BULK
, // Attribute: BULK
247 AT91C_USB_EP_IN_SIZE
, 0x00, // MaxPacket Size: 64 bytes
248 0 // Interval: ignored for bulk
252 static const char bosDescriptor
[] = {
254 USB_DESCRIPTOR_TYPE_BO
,
257 0x1, // 1 device capability
259 0x10, // USB_DEVICE_CAPABITY_TYPE,
261 0x2, // LPM capability bit set
267 // Microsoft OS Extended Configuration Compatible ID Descriptor
269 static const char CompatIDFeatureDescriptor[] = {
270 0x28, 0x00, 0x00, 0x00, // Descriptor Length 40bytes (0x28)
271 0x00, 0x01, // Version ('1.0')
272 MS_EXTENDED_COMPAT_ID, 0x00, // Compatibility ID Descriptor Index 0x0004
273 0x01, // Number of sections. 0x1
274 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Reserved (7bytes)
275 // -----function section 1------
276 0x00, // Interface Number #0
277 0x01, // reserved (0x1)
278 0x57, 0x49, 0x4E, 0x55, 0x53, 0x42, 0x00, 0x00, // Compatible ID ('WINUSB\0\0') (8bytes)
279 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Sub-Compatible ID (8byte)
280 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Reserved (6bytes)
284 // Microsoft Extended Properties Feature Descriptor
286 static const char OSprop[] = {
287 // u32 Descriptor Length (10+132+64+102 == 308
289 // u16 Version ('1.0')
292 MS_EXTENDED_PROPERTIES, 0,
293 // u16 wCount -- three section
296 // -----property section 1------
297 // u32 size ( 14+40+78 == 132)
300 1, 0, 0, 0, // unicode string
301 // u16 namelen (20*2 = 40)
303 // name DeviceInterfaceGUID
304 'D',0,'e',0,'v',0,'i',0,'c',0,'e',0,'I',0,'n',0,'t',0,'e',0,'r',0,'f',0,'a',0,'c',0,'e',0,'G',0,'U',0,'I',0,'D',0,0,0,
305 // u32 datalen (39*2 = 78)
307 // data {4D36E978-E325-11CE-BFC1-08002BE10318}
308 '{',0,'4',0,'d',0,'3',0,'6',0,'e',0,'9',0,'7',0,'8',0,'-',0,'e',0,'3',0,'2',0,'5',0,
309 '-',0,'1',0,'1',0,'c',0,'e',0,'-',0,'b',0,'f',0,'c',0,'1',0,'-',0,'0',0,'8',0,'0',0,
310 '0',0,'2',0,'b',0,'e',0,'1',0,'0',0,'3',0,'1',0,'8',0,'}',0,0,0,
312 // -----property section 2------
313 // u32 size ( 14+12+38 == 64)
316 1, 0, 0, 0, // unicode string
320 'L',0,'a',0,'b',0,'e',0,'l',0,0,0,
321 // u32 datalen ( 19*2 = 38 )
323 // data 'Awesome PM3 Device'
324 'A',0,'w',0,'e',0,'s',0,'o',0,'m',0,'e',0,' ',0,'P',0,'M',0,'3',0,' ',0,'D',0,'e',0,'v',0,'i',0,'c',0,'e',0,0,0,
326 // -----property section 3------
327 // u32 size ( 14+12+76 == 102)
330 2, 0, 0, 0, //Unicode string with environment variables
334 'I',0,'c',0,'o',0,'n',0,'s',0,0,0,
335 // u32 datalen ( 38*2 == 76)
337 // data '%SystemRoot%\\system32\\Shell32.dll,-13'
338 '%',0,'S',0,'y',0,'s',0,'t',0,'e',0,'m',0,'R',0,'o',0,'o',0,'t',0,'%',0,
339 '\\',0,'s',0,'y',0,'s',0,'t',0,'e',0,'m',0,'3',0,'2',0,'\\',0,
340 'S',0,'h',0,'e',0,'l',0,'l',0,'3',0,'2',0,'.',0,'d',0,'l',0,'l',0,',',0,
341 '-',0,'1',0,'3',0,0,0
346 static const char StrLanguageCodes
[] = {
348 0x03, // Type is string
349 0x09, 0x04 // supported language Code 0 = 0x0409 (English)
352 // Note: ModemManager (Linux) ignores Proxmark3 devices by matching the
353 // manufacturer string "proxmark.org". Don't change this.
354 // or use the blacklisting file.
355 static const char StrManufacturer
[] = {
357 0x03, // Type is string
358 'p', 0, 'r', 0, 'o', 0, 'x', 0, 'm', 0, 'a', 0, 'r', 0, 'k', 0, '.', 0, 'o', 0, 'r', 0, 'g', 0,
361 static const char StrProduct
[] = {
363 0x03, // Type is string
364 'p', 0, 'r', 0, 'o', 0, 'x', 0, 'm', 0, 'a', 0, 'r', 0, 'k', 0, '3', 0
368 static const char StrSerialNumber
[] = {
370 0x03, // Type is string
371 'i', 0, 'c', 0, 'e', 0, 'm', 0, 'a', 0, 'n', 0
373 #else // WITH_FLASH is defined
375 // Manually calculated size of descriptor with unique ID:
376 // offset 0, lengt h 1: total length field
377 // offset 1, length 1: descriptor type field
378 // offset 2, length 12: 6x unicode chars (original string)
379 // offset 14, length 4: 2x unicode chars (underscores) [[ to avoid descriptor being (size % 8) == 0, OS bug workaround ]]
380 // offset 18, length 32: 16x unicode chars (8-byte serial as hex characters)
381 // ============================
383 #define USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH 50
384 char StrSerialNumber
[] = {
385 14, // Length is initially identical to non-unique version ... The length updated at boot, if unique serial is available
386 0x03, // Type is string
387 'i', 0, 'c', 0, 'e', 0, 'm', 0, 'a', 0, 'n', 0,
389 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0,
390 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0, 'x', 0,
392 void usb_update_serial(uint64_t newSerialNumber
) {
393 static bool configured
= false; // TODO: enable by setting to false here...
397 // run this only once per boot... even if it fails to find serial number
399 // reject serial number if all-zero or all-ones
400 if ((newSerialNumber
== 0x0000000000000000) || (newSerialNumber
== 0xFFFFFFFFFFFFFFFF)) {
403 // Descriptor is, effectively, initially identical to non-unique serial
404 // number because it reports the shorter length in the first byte.
405 // Convert uniqueID's eight bytes to 16 unicode characters in the
406 // descriptor and, finally, update the descriptor's length, which
407 // causes the serial number to become visible.
408 for (uint8_t i
= 0; i
< 8; i
++) {
409 // order of nibbles chosen to match display order from `hw status`
410 uint8_t nibble1
= (newSerialNumber
>> ((8 * i
) + 4)) & 0xFu
; // bitmasks [0xF0, 0xF000, 0xF00000, ... 0xF000000000000000]
411 uint8_t nibble2
= (newSerialNumber
>> ((8 * i
) + 0)) & 0xFu
; // bitmasks [0x0F, 0x0F00, 0x0F0000, ... 0x0F00000000000000]
412 char c1
= nibble1
< 10 ? '0' + nibble1
: 'A' + (nibble1
- 10);
413 char c2
= nibble2
< 10 ? '0' + nibble2
: 'A' + (nibble2
- 10);
414 StrSerialNumber
[18 + (4 * i
) + 0] = c1
; // [ 18, 22, .., 42, 46 ]
415 StrSerialNumber
[18 + (4 * i
) + 2] = c2
; // [ 20, 24, .., 44, 48 ]
417 StrSerialNumber
[0] = USB_STRING_DESCRIPTOR_SERIAL_NUMBER_LENGTH
;
422 // size includes their own field.
423 static const char StrMS_OSDescriptor
[] = {
425 0x03, // Type is string
426 'M', 0, 'S', 0, 'F', 0, 'T', 0, '1', 0, '0', 0, '0', 0, MS_VENDOR_CODE
, 0
429 static const char *getStringDescriptor(uint8_t idx
) {
432 return StrLanguageCodes
;
434 return StrManufacturer
;
438 return StrSerialNumber
;
439 case MS_OS_DESCRIPTOR_INDEX
:
440 return StrMS_OSDescriptor
;
446 // Bitmap for all status bits in CSR which must be written as 1 to cause no effect
447 #define REG_NO_EFFECT_1_ALL AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \
448 |AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP \
451 // Clear flags in the UDP_CSR register and waits for synchronization
452 #define UDP_CLEAR_EP_FLAGS(endpoint, flags) { \
453 volatile unsigned int reg; \
454 reg = pUdp->UDP_CSR[(endpoint)]; \
455 reg |= REG_NO_EFFECT_1_ALL; \
457 pUdp->UDP_CSR[(endpoint)] = reg; \
460 // reset flags in the UDP_CSR register and waits for synchronization
461 #define UDP_SET_EP_FLAGS(endpoint, flags) { \
462 volatile unsigned int reg; \
463 reg = pUdp->UDP_CSR[(endpoint)]; \
464 reg |= REG_NO_EFFECT_1_ALL; \
466 pUdp->UDP_CSR[(endpoint)] = reg; \
475 } AT91S_CDC_LINE_CODING
, *AT91PS_CDC_LINE_CODING
;
477 static AT91S_CDC_LINE_CODING line
= { // purely informative, actual values don't matter
478 USART_BAUD_RATE
, // baudrate
484 // timer counts in 21.3us increments (1024/48MHz), rounding applies
485 // WARNING: timer can't measure more than 1.39s (21.3us * 0xffff)
486 static void SpinDelayUs(int us
) {
487 int ticks
= ((MCK
/ 1000000) * us
+ 512) >> 10;
489 // Borrow a PWM unit for my real-time clock
490 AT91C_BASE_PWMC
->PWMC_ENA
= PWM_CHANNEL(0);
492 // 48 MHz / 1024 gives 46.875 kHz
493 AT91C_BASE_PWMC_CH0
->PWMC_CMR
= PWM_CH_MODE_PRESCALER(10); // Channel Mode Register
494 AT91C_BASE_PWMC_CH0
->PWMC_CDTYR
= 0; // Channel Duty Cycle Register
495 AT91C_BASE_PWMC_CH0
->PWMC_CPRDR
= 0xffff; // Channel Period Register
497 uint16_t start
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
500 uint16_t now
= AT91C_BASE_PWMC_CH0
->PWMC_CCNTR
;
501 if (now
== (uint16_t)(start
+ ticks
))
509 *----------------------------------------------------------------------------
511 * \brief This function deactivates the USB device
512 *----------------------------------------------------------------------------
514 void usb_disable(void) {
515 // Disconnect the USB device
516 AT91C_BASE_PIOA
->PIO_ODR
= GPIO_USB_PU
;
518 // Clear all lingering interrupts
519 if (pUdp
->UDP_ISR
& AT91C_UDP_ENDBUSRES
) {
520 pUdp
->UDP_ICR
= AT91C_UDP_ENDBUSRES
;
525 *----------------------------------------------------------------------------
527 * \brief This function Activates the USB device
528 *----------------------------------------------------------------------------
530 void usb_enable(void) {
531 // Set the PLL USB Divider
532 AT91C_BASE_CKGR
->CKGR_PLLR
|= AT91C_CKGR_USBDIV_1
;
534 // Specific Chip USB Initialisation
535 // Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock
536 AT91C_BASE_PMC
->PMC_SCER
|= AT91C_PMC_UDP
;
537 AT91C_BASE_PMC
->PMC_PCER
= (1 << AT91C_ID_UDP
);
539 AT91C_BASE_UDP
->UDP_FADDR
= 0;
540 AT91C_BASE_UDP
->UDP_GLBSTATE
= 0;
542 // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
543 // Set in PIO mode and Configure in Output
544 AT91C_BASE_PIOA
->PIO_PER
= GPIO_USB_PU
; // Set in PIO mode
545 AT91C_BASE_PIOA
->PIO_OER
= GPIO_USB_PU
; // Configure as Output
547 // Clear for set the Pullup resistor
548 AT91C_BASE_PIOA
->PIO_CODR
= GPIO_USB_PU
;
550 // Disconnect and reconnect USB controller for 100ms
553 SpinDelayUs(100 * 1000);
554 // Wait for a short while
555 //for (volatile size_t i=0; i<0x100000; i++) {};
557 // Reconnect USB reconnect
558 AT91C_BASE_PIOA
->PIO_SODR
= GPIO_USB_PU
;
559 AT91C_BASE_PIOA
->PIO_OER
= GPIO_USB_PU
;
563 *----------------------------------------------------------------------------
565 * \brief Test if the device is configured and handle enumeration
566 *----------------------------------------------------------------------------
568 static int usb_reconnect
= 0;
569 static int usb_configured
= 0;
570 void SetUSBreconnect(int value
) {
571 usb_reconnect
= value
;
573 int GetUSBreconnect(void) {
574 return usb_reconnect
;
576 void SetUSBconfigured(int value
) {
577 usb_configured
= value
;
579 int GetUSBconfigured(void) {
580 return usb_configured
;
583 bool usb_check(void) {
586 // reconnected ONCE and
587 if ( !USB_ATTACHED() ){
592 // only one time after USB been disengaged and re-engaged
593 if ( USB_ATTACHED() && usb_reconnect == 1 ) {
595 if ( usb_configured == 0) {
599 AT91F_CDC_Enumerate();
607 // interrupt status register
608 AT91_REG isr
= pUdp
->UDP_ISR
;
611 if (isr
& AT91C_UDP_ENDBUSRES
) {
612 pUdp
->UDP_ICR
= AT91C_UDP_ENDBUSRES
;
613 // reset all endpoints
614 pUdp
->UDP_RSTEP
= (unsigned int) - 1;
616 // Enable the function
617 pUdp
->UDP_FADDR
= AT91C_UDP_FEN
;
618 // Configure endpoint 0 (enable control endpoint)
619 pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] = (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_CTRL
);
620 } else if (isr
& AT91C_UDP_EPINT0
) {
621 pUdp
->UDP_ICR
= AT91C_UDP_EPINT0
;
622 AT91F_CDC_Enumerate();
625 else if (isr & AT91C_UDP_EPINT3 ) {
626 pUdp->UDP_ICR = AT91C_UDP_EPINT3;
627 AT91F_CDC_Enumerate();
628 //pUdp->UDP_ICR |= AT91C_UDP_EPINT3;
631 return (btConfiguration
) ? true : false;
634 bool usb_poll(void) {
635 if (usb_check() == false) {
639 return (pUdp
->UDP_CSR
[AT91C_EP_OUT
] & btReceiveBank
);
642 inline uint16_t usb_available_length(void) {
643 return (((pUdp
->UDP_CSR
[AT91C_EP_OUT
] & AT91C_UDP_RXBYTECNT
) >> 16) & 0x7FF);
647 In github PR #129, some users appears to get a false positive from
648 usb_poll, which returns true, but the usb_read operation
650 This check is basically the same as above, but also checks
651 that the length available to read is non-zero, thus hopefully fixes the
654 bool usb_poll_validate_length(void) {
656 if (usb_check() == false) {
660 if (!(pUdp
->UDP_CSR
[AT91C_EP_OUT
] & btReceiveBank
)) {
664 return (((pUdp
->UDP_CSR
[AT91C_EP_OUT
] & AT91C_UDP_RXBYTECNT
) >> 16) > 0);
668 *----------------------------------------------------------------------------
670 * \brief Read available data from Endpoint 1 OUT (host to device)
671 *----------------------------------------------------------------------------
673 uint32_t usb_read(uint8_t *data
, size_t len
) {
679 uint8_t bank
= btReceiveBank
;
680 uint16_t packetSize
, nbBytesRcv
= 0;
681 uint16_t time_out
= 0;
684 if (usb_check() == false) {
688 if (pUdp
->UDP_CSR
[AT91C_EP_OUT
] & bank
) {
690 packetSize
= (((pUdp
->UDP_CSR
[AT91C_EP_OUT
] & AT91C_UDP_RXBYTECNT
) >> 16) & 0x7FF);
691 packetSize
= MIN(packetSize
, len
);
694 while (packetSize
--) {
695 data
[nbBytesRcv
++] = pUdp
->UDP_FDR
[AT91C_EP_OUT
];
699 UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT
, bank
)
701 if (bank
== AT91C_UDP_RX_DATA_BK0
) {
702 bank
= AT91C_UDP_RX_DATA_BK1
;
704 bank
= AT91C_UDP_RX_DATA_BK0
;
708 if (time_out
++ == 0x1FFF) {
713 btReceiveBank
= bank
;
717 static uint8_t usb_read_ng_buffer
[64] = {0};
718 static uint8_t usb_read_ng_bufoffset
= 0;
719 static size_t usb_read_ng_buflen
= 0;
721 bool usb_read_ng_has_buffered_data(void) {
722 return usb_read_ng_buflen
> 0;
725 uint32_t usb_read_ng(uint8_t *data
, size_t len
) {
731 uint8_t bank
= btReceiveBank
;
732 uint16_t packetSize
, nbBytesRcv
= 0;
733 uint16_t time_out
= 0;
735 // take first from local buffer
736 if (len
<= usb_read_ng_buflen
) {
738 // if local buffer has all data
740 for (size_t i
= 0; i
< len
; i
++) {
741 data
[nbBytesRcv
++] = usb_read_ng_buffer
[usb_read_ng_bufoffset
+ i
];
744 usb_read_ng_buflen
-= len
;
746 if (usb_read_ng_buflen
== 0) {
747 usb_read_ng_bufoffset
= 0;
749 usb_read_ng_bufoffset
+= len
;
756 // take all data from local buffer, then read from usb
758 for (size_t i
= 0; i
< usb_read_ng_buflen
; i
++) {
759 data
[nbBytesRcv
++] = usb_read_ng_buffer
[usb_read_ng_bufoffset
+ i
];
762 len
-= usb_read_ng_buflen
;
763 usb_read_ng_buflen
= 0;
764 usb_read_ng_bufoffset
= 0;
770 if (usb_check() == false) {
774 if ((pUdp
->UDP_CSR
[AT91C_EP_OUT
] & bank
)) {
776 uint16_t available
= (((pUdp
->UDP_CSR
[AT91C_EP_OUT
] & AT91C_UDP_RXBYTECNT
) >> 16) & 0x7FF);
778 packetSize
= MIN(available
, len
);
779 available
-= packetSize
;
782 while (packetSize
--) {
783 data
[nbBytesRcv
++] = pUdp
->UDP_FDR
[AT91C_EP_OUT
];
786 // fill the local buffer with the remaining bytes
787 for (uint16_t i
= 0; i
< available
; i
++) {
788 usb_read_ng_buffer
[i
] = pUdp
->UDP_FDR
[AT91C_EP_OUT
];
791 // update number of available bytes in local bytes
792 usb_read_ng_buflen
= available
;
795 UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT
, bank
)
797 if (bank
== AT91C_UDP_RX_DATA_BK0
) {
798 bank
= AT91C_UDP_RX_DATA_BK1
;
800 bank
= AT91C_UDP_RX_DATA_BK0
;
804 if (time_out
++ == 0x1FFF) {
809 btReceiveBank
= bank
;
814 *----------------------------------------------------------------------------
816 * \brief Send through endpoint 2 (device to host)
817 *----------------------------------------------------------------------------
819 int usb_write(const uint8_t *data
, const size_t len
) {
825 if (usb_check() == false) {
830 if ((pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXPKTRDY
) != 0) {
838 cpt
= MIN(length
, AT91C_USB_EP_IN_SIZE
);
841 pUdp
->UDP_FDR
[AT91C_EP_IN
] = *data
++;
844 UDP_SET_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXPKTRDY
);
845 while (!(pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXPKTRDY
)) {};
849 cpt
= MIN(length
, AT91C_USB_EP_IN_SIZE
);
852 pUdp
->UDP_FDR
[AT91C_EP_IN
] = *data
++;
855 // Wait for previous chunk to be sent
856 // (iceman) when is the bankswapping done?
857 while (!(pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
)) {
858 if (usb_check() == false) {
863 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXCOMP
);
864 while (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
) {};
866 UDP_SET_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXPKTRDY
);
867 while (!(pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXPKTRDY
)) {};
870 // Wait for the end of transfer
871 while (!(pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
)) {
872 if (usb_check() == false) {
877 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXCOMP
);
878 while (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
) {};
881 if (len
% AT91C_USB_EP_IN_SIZE
== 0) {
882 // like AT91F_USB_SendZlp(), in non ping-pong mode
883 UDP_SET_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXPKTRDY
);
884 while (!(pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
)) {};
886 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXCOMP
);
887 while (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
) {};
894 *----------------------------------------------------------------------------
895 * \fn async_usb_write_start
896 * \brief Start async write process
897 * \return PM3_EIO if USB is invalid, PM3_SUCCESS if it is ready for write
899 * This function checks if the USB is connected, and wait until the FIFO
900 * is ready to be filled.
902 * Warning: usb_write() should not be called between
903 * async_usb_write_start() and async_usb_write_stop().
904 *----------------------------------------------------------------------------
906 int async_usb_write_start(void) {
908 if (usb_check() == false) {
912 while (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXPKTRDY
) {
913 if (usb_check() == false) {
918 isAsyncRequestFinished
= false;
923 *----------------------------------------------------------------------------
924 * \fn async_usb_write_pushByte
925 * \brief Push one byte to the FIFO of IN endpoint (time-critical)
927 * This function simply push a byte to the FIFO of IN endpoint.
928 * The FIFO size is AT91C_USB_EP_IN_SIZE. Make sure this function is not called
929 * over AT91C_USB_EP_IN_SIZE times between each async_usb_write_requestWrite().
930 *----------------------------------------------------------------------------
932 inline void async_usb_write_pushByte(uint8_t data
) {
933 pUdp
->UDP_FDR
[AT91C_EP_IN
] = data
;
934 isAsyncRequestFinished
= false;
938 *----------------------------------------------------------------------------
939 * \fn async_usb_write_requestWrite
940 * \brief Request a write operation (time-critical)
941 * \return false if the last write request is not finished, true if success
943 * This function requests a write operation from FIFO to the USB bus,
944 * and switch the internal banks of FIFO. It doesn't wait for the end of
945 * transmission from FIFO to the USB bus.
947 * Note: This function doesn't check if the usb is valid, as it is
949 *----------------------------------------------------------------------------
951 inline bool async_usb_write_requestWrite(void) {
953 // check if last request is finished
954 if (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXPKTRDY
) {
958 // clear transmission completed flag
959 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXCOMP
);
960 while (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
) {};
962 // start of transmission
963 UDP_SET_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXPKTRDY
);
965 // hack: no need to wait if UDP_CSR and UDP_FDR are not used immediately.
966 // while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY)) {};
967 isAsyncRequestFinished
= true;
972 *----------------------------------------------------------------------------
973 * \fn async_usb_write_stop
974 * \brief Stop async write process
975 * \return PM3_EIO if USB is invalid, PM3_SUCCESS if data is written
977 * This function makes sure the data left in the FIFO is written to the
980 * Warning: usb_write() should not be called between
981 * async_usb_write_start() and async_usb_write_stop().
982 *----------------------------------------------------------------------------
984 int async_usb_write_stop(void) {
985 // Wait for the end of transfer
986 while (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXPKTRDY
) {
987 if (usb_check() == false) {
992 // clear transmission completed flag
993 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXCOMP
);
994 while (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
) {};
996 // FIFO is not empty, request a write in non-ping-pong mode
997 if (isAsyncRequestFinished
== false) {
998 UDP_SET_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXPKTRDY
);
1000 while (!(pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
)) {
1001 if (usb_check() == false) {
1006 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN
, AT91C_UDP_TXCOMP
);
1007 while (pUdp
->UDP_CSR
[AT91C_EP_IN
] & AT91C_UDP_TXCOMP
) {};
1013 *----------------------------------------------------------------------------
1014 * \fn AT91F_USB_SendData
1015 * \brief Send Data through the control endpoint
1016 *----------------------------------------------------------------------------
1018 void AT91F_USB_SendData(AT91PS_UDP pudp
, const char *pData
, uint32_t length
) {
1022 uint32_t cpt
= MIN(length
, AT91C_USB_EP_CONTROL_SIZE
);
1026 pudp
->UDP_FDR
[AT91C_EP_CONTROL
] = *pData
++;
1029 if (pudp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
) {
1030 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_TXCOMP
);
1031 while (pudp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
) {};
1034 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_TXPKTRDY
);
1037 csr
= pudp
->UDP_CSR
[AT91C_EP_CONTROL
];
1038 // Data IN stage has been stopped by a status OUT
1039 if (csr
& AT91C_UDP_RX_DATA_BK0
) {
1041 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_RX_DATA_BK0
)
1044 } while (!(csr
& AT91C_UDP_TXCOMP
));
1048 if (pudp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
) {
1049 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_TXCOMP
);
1050 while (pudp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
) {};
1055 //*----------------------------------------------------------------------------
1056 //* \fn AT91F_USB_SendZlp
1057 //* \brief Send zero length packet through the control endpoint
1058 //*----------------------------------------------------------------------------
1059 void AT91F_USB_SendZlp(AT91PS_UDP pudp
) {
1060 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_TXPKTRDY
);
1061 // for non ping-pong operation, wait until the FIFO is released
1062 // the flag for FIFO released is AT91C_UDP_TXCOMP rather than AT91C_UDP_TXPKTRDY
1063 while (!(pudp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
)) {};
1064 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_TXCOMP
);
1065 while (pudp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_TXCOMP
) {};
1068 //*----------------------------------------------------------------------------
1069 //* \fn AT91F_USB_SendStall
1070 //* \brief Stall the control endpoint
1071 //*----------------------------------------------------------------------------
1072 void AT91F_USB_SendStall(AT91PS_UDP pudp
) {
1073 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_FORCESTALL
);
1074 while (!(pudp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_ISOERROR
)) {};
1075 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, (AT91C_UDP_FORCESTALL
| AT91C_UDP_ISOERROR
));
1076 while (pudp
->UDP_CSR
[AT91C_EP_CONTROL
] & (AT91C_UDP_FORCESTALL
| AT91C_UDP_ISOERROR
)) {};
1079 //*----------------------------------------------------------------------------
1080 //* \fn AT91F_CDC_Enumerate
1081 //* \brief This function is a callback invoked when a SETUP packet is received
1083 //* 1. this is for USB endpoint0. the control endpoint.
1084 //* 2. mixed with CDC ACM endpoint3 , interrupt, control endpoint
1085 //*----------------------------------------------------------------------------
1086 void AT91F_CDC_Enumerate(void) {
1087 uint8_t bmRequestType
, bRequest
;
1088 uint16_t wValue
, wIndex
, wLength
, wStatus
;
1090 if (!(pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_RXSETUP
)) {
1094 bmRequestType
= pUdp
->UDP_FDR
[AT91C_EP_CONTROL
];
1095 bRequest
= pUdp
->UDP_FDR
[AT91C_EP_CONTROL
];
1096 wValue
= (pUdp
->UDP_FDR
[AT91C_EP_CONTROL
] & 0xFF);
1097 wValue
|= (pUdp
->UDP_FDR
[AT91C_EP_CONTROL
] << 8);
1098 wIndex
= (pUdp
->UDP_FDR
[AT91C_EP_CONTROL
] & 0xFF);
1099 wIndex
|= (pUdp
->UDP_FDR
[AT91C_EP_CONTROL
] << 8);
1100 wLength
= (pUdp
->UDP_FDR
[AT91C_EP_CONTROL
] & 0xFF);
1101 wLength
|= (pUdp
->UDP_FDR
[AT91C_EP_CONTROL
] << 8);
1103 if (bmRequestType
& 0x80) { // Data Phase Transfer Direction Device to Host
1104 UDP_SET_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_DIR
);
1105 while (!(pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_DIR
)) {};
1107 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_RXSETUP
);
1108 while ((pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_RXSETUP
)) {};
1111 if ( bRequest == MS_VENDOR_CODE) {
1112 if ( bmRequestType == MS_WCID_GET_DESCRIPTOR ) { // C0
1113 if ( wIndex == MS_EXTENDED_COMPAT_ID ) { // 4
1114 //AT91F_USB_SendData(pUdp, CompatIDFeatureDescriptor, MIN(sizeof(CompatIDFeatureDescriptor), wLength));
1119 if ( bmRequestType == MS_WCID_GET_FEATURE_DESCRIPTOR ) { //C1
1120 // if ( wIndex == MS_EXTENDED_PROPERTIES ) { // 5 - winusb bug with wIndex == interface index, so I just send it always)
1121 //AT91F_USB_SendData(pUdp, OSprop, MIN(sizeof(OSprop), wLength));
1128 // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1
1129 switch ((bRequest
<< 8) | bmRequestType
) {
1130 case STD_GET_DESCRIPTOR
: {
1132 if (wValue
== 0x100) { // Return Device Descriptor
1133 AT91F_USB_SendData(pUdp
, devDescriptor
, MIN(sizeof(devDescriptor
), wLength
));
1134 } else if (wValue
== 0x200) { // Return Configuration Descriptor
1135 AT91F_USB_SendData(pUdp
, cfgDescriptor
, MIN(sizeof(cfgDescriptor
), wLength
));
1136 } else if ((wValue
& 0xF00) == 0xF00) { // Return BOS Descriptor
1137 AT91F_USB_SendData(pUdp
, bosDescriptor
, MIN(sizeof(bosDescriptor
), wLength
));
1138 } else if ((wValue
& 0x300) == 0x300) { // Return String Descriptor
1140 const char *strDescriptor
= getStringDescriptor(wValue
& 0xff);
1141 if (strDescriptor
!= NULL
) {
1142 AT91F_USB_SendData(pUdp
, strDescriptor
, MIN(strDescriptor
[0], wLength
));
1144 AT91F_USB_SendStall(pUdp
);
1147 AT91F_USB_SendStall(pUdp
);
1151 case STD_SET_ADDRESS
:
1152 AT91F_USB_SendZlp(pUdp
);
1153 pUdp
->UDP_FADDR
= (AT91C_UDP_FEN
| (wValue
& 0x7F));
1154 pUdp
->UDP_GLBSTATE
= (wValue
) ? AT91C_UDP_FADDEN
: 0;
1156 case STD_SET_CONFIGURATION
:
1159 * Set or clear the device "configured" state.
1160 * The LSB of wValue is the "Configuration Number". If this value is non-zero,
1161 * it should be the same number as defined in the Configuration Descriptor;
1162 * otherwise an error must have occurred.
1163 * This device has only one configuration and its Config Number is CONF_NB (= 1).
1165 AT91F_USB_SendZlp(pUdp
);
1166 btConfiguration
= wValue
;
1167 pUdp
->UDP_GLBSTATE
= (wValue
) ? AT91C_UDP_CONFG
: AT91C_UDP_FADDEN
;
1169 // make sure we are not stalled
1171 UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT , AT91C_UDP_FORCESTALL);
1172 UDP_CLEAR_EP_FLAGS(AT91C_EP_IN , AT91C_UDP_FORCESTALL);
1173 UDP_CLEAR_EP_FLAGS(AT91C_EP_NOTIFY, AT91C_UDP_FORCESTALL);
1177 pUdp
->UDP_CSR
[AT91C_EP_OUT
] = (wValue
) ? (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_BULK_OUT
) : 0;
1178 pUdp
->UDP_CSR
[AT91C_EP_IN
] = (wValue
) ? (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_BULK_IN
) : 0;
1179 pUdp
->UDP_CSR
[AT91C_EP_NOTIFY
] = (wValue
) ? (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_INT_IN
) : 0;
1181 case STD_GET_CONFIGURATION
:
1182 AT91F_USB_SendData(pUdp
, (char *) & (btConfiguration
), sizeof(btConfiguration
));
1184 case STD_GET_STATUS_ZERO
:
1185 wStatus
= 0; // Device is Bus powered, remote wakeup disabled
1186 AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
));
1188 case STD_GET_STATUS_INTERFACE
:
1189 wStatus
= 0; // reserved for future use
1190 AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
));
1192 case STD_GET_STATUS_ENDPOINT
:
1195 if ((pUdp
->UDP_GLBSTATE
& AT91C_UDP_CONFG
) && (wIndex
<= AT91C_EP_NOTIFY
)) {
1196 wStatus
= (pUdp
->UDP_CSR
[wIndex
] & AT91C_UDP_EPEDS
) ? 0 : 1;
1197 AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
));
1198 } else if ((pUdp
->UDP_GLBSTATE
& AT91C_UDP_FADDEN
) && (wIndex
== AT91C_EP_CONTROL
)) {
1199 wStatus
= (pUdp
->UDP_CSR
[wIndex
] & AT91C_UDP_EPEDS
) ? 0 : 1;
1200 AT91F_USB_SendData(pUdp
, (char *) &wStatus
, sizeof(wStatus
));
1202 AT91F_USB_SendStall(pUdp
);
1205 case STD_SET_FEATURE_ZERO
:
1206 AT91F_USB_SendStall(pUdp
);
1208 case STD_SET_FEATURE_INTERFACE
:
1209 AT91F_USB_SendZlp(pUdp
);
1211 case STD_SET_FEATURE_ENDPOINT
:
1213 if ((wValue
== 0) && (wIndex
>= AT91C_EP_OUT
) && (wIndex
<= AT91C_EP_NOTIFY
)) {
1214 pUdp
->UDP_CSR
[wIndex
] = 0;
1215 AT91F_USB_SendZlp(pUdp
);
1217 AT91F_USB_SendStall(pUdp
);
1220 case STD_CLEAR_FEATURE_ZERO
:
1221 AT91F_USB_SendStall(pUdp
);
1223 case STD_CLEAR_FEATURE_INTERFACE
:
1224 AT91F_USB_SendZlp(pUdp
);
1226 case STD_CLEAR_FEATURE_ENDPOINT
:
1228 if ((wValue
== 0) && (wIndex
>= AT91C_EP_OUT
) && (wIndex
<= AT91C_EP_NOTIFY
)) {
1230 if (wIndex
== AT91C_EP_OUT
) {
1231 pUdp
->UDP_CSR
[AT91C_EP_OUT
] = (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_BULK_OUT
);
1232 } else if (wIndex
== AT91C_EP_IN
) {
1233 pUdp
->UDP_CSR
[AT91C_EP_IN
] = (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_BULK_IN
);
1234 } else if (wIndex
== AT91C_EP_NOTIFY
) {
1235 pUdp
->UDP_CSR
[AT91C_EP_NOTIFY
] = (AT91C_UDP_EPEDS
| AT91C_UDP_EPTYPE_INT_IN
);
1238 AT91F_USB_SendZlp(pUdp
);
1240 AT91F_USB_SendStall(pUdp
);
1244 // handle CDC class requests
1245 case SET_LINE_CODING
: {
1248 for ( i = 0 ; i < 7 ; i++ ) {
1249 ((uint8_t*)&line)[i] = pUdp->UDP_FDR[AT91C_EP_CONTROL];
1251 // ignore SET_LINE_CODING...
1252 while (!(pUdp
->UDP_CSR
[AT91C_EP_CONTROL
] & AT91C_UDP_RX_DATA_BK0
)) {};
1253 UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL
, AT91C_UDP_RX_DATA_BK0
);
1254 AT91F_USB_SendZlp(pUdp
);
1257 case GET_LINE_CODING
:
1258 AT91F_USB_SendData(pUdp
, (char *) &line
, MIN(sizeof(line
), wLength
));
1260 case SET_CONTROL_LINE_STATE
:
1261 btConnection
= wValue
;
1262 AT91F_USB_SendZlp(pUdp
);
1265 AT91F_USB_SendStall(pUdp
);