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 UDP_ENDPOINT_FIFO(0) = *data
;
224 if(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED
) {
225 UDP_ENDPOINT_CSR(0) &= ~UDP_CSR_TX_PACKET_ACKED
;
226 while(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED
)
230 UDP_ENDPOINT_CSR(0) |= UDP_CSR_TX_PACKET
;
233 if(UDP_ENDPOINT_CSR(0) & UDP_CSR_RX_PACKET_RECEIVED_BANK_0
) {
234 // This means that the host is trying to write to us, so
235 // abandon our write to them.
236 UDP_ENDPOINT_CSR(0) &= ~UDP_CSR_RX_PACKET_RECEIVED_BANK_0
;
239 } while(!(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED
));
242 if(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED
) {
243 UDP_ENDPOINT_CSR(0) &= ~UDP_CSR_TX_PACKET_ACKED
;
244 while(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED
)
249 static void UsbSendZeroLength(void)
251 UDP_ENDPOINT_CSR(0) |= UDP_CSR_TX_PACKET
;
253 while(!(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED
))
256 UDP_ENDPOINT_CSR(0) &= ~UDP_CSR_TX_PACKET_ACKED
;
258 while(UDP_ENDPOINT_CSR(0) & UDP_CSR_TX_PACKET_ACKED
)
262 static void HandleRxdSetupData(void)
267 for(i
= 0; i
< sizeof(usd
); i
++) {
268 ((BYTE
*)&usd
)[i
] = UDP_ENDPOINT_FIFO(0);
271 if(usd
.bmRequestType
& 0x80) {
272 UDP_ENDPOINT_CSR(0) |= UDP_CSR_CONTROL_DATA_DIR
;
273 while(!(UDP_ENDPOINT_CSR(0) & UDP_CSR_CONTROL_DATA_DIR
))
277 UDP_ENDPOINT_CSR(0) &= ~UDP_CSR_RX_HAVE_READ_SETUP_DATA
;
278 while(UDP_ENDPOINT_CSR(0) & UDP_CSR_RX_HAVE_READ_SETUP_DATA
)
281 switch(usd
.bRequest
) {
282 case USB_REQUEST_GET_DESCRIPTOR
:
283 if((usd
.wValue
>> 8) == USB_DESCRIPTOR_TYPE_DEVICE
) {
284 UsbSendEp0((BYTE
*)&DeviceDescriptor
,
285 min(sizeof(DeviceDescriptor
), usd
.wLength
));
286 } else if((usd
.wValue
>> 8) == USB_DESCRIPTOR_TYPE_CONFIGURATION
) {
287 UsbSendEp0((BYTE
*)&ConfigurationDescriptor
,
288 min(sizeof(ConfigurationDescriptor
), usd
.wLength
));
289 } else if((usd
.wValue
>> 8) == USB_DESCRIPTOR_TYPE_STRING
) {
290 const BYTE
*s
= StringDescriptors
[usd
.wValue
& 0xff];
291 UsbSendEp0(s
, min(s
[0], usd
.wLength
));
292 } else if((usd
.wValue
>> 8) == USB_DESCRIPTOR_TYPE_HID_REPORT
) {
293 UsbSendEp0((BYTE
*)&HidReportDescriptor
,
294 min(sizeof(HidReportDescriptor
), usd
.wLength
));
296 *((DWORD
*)0x00200000) = usd
.wValue
;
300 case USB_REQUEST_SET_ADDRESS
:
302 UDP_FUNCTION_ADDR
= UDP_FUNCTION_ADDR_ENABLED
| usd
.wValue
;
303 if(usd
.wValue
!= 0) {
304 UDP_GLOBAL_STATE
= UDP_GLOBAL_STATE_ADDRESSED
;
306 UDP_GLOBAL_STATE
= 0;
310 case USB_REQUEST_GET_CONFIGURATION
:
311 UsbSendEp0(&CurrentConfiguration
, sizeof(CurrentConfiguration
));
314 case USB_REQUEST_GET_STATUS
: {
315 if(usd
.bmRequestType
& 0x80) {
317 UsbSendEp0((BYTE
*)&w
, sizeof(w
));
321 case USB_REQUEST_SET_CONFIGURATION
:
322 CurrentConfiguration
= usd
.wValue
;
323 if(CurrentConfiguration
) {
324 UDP_GLOBAL_STATE
= UDP_GLOBAL_STATE_CONFIGURED
;
325 UDP_ENDPOINT_CSR(1) = UDP_CSR_ENABLE_EP
|
326 UDP_CSR_EPTYPE_INTERRUPT_OUT
;
327 UDP_ENDPOINT_CSR(2) = UDP_CSR_ENABLE_EP
|
328 UDP_CSR_EPTYPE_INTERRUPT_IN
;
330 UDP_GLOBAL_STATE
= UDP_GLOBAL_STATE_ADDRESSED
;
331 UDP_ENDPOINT_CSR(1) = 0;
332 UDP_ENDPOINT_CSR(2) = 0;
337 case USB_REQUEST_GET_INTERFACE
: {
339 UsbSendEp0(&b
, sizeof(b
));
343 case USB_REQUEST_SET_INTERFACE
:
347 case USB_REQUEST_CLEAR_FEATURE
:
348 case USB_REQUEST_SET_FEATURE
:
349 case USB_REQUEST_SET_DESCRIPTOR
:
350 case USB_REQUEST_SYNC_FRAME
:
356 void UsbSendPacket(BYTE
*packet
, int len
)
361 thisTime
= min(len
, 8);
363 for(i
= 0; i
< thisTime
; i
++) {
364 UDP_ENDPOINT_FIFO(2) = packet
[i
];
366 UDP_ENDPOINT_CSR(2) |= UDP_CSR_TX_PACKET
;
368 while(!(UDP_ENDPOINT_CSR(2) & UDP_CSR_TX_PACKET_ACKED
))
370 UDP_ENDPOINT_CSR(2) &= ~UDP_CSR_TX_PACKET_ACKED
;
372 while(UDP_ENDPOINT_CSR(2) & UDP_CSR_TX_PACKET_ACKED
)
380 static void HandleRxdData(void)
384 if(UDP_ENDPOINT_CSR(1) & UDP_CSR_RX_PACKET_RECEIVED_BANK_0
) {
385 len
= UDP_CSR_BYTES_RECEIVED(UDP_ENDPOINT_CSR(1));
387 for(i
= 0; i
< len
; i
++) {
388 UsbBuffer
[UsbSoFarCount
] = UDP_ENDPOINT_FIFO(1);
392 UDP_ENDPOINT_CSR(1) &= ~UDP_CSR_RX_PACKET_RECEIVED_BANK_0
;
393 while(UDP_ENDPOINT_CSR(1) & UDP_CSR_RX_PACKET_RECEIVED_BANK_0
)
396 if(UsbSoFarCount
>= 64) {
397 UsbPacketReceived(UsbBuffer
, UsbSoFarCount
);
402 if(UDP_ENDPOINT_CSR(1) & UDP_CSR_RX_PACKET_RECEIVED_BANK_1
) {
403 len
= UDP_CSR_BYTES_RECEIVED(UDP_ENDPOINT_CSR(1));
405 for(i
= 0; i
< len
; i
++) {
406 UsbBuffer
[UsbSoFarCount
] = UDP_ENDPOINT_FIFO(1);
410 UDP_ENDPOINT_CSR(1) &= ~UDP_CSR_RX_PACKET_RECEIVED_BANK_1
;
411 while(UDP_ENDPOINT_CSR(1) & UDP_CSR_RX_PACKET_RECEIVED_BANK_1
)
414 if(UsbSoFarCount
>= 64) {
415 UsbPacketReceived(UsbBuffer
, UsbSoFarCount
);
427 USB_D_PLUS_PULLUP_OFF();
429 for(i
= 0; i
< 1000000; i
++)
432 USB_D_PLUS_PULLUP_ON();
434 if(UDP_INTERRUPT_STATUS
& UDP_INTERRUPT_END_OF_BUS_RESET
) {
435 UDP_INTERRUPT_CLEAR
= UDP_INTERRUPT_END_OF_BUS_RESET
;
439 BOOL
UsbPoll(BOOL blinkLeds
)
443 if(UDP_INTERRUPT_STATUS
& UDP_INTERRUPT_END_OF_BUS_RESET
) {
444 UDP_INTERRUPT_CLEAR
= UDP_INTERRUPT_END_OF_BUS_RESET
;
446 // following a reset we should be ready to receive a setup packet
447 UDP_RESET_ENDPOINT
= 0xf;
448 UDP_RESET_ENDPOINT
= 0;
450 UDP_FUNCTION_ADDR
= UDP_FUNCTION_ADDR_ENABLED
;
452 UDP_ENDPOINT_CSR(0) = UDP_CSR_EPTYPE_CONTROL
| UDP_CSR_ENABLE_EP
;
454 CurrentConfiguration
= 0;
459 if(UDP_INTERRUPT_STATUS
& UDP_INTERRUPT_ENDPOINT(0)) {
460 if(UDP_ENDPOINT_CSR(0) & UDP_CSR_RX_HAVE_READ_SETUP_DATA
) {
461 HandleRxdSetupData();
466 if(UDP_INTERRUPT_STATUS
& UDP_INTERRUPT_ENDPOINT(1)) {