1 //-----------------------------------------------------------------------------
2 // My USB driver. This has to be common, because it exists in both the
3 // bootrom and the application.
4 // Jonathan Westhues, split Aug 14 2005
5 //-----------------------------------------------------------------------------
8 #define min(a, b) (((a) > (b)) ? (b) : (a))
10 #define USB_REPORT_PACKET_SIZE 64
12 typedef struct PACKED
{
20 #define USB_REQUEST_GET_STATUS 0
21 #define USB_REQUEST_CLEAR_FEATURE 1
22 #define USB_REQUEST_SET_FEATURE 3
23 #define USB_REQUEST_SET_ADDRESS 5
24 #define USB_REQUEST_GET_DESCRIPTOR 6
25 #define USB_REQUEST_SET_DESCRIPTOR 7
26 #define USB_REQUEST_GET_CONFIGURATION 8
27 #define USB_REQUEST_SET_CONFIGURATION 9
28 #define USB_REQUEST_GET_INTERFACE 10
29 #define USB_REQUEST_SET_INTERFACE 11
30 #define USB_REQUEST_SYNC_FRAME 12
32 #define USB_DESCRIPTOR_TYPE_DEVICE 1
33 #define USB_DESCRIPTOR_TYPE_CONFIGURATION 2
34 #define USB_DESCRIPTOR_TYPE_STRING 3
35 #define USB_DESCRIPTOR_TYPE_INTERFACE 4
36 #define USB_DESCRIPTOR_TYPE_ENDPOINT 5
37 #define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER 6
38 #define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONF 7
39 #define USB_DESCRIPTOR_TYPE_INTERFACE_POWER 8
40 #define USB_DESCRIPTOR_TYPE_HID 0x21
41 #define USB_DESCRIPTOR_TYPE_HID_REPORT 0x22
43 #define USB_DEVICE_CLASS_HID 0x03
45 static const BYTE HidReportDescriptor
[] = {
46 0x06,0xA0,0xFF, // Usage Page (vendor defined) FFA0
47 0x09,0x01, // Usage (vendor defined)
48 0xA1,0x01, // Collection (Application)
49 0x09,0x02, // Usage (vendor defined)
50 0xA1,0x00, // Collection (Physical)
51 0x06,0xA1,0xFF, // Usage Page (vendor defined)
54 0x09,0x03, // usage - vendor defined
55 0x09,0x04, // usage - vendor defined
56 0x15,0x80, // Logical Minimum (-128)
57 0x25,0x7F, // Logical Maximum (127)
58 0x35,0x00, // Physical Minimum (0)
59 0x45,0xFF, // Physical Maximum (255)
60 0x75,0x08, // Report Size (8) (bits)
61 0x95,0x40, // Report Count (64) (fields)
62 0x81,0x02, // Input (Data,Variable,Absolute)
65 0x09,0x05, // usage - vendor defined
66 0x09,0x06, // usage - vendor defined
67 0x15,0x80, // Logical Minimum (-128)
68 0x25,0x7F, // Logical Maximum (127)
69 0x35,0x00, // Physical Minimum (0)
70 0x45,0xFF, // Physical Maximum (255)
71 0x75,0x08, // Report Size (8) (bits)
72 0x95,0x40, // Report Count (64) (fields)
73 0x91,0x02, // Output (Data,Variable,Absolute)
75 0xC0, // End Collection
77 0xC0, // End Collection
80 static const BYTE DeviceDescriptor
[] = {
81 0x12, // Descriptor length (18 bytes)
82 0x01, // Descriptor type (Device)
83 0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10)
84 0x00, // Class code (0)
85 0x00, // Subclass code (0)
86 0x00, // Protocol (No specific protocol)
87 0x08, // Maximum packet size for Endpoint 0 (8 bytes)
88 0xc4,0x9a, // Vendor ID (random numbers)
89 0x8f,0x4b, // Product ID (random numbers)
90 0x01,0x00, // Device release number (0001)
91 0x01, // Manufacturer string descriptor index
92 0x02, // Product string descriptor index
93 0x00, // Serial Number string descriptor index (None)
94 0x01, // Number of possible configurations (1)
97 static const BYTE ConfigurationDescriptor
[] = {
98 0x09, // Descriptor length (9 bytes)
99 0x02, // Descriptor type (Configuration)
100 0x29,0x00, // Total data length (41 bytes)
101 0x01, // Interface supported (1)
102 0x01, // Configuration value (1)
103 0x00, // Index of string descriptor (None)
104 0x80, // Configuration (Bus powered)
105 250, // Maximum power consumption (500mA)
108 0x09, // Descriptor length (9 bytes)
109 0x04, // Descriptor type (Interface)
110 0x00, // Number of interface (0)
111 0x00, // Alternate setting (0)
112 0x02, // Number of interface endpoint (2)
113 0x03, // Class code (HID)
114 0x00, // Subclass code ()
115 0x00, // Protocol code ()
116 0x00, // Index of string()
119 0x09, // Descriptor length (9 bytes)
120 0x21, // Descriptor type (HID)
121 0x00,0x01, // HID class release number (1.00)
122 0x00, // Localized country code (None)
123 0x01, // # of HID class dscrptr to follow (1)
124 0x22, // Report descriptor type (HID)
125 // Total length of report descriptor
126 sizeof(HidReportDescriptor
),0x00,
129 0x07, // Descriptor length (7 bytes)
130 0x05, // Descriptor type (Endpoint)
131 0x01, // Encoded address (Respond to OUT)
132 0x03, // Endpoint attribute (Interrupt transfer)
133 0x08,0x00, // Maximum packet size (8 bytes)
134 0x01, // Polling interval (1 ms)
137 0x07, // Descriptor length (7 bytes)
138 0x05, // Descriptor type (Endpoint)
139 0x82, // Encoded address (Respond to IN)
140 0x03, // Endpoint attribute (Interrupt transfer)
141 0x08,0x00, // Maximum packet size (8 bytes)
142 0x01, // Polling interval (1 ms)
145 static const BYTE StringDescriptor0
[] = {
147 0x03, // Type is string
152 static const BYTE StringDescriptor1
[] = {
154 0x03, // Type is string
168 static const BYTE StringDescriptor2
[] = {
170 0x03, // Type is string
199 static const BYTE
* const StringDescriptors
[] = {
206 static BYTE UsbBuffer
[64];
207 static int UsbSoFarCount
;
209 static BYTE CurrentConfiguration
;
211 static void UsbSendEp0(const BYTE
*data
, int len
)
216 thisTime
= min(len
, 8);
219 for(i
= 0; i
< thisTime
; i
++) {
220 AT91C_BASE_UDP
->UDP_FDR
[0] = *data
;
224 if(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_TXCOMP
) {
225 AT91C_BASE_UDP
->UDP_CSR
[0] &= ~AT91C_UDP_TXCOMP
;
226 while(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_TXCOMP
)
230 AT91C_BASE_UDP
->UDP_CSR
[0] |= AT91C_UDP_TXPKTRDY
;
233 if(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_RX_DATA_BK0
) {
234 // This means that the host is trying to write to us, so
235 // abandon our write to them.
236 AT91C_BASE_UDP
->UDP_CSR
[0] &= ~AT91C_UDP_RX_DATA_BK0
;
239 } while(!(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_TXCOMP
));
242 if(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_TXCOMP
) {
243 AT91C_BASE_UDP
->UDP_CSR
[0] &= ~AT91C_UDP_TXCOMP
;
244 while(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_TXCOMP
)
249 static void UsbSendZeroLength(void)
251 AT91C_BASE_UDP
->UDP_CSR
[0] |= AT91C_UDP_TXPKTRDY
;
253 while(!(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_TXCOMP
))
256 AT91C_BASE_UDP
->UDP_CSR
[0] &= ~AT91C_UDP_TXCOMP
;
258 while(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_TXCOMP
)
262 static void UsbSendStall(void)
264 AT91C_BASE_UDP
->UDP_CSR
[0] |= AT91C_UDP_FORCESTALL
;
266 while(!(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_STALLSENT
))
269 AT91C_BASE_UDP
->UDP_CSR
[0] &= ~AT91C_UDP_STALLSENT
;
271 while(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_STALLSENT
)
275 static void HandleRxdSetupData(void)
280 for(i
= 0; i
< sizeof(usd
); i
++) {
281 ((BYTE
*)&usd
)[i
] = AT91C_BASE_UDP
->UDP_FDR
[0];
284 if(usd
.bmRequestType
& 0x80) {
285 AT91C_BASE_UDP
->UDP_CSR
[0] |= AT91C_UDP_DIR
;
286 while(!(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_DIR
))
290 AT91C_BASE_UDP
->UDP_CSR
[0] &= ~AT91C_UDP_RXSETUP
;
291 while(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_RXSETUP
)
294 switch(usd
.bRequest
) {
295 case USB_REQUEST_GET_DESCRIPTOR
:
296 if((usd
.wValue
>> 8) == USB_DESCRIPTOR_TYPE_DEVICE
) {
297 UsbSendEp0((BYTE
*)&DeviceDescriptor
,
298 min(sizeof(DeviceDescriptor
), usd
.wLength
));
299 } else if((usd
.wValue
>> 8) == USB_DESCRIPTOR_TYPE_CONFIGURATION
) {
300 UsbSendEp0((BYTE
*)&ConfigurationDescriptor
,
301 min(sizeof(ConfigurationDescriptor
), usd
.wLength
));
302 } else if((usd
.wValue
>> 8) == USB_DESCRIPTOR_TYPE_STRING
) {
303 const BYTE
*s
= StringDescriptors
[usd
.wValue
& 0xff];
304 UsbSendEp0(s
, min(s
[0], usd
.wLength
));
305 } else if((usd
.wValue
>> 8) == USB_DESCRIPTOR_TYPE_HID_REPORT
) {
306 UsbSendEp0((BYTE
*)&HidReportDescriptor
,
307 min(sizeof(HidReportDescriptor
), usd
.wLength
));
309 *((DWORD
*)0x00200000) = usd
.wValue
;
313 case USB_REQUEST_SET_ADDRESS
:
315 AT91C_BASE_UDP
->UDP_FADDR
= AT91C_UDP_FEN
| usd
.wValue
;
316 if(usd
.wValue
!= 0) {
317 AT91C_BASE_UDP
->UDP_GLBSTATE
= AT91C_UDP_FADDEN
;
319 AT91C_BASE_UDP
->UDP_GLBSTATE
= 0;
323 case USB_REQUEST_GET_CONFIGURATION
:
324 UsbSendEp0(&CurrentConfiguration
, sizeof(CurrentConfiguration
));
327 case USB_REQUEST_GET_STATUS
: {
328 if(usd
.bmRequestType
& 0x80) {
330 UsbSendEp0((BYTE
*)&w
, sizeof(w
));
334 case USB_REQUEST_SET_CONFIGURATION
:
335 CurrentConfiguration
= usd
.wValue
;
336 if(CurrentConfiguration
) {
337 AT91C_BASE_UDP
->UDP_GLBSTATE
= AT91C_UDP_CONFG
;
338 AT91C_BASE_UDP
->UDP_CSR
[1] = AT91C_UDP_EPEDS
|
339 AT91C_UDP_EPTYPE_INT_OUT
;
340 AT91C_BASE_UDP
->UDP_CSR
[2] = AT91C_UDP_EPEDS
|
341 AT91C_UDP_EPTYPE_INT_IN
;
343 AT91C_BASE_UDP
->UDP_GLBSTATE
= AT91C_UDP_FADDEN
;
344 AT91C_BASE_UDP
->UDP_CSR
[1] = 0;
345 AT91C_BASE_UDP
->UDP_CSR
[2] = 0;
350 case USB_REQUEST_GET_INTERFACE
: {
352 UsbSendEp0(&b
, sizeof(b
));
356 case USB_REQUEST_SET_INTERFACE
:
360 case USB_REQUEST_CLEAR_FEATURE
:
361 case USB_REQUEST_SET_FEATURE
:
364 case USB_REQUEST_SET_DESCRIPTOR
:
365 case USB_REQUEST_SYNC_FRAME
:
371 void UsbSendPacket(BYTE
*packet
, int len
)
376 thisTime
= min(len
, 8);
378 for(i
= 0; i
< thisTime
; i
++) {
379 AT91C_BASE_UDP
->UDP_FDR
[2] = packet
[i
];
381 AT91C_BASE_UDP
->UDP_CSR
[2] |= AT91C_UDP_TXPKTRDY
;
383 while(!(AT91C_BASE_UDP
->UDP_CSR
[2] & AT91C_UDP_TXCOMP
))
385 AT91C_BASE_UDP
->UDP_CSR
[2] &= ~AT91C_UDP_TXCOMP
;
387 while(AT91C_BASE_UDP
->UDP_CSR
[2] & AT91C_UDP_TXCOMP
)
395 static void HandleRxdData(void)
399 if(AT91C_BASE_UDP
->UDP_CSR
[1] & AT91C_UDP_RX_DATA_BK0
) {
400 len
= UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP
->UDP_CSR
[1]);
402 for(i
= 0; i
< len
; i
++) {
403 UsbBuffer
[UsbSoFarCount
] = AT91C_BASE_UDP
->UDP_FDR
[1];
407 AT91C_BASE_UDP
->UDP_CSR
[1] &= ~AT91C_UDP_RX_DATA_BK0
;
408 while(AT91C_BASE_UDP
->UDP_CSR
[1] & AT91C_UDP_RX_DATA_BK0
)
411 if(UsbSoFarCount
>= 64) {
412 UsbPacketReceived(UsbBuffer
, UsbSoFarCount
);
417 if(AT91C_BASE_UDP
->UDP_CSR
[1] & AT91C_UDP_RX_DATA_BK1
) {
418 len
= UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP
->UDP_CSR
[1]);
420 for(i
= 0; i
< len
; i
++) {
421 UsbBuffer
[UsbSoFarCount
] = AT91C_BASE_UDP
->UDP_FDR
[1];
425 AT91C_BASE_UDP
->UDP_CSR
[1] &= ~AT91C_UDP_RX_DATA_BK1
;
426 while(AT91C_BASE_UDP
->UDP_CSR
[1] & AT91C_UDP_RX_DATA_BK1
)
429 if(UsbSoFarCount
>= 64) {
430 UsbPacketReceived(UsbBuffer
, UsbSoFarCount
);
442 USB_D_PLUS_PULLUP_OFF();
444 for(i
= 0; i
< 1000000; i
++)
447 USB_D_PLUS_PULLUP_ON();
449 if(AT91C_BASE_UDP
->UDP_ISR
& AT91C_UDP_ENDBUSRES
) {
450 AT91C_BASE_UDP
->UDP_ICR
= AT91C_UDP_ENDBUSRES
;
456 if (AT91C_BASE_UDP
->UDP_GLBSTATE
& AT91C_UDP_CONFG
)
462 BOOL
UsbPoll(BOOL blinkLeds
)
466 if(AT91C_BASE_UDP
->UDP_ISR
& AT91C_UDP_ENDBUSRES
) {
467 AT91C_BASE_UDP
->UDP_ICR
= AT91C_UDP_ENDBUSRES
;
469 // following a reset we should be ready to receive a setup packet
470 AT91C_BASE_UDP
->UDP_RSTEP
= 0xf;
471 AT91C_BASE_UDP
->UDP_RSTEP
= 0;
473 AT91C_BASE_UDP
->UDP_FADDR
= AT91C_UDP_FEN
;
475 AT91C_BASE_UDP
->UDP_CSR
[0] = AT91C_UDP_EPTYPE_CTRL
| AT91C_UDP_EPEDS
;
477 CurrentConfiguration
= 0;
482 if(AT91C_BASE_UDP
->UDP_ISR
& UDP_INTERRUPT_ENDPOINT(0)) {
483 if(AT91C_BASE_UDP
->UDP_CSR
[0] & AT91C_UDP_RXSETUP
) {
484 HandleRxdSetupData();
489 if(AT91C_BASE_UDP
->UDP_ISR
& UDP_INTERRUPT_ENDPOINT(1)) {