update files to correct FSF address
[fw/openocd] / src / jtag / drivers / OpenULINK / src / usb.c
1 /***************************************************************************
2  *   Copyright (C) 2011 by Martin Schmoelzer                               *
3  *   <martin.schmoelzer@student.tuwien.ac.at>                              *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.           *
19  ***************************************************************************/
20
21 /**
22  * @file
23  * Defines USB descriptors, interrupt routines and helper functions.
24  * To minimize code size, we make the following assumptions:
25  *  - The OpenULINK has exactly one configuration
26  *  - and exactly one alternate setting
27  *
28  * Therefore, we do not have to support the Set Configuration USB request.
29  */
30
31 #include "usb.h"
32 #include "delay.h"
33 #include "io.h"
34
35 /* Also update external declarations in "include/usb.h" if making changes to
36  * these variables! */
37 volatile bool EP2_out;
38 volatile bool EP2_in;
39
40 volatile __xdata __at 0x7FE8 struct setup_data setup_data;
41
42 /* Define number of endpoints (except Control Endpoint 0) in a central place.
43  * Be sure to include the neccessary endpoint descriptors! */
44 #define NUM_ENDPOINTS 2
45
46 /*
47  * Normally, we would initialize the descriptor structures in C99 style:
48  *
49  * __code usb_device_descriptor_t device_descriptor = {
50  *   .bLength = foo,
51  *   .bDescriptorType = bar,
52  *   .bcdUSB = 0xABCD,
53  *   ...
54  * };
55  *
56  * But SDCC currently does not support this, so we have to do it the
57  * old-fashioned way...
58  */
59
60 __code struct usb_device_descriptor device_descriptor = {
61         /* .bLength = */ sizeof(struct usb_device_descriptor),
62         /* .bDescriptorType = */ DESCRIPTOR_TYPE_DEVICE,
63         /* .bcdUSB = */ 0x0110,         /* BCD: 01.00 (Version 1.0 USB spec) */
64         /* .bDeviceClass = */ 0xFF,     /* 0xFF = vendor-specific */
65         /* .bDeviceSubClass = */ 0xFF,
66         /* .bDeviceProtocol = */ 0xFF,
67         /* .bMaxPacketSize0 = */ 64,
68         /* .idVendor = */ 0xC251,
69         /* .idProduct = */ 0x2710,
70         /* .bcdDevice = */ 0x0100,
71         /* .iManufacturer = */ 1,
72         /* .iProduct = */ 2,
73         /* .iSerialNumber = */ 3,
74         /* .bNumConfigurations = */ 1
75 };
76
77 /* WARNING: ALL config, interface and endpoint descriptors MUST be adjacent! */
78
79 __code struct usb_config_descriptor config_descriptor = {
80         /* .bLength = */ sizeof(struct usb_config_descriptor),
81         /* .bDescriptorType = */ DESCRIPTOR_TYPE_CONFIGURATION,
82         /* .wTotalLength = */ sizeof(struct usb_config_descriptor) +
83         sizeof(struct usb_interface_descriptor) +
84         (NUM_ENDPOINTS *
85          sizeof(struct usb_endpoint_descriptor)),
86         /* .bNumInterfaces = */ 1,
87         /* .bConfigurationValue = */ 1,
88         /* .iConfiguration = */ 4,      /* String describing this configuration */
89         /* .bmAttributes = */ 0x80,     /* Only MSB set according to USB spec */
90         /* .MaxPower = */ 50            /* 100 mA */
91 };
92
93 __code struct usb_interface_descriptor interface_descriptor00 = {
94         /* .bLength = */ sizeof(struct usb_interface_descriptor),
95         /* .bDescriptorType = */ DESCRIPTOR_TYPE_INTERFACE,
96         /* .bInterfaceNumber = */ 0,
97         /* .bAlternateSetting = */ 0,
98         /* .bNumEndpoints = */ NUM_ENDPOINTS,
99         /* .bInterfaceClass = */ 0xFF,
100         /* .bInterfaceSubclass = */ 0xFF,
101         /* .bInterfaceProtocol = */ 0xFF,
102         /* .iInterface = */ 0
103 };
104
105 __code struct usb_endpoint_descriptor Bulk_EP2_IN_Endpoint_Descriptor = {
106         /* .bLength = */ sizeof(struct usb_endpoint_descriptor),
107         /* .bDescriptorType = */ 0x05,
108         /* .bEndpointAddress = */ 2 | USB_DIR_IN,
109         /* .bmAttributes = */ 0x02,
110         /* .wMaxPacketSize = */ 64,
111         /* .bInterval = */ 0
112 };
113
114 __code struct usb_endpoint_descriptor Bulk_EP2_OUT_Endpoint_Descriptor = {
115         /* .bLength = */ sizeof(struct usb_endpoint_descriptor),
116         /* .bDescriptorType = */ 0x05,
117         /* .bEndpointAddress = */ 2 | USB_DIR_OUT,
118         /* .bmAttributes = */ 0x02,
119         /* .wMaxPacketSize = */ 64,
120         /* .bInterval = */ 0
121 };
122
123 __code struct usb_language_descriptor language_descriptor = {
124         /* .bLength =  */ 4,
125         /* .bDescriptorType = */ DESCRIPTOR_TYPE_STRING,
126         /* .wLANGID = */ {0x0409 /* US English */}
127 };
128
129 __code struct usb_string_descriptor strManufacturer =
130         STR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K');
131
132 __code struct usb_string_descriptor strProduct =
133         STR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K');
134
135 __code struct usb_string_descriptor strSerialNumber =
136         STR_DESCR(6, '0', '0', '0', '0', '0', '1');
137
138 __code struct usb_string_descriptor strConfigDescr  =
139         STR_DESCR(12, 'J', 'T', 'A', 'G', ' ', 'A', 'd', 'a', 'p', 't', 'e', 'r');
140
141 /* Table containing pointers to string descriptors */
142 __code struct usb_string_descriptor *__code en_string_descriptors[4] = {
143         &strManufacturer,
144         &strProduct,
145         &strSerialNumber,
146         &strConfigDescr
147 };
148
149 void sudav_isr(void) __interrupt SUDAV_ISR
150 {
151         CLEAR_IRQ();
152
153         usb_handle_setup_data();
154
155         USBIRQ = SUDAVIR;
156         EP0CS |= HSNAK;
157 }
158
159 void sof_isr(void)      __interrupt SOF_ISR
160 {
161 }
162 void sutok_isr(void)    __interrupt SUTOK_ISR
163 {
164 }
165 void suspend_isr(void)  __interrupt SUSPEND_ISR
166 {
167 }
168 void usbreset_isr(void) __interrupt USBRESET_ISR
169 {
170 }
171 void ibn_isr(void)      __interrupt IBN_ISR
172 {
173 }
174
175 void ep0in_isr(void)    __interrupt EP0IN_ISR
176 {
177 }
178 void ep0out_isr(void)   __interrupt EP0OUT_ISR
179 {
180 }
181 void ep1in_isr(void)    __interrupt EP1IN_ISR
182 {
183 }
184 void ep1out_isr(void)   __interrupt EP1OUT_ISR
185 {
186 }
187
188 /**
189  * EP2 IN: called after the transfer from uC->Host has finished: we sent data
190  */
191 void ep2in_isr(void)    __interrupt EP2IN_ISR
192 {
193         EP2_in = 1;
194
195         CLEAR_IRQ();
196         IN07IRQ = IN2IR;/* Clear OUT2 IRQ */
197 }
198
199 /**
200  * EP2 OUT: called after the transfer from Host->uC has finished: we got data
201  */
202 void ep2out_isr(void)   __interrupt EP2OUT_ISR
203 {
204         EP2_out = 1;
205
206         CLEAR_IRQ();
207         OUT07IRQ = OUT2IR;      /* Clear OUT2 IRQ */
208 }
209
210 void ep3in_isr(void)    __interrupt EP3IN_ISR
211 {
212 }
213 void ep3out_isr(void)   __interrupt EP3OUT_ISR
214 {
215 }
216 void ep4in_isr(void)    __interrupt EP4IN_ISR
217 {
218 }
219 void ep4out_isr(void)   __interrupt EP4OUT_ISR
220 {
221 }
222 void ep5in_isr(void)    __interrupt EP5IN_ISR
223 {
224 }
225 void ep5out_isr(void)   __interrupt EP5OUT_ISR
226 {
227 }
228 void ep6in_isr(void)    __interrupt EP6IN_ISR
229 {
230 }
231 void ep6out_isr(void)   __interrupt EP6OUT_ISR
232 {
233 }
234 void ep7in_isr(void)    __interrupt EP7IN_ISR
235 {
236 }
237 void ep7out_isr(void)   __interrupt EP7OUT_ISR
238 {
239 }
240
241 /**
242  * Return the control/status register for an endpoint
243  *
244  * @param ep endpoint address
245  * @return on success: pointer to Control & Status register for endpoint
246  *  specified in \a ep
247  * @return on failure: NULL
248  */
249 __xdata uint8_t *usb_get_endpoint_cs_reg(uint8_t ep)
250 {
251         /* Mask direction bit */
252         uint8_t ep_num = ep & 0x7F;
253
254         switch (ep_num) {
255             case 0:
256                     return &EP0CS;
257                     break;
258             case 1:
259                     return ep & 0x80 ? &IN1CS : &OUT1CS;
260                     break;
261             case 2:
262                     return ep & 0x80 ? &IN2CS : &OUT2CS;
263                     break;
264             case 3:
265                     return ep & 0x80 ? &IN3CS : &OUT3CS;
266                     break;
267             case 4:
268                     return ep & 0x80 ? &IN4CS : &OUT4CS;
269                     break;
270             case 5:
271                     return ep & 0x80 ? &IN5CS : &OUT5CS;
272                     break;
273             case 6:
274                     return ep & 0x80 ? &IN6CS : &OUT6CS;
275                     break;
276             case 7:
277                     return ep & 0x80 ? &IN7CS : &OUT7CS;
278                     break;
279         }
280
281         return NULL;
282 }
283
284 void usb_reset_data_toggle(uint8_t ep)
285 {
286         /* TOGCTL register:
287            +----+-----+-----+------+-----+-------+-------+-------+
288            | Q  |  S  |  R  |  IO  |  0  |  EP2  |  EP1  |  EP0  |
289            +----+-----+-----+------+-----+-------+-------+-------+
290
291            To reset data toggle bits, we have to write the endpoint direction (IN/OUT)
292            to the IO bit and the endpoint number to the EP2..EP0 bits. Then, in a
293            separate write cycle, the R bit needs to be set.
294         */
295         uint8_t togctl_value = (ep & 0x80 >> 3) | (ep & 0x7);
296
297         /* First step: Write EP number and direction bit */
298         TOGCTL = togctl_value;
299
300         /* Second step: Set R bit */
301         togctl_value |= TOG_R;
302         TOGCTL = togctl_value;
303 }
304
305 /**
306  * Handle GET_STATUS request.
307  *
308  * @return on success: true
309  * @return on failure: false
310  */
311 bool usb_handle_get_status(void)
312 {
313         uint8_t *ep_cs;
314
315         switch (setup_data.bmRequestType) {
316             case GS_DEVICE:
317                         /* Two byte response: Byte 0, Bit 0 = self-powered, Bit 1 = remote wakeup.
318                          *                    Byte 1: reserved, reset to zero */
319                     IN0BUF[0] = 0;
320                     IN0BUF[1] = 0;
321
322                         /* Send response */
323                     IN0BC = 2;
324                     break;
325             case GS_INTERFACE:
326                         /* Always return two zero bytes according to USB 1.1 spec, p. 191 */
327                     IN0BUF[0] = 0;
328                     IN0BUF[1] = 0;
329
330                         /* Send response */
331                     IN0BC = 2;
332                     break;
333             case GS_ENDPOINT:
334                         /* Get stall bit for endpoint specified in low byte of wIndex */
335                     ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex & 0xff);
336
337                     if (*ep_cs & EPSTALL)
338                             IN0BUF[0] = 0x01;
339                     else
340                             IN0BUF[0] = 0x00;
341
342                         /* Second byte sent has to be always zero */
343                     IN0BUF[1] = 0;
344
345                         /* Send response */
346                     IN0BC = 2;
347                     break;
348             default:
349                     return false;
350                     break;
351         }
352
353         return true;
354 }
355
356 /**
357  * Handle CLEAR_FEATURE request.
358  *
359  * @return on success: true
360  * @return on failure: false
361  */
362 bool usb_handle_clear_feature(void)
363 {
364         __xdata uint8_t *ep_cs;
365
366         switch (setup_data.bmRequestType) {
367             case CF_DEVICE:
368                         /* Clear remote wakeup not supported: stall EP0 */
369                     STALL_EP0();
370                     break;
371             case CF_ENDPOINT:
372                     if (setup_data.wValue == 0) {
373                                 /* Unstall the endpoint specified in wIndex */
374                             ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);
375                             if (!ep_cs)
376                                     return false;
377                             *ep_cs &= ~EPSTALL;
378                     } else {
379                                 /* Unsupported feature, stall EP0 */
380                             STALL_EP0();
381                     }
382                     break;
383             default:
384                         /* Vendor commands... */
385         }
386
387         return true;
388 }
389
390 /**
391  * Handle SET_FEATURE request.
392  *
393  * @return on success: true
394  * @return on failure: false
395  */
396 bool usb_handle_set_feature(void)
397 {
398         __xdata uint8_t *ep_cs;
399
400         switch (setup_data.bmRequestType) {
401             case SF_DEVICE:
402                     if (setup_data.wValue == 2)
403                             return true;
404                     break;
405             case SF_ENDPOINT:
406                     if (setup_data.wValue == 0) {
407                                 /* Stall the endpoint specified in wIndex */
408                             ep_cs = usb_get_endpoint_cs_reg(setup_data.wIndex);
409                             if (!ep_cs)
410                                     return false;
411                             *ep_cs |= EPSTALL;
412                     } else {
413                                 /* Unsupported endpoint feature */
414                             return false;
415                     }
416                     break;
417             default:
418                         /* Vendor commands... */
419                     break;
420         }
421
422         return true;
423 }
424
425 /**
426  * Handle GET_DESCRIPTOR request.
427  *
428  * @return on success: true
429  * @return on failure: false
430  */
431 bool usb_handle_get_descriptor(void)
432 {
433         __xdata uint8_t descriptor_type;
434         __xdata uint8_t descriptor_index;
435
436         descriptor_type = (setup_data.wValue & 0xff00) >> 8;
437         descriptor_index = setup_data.wValue & 0x00ff;
438
439         switch (descriptor_type) {
440             case DESCRIPTOR_TYPE_DEVICE:
441                     SUDPTRH = HI8(&device_descriptor);
442                     SUDPTRL = LO8(&device_descriptor);
443                     break;
444             case DESCRIPTOR_TYPE_CONFIGURATION:
445                     SUDPTRH = HI8(&config_descriptor);
446                     SUDPTRL = LO8(&config_descriptor);
447                     break;
448             case DESCRIPTOR_TYPE_STRING:
449                     if (setup_data.wIndex == 0) {
450                                 /* Supply language descriptor */
451                             SUDPTRH = HI8(&language_descriptor);
452                             SUDPTRL = LO8(&language_descriptor);
453                     } else if (setup_data.wIndex == 0x0409 /* US English */)   {
454                                 /* Supply string descriptor */
455                             SUDPTRH = HI8(en_string_descriptors[descriptor_index - 1]);
456                             SUDPTRL = LO8(en_string_descriptors[descriptor_index - 1]);
457                     } else
458                             return false;
459                     break;
460             default:
461                         /* Unsupported descriptor type */
462                     return false;
463                     break;
464         }
465
466         return true;
467 }
468
469 /**
470  * Handle SET_INTERFACE request.
471  */
472 void usb_handle_set_interface(void)
473 {
474         /* Reset Data Toggle */
475         usb_reset_data_toggle(USB_DIR_IN  | 2);
476         usb_reset_data_toggle(USB_DIR_OUT | 2);
477
478         /* Unstall & clear busy flag of all valid IN endpoints */
479         IN2CS = 0 | EPBSY;
480
481         /* Unstall all valid OUT endpoints, reset bytecounts */
482         OUT2CS = 0;
483         OUT2BC = 0;
484 }
485
486 /**
487  * Handle the arrival of a USB Control Setup Packet.
488  */
489 void usb_handle_setup_data(void)
490 {
491         switch (setup_data.bRequest) {
492             case GET_STATUS:
493                     if (!usb_handle_get_status())
494                             STALL_EP0();
495                     break;
496             case CLEAR_FEATURE:
497                     if (!usb_handle_clear_feature())
498                             STALL_EP0();
499                     break;
500             case 2: case 4:
501                         /* Reserved values */
502                     STALL_EP0();
503                     break;
504             case SET_FEATURE:
505                     if (!usb_handle_set_feature())
506                             STALL_EP0();
507                     break;
508             case SET_ADDRESS:
509                         /* Handled by USB core */
510                     break;
511             case SET_DESCRIPTOR:
512                         /* Set Descriptor not supported. */
513                     STALL_EP0();
514                     break;
515             case GET_DESCRIPTOR:
516                     if (!usb_handle_get_descriptor())
517                             STALL_EP0();
518                     break;
519             case GET_CONFIGURATION:
520                         /* OpenULINK has only one configuration, return its index */
521                     IN0BUF[0] = config_descriptor.bConfigurationValue;
522                     IN0BC = 1;
523                     break;
524             case SET_CONFIGURATION:
525                         /* OpenULINK has only one configuration -> nothing to do */
526                     break;
527             case GET_INTERFACE:
528                         /* OpenULINK only has one interface, return its number */
529                     IN0BUF[0] = interface_descriptor00.bInterfaceNumber;
530                     IN0BC = 1;
531                     break;
532             case SET_INTERFACE:
533                     usb_handle_set_interface();
534                     break;
535             case SYNCH_FRAME:
536                         /* Isochronous endpoints not used -> nothing to do */
537                     break;
538             default:
539                         /* Any other requests: do nothing */
540                     break;
541         }
542 }
543
544 /**
545  * USB initialization. Configures USB interrupts, endpoints and performs
546  * ReNumeration.
547  */
548 void usb_init(void)
549 {
550         /* Mark endpoint 2 IN & OUT as valid */
551         IN07VAL  = IN2VAL;
552         OUT07VAL = OUT2VAL;
553
554         /* Make sure no isochronous endpoints are marked valid */
555         INISOVAL  = 0;
556         OUTISOVAL = 0;
557
558         /* Disable isochronous endpoints. This makes the isochronous data buffers
559          * available as 8051 XDATA memory at address 0x2000 - 0x27FF */
560         ISOCTL = ISODISAB;
561
562         /* Enable USB Autovectoring */
563         USBBAV |= AVEN;
564
565         /* Enable SUDAV interrupt */
566         USBIEN |= SUDAVIE;
567
568         /* Enable EP2 OUT & IN interrupts */
569         OUT07IEN = OUT2IEN;
570         IN07IEN  = IN2IEN;
571
572         /* Enable USB interrupt (EIE register) */
573         EUSB = 1;
574
575         /* Perform ReNumeration */
576         USBCS = DISCON | RENUM;
577         delay_ms(200);
578         USBCS = DISCOE | RENUM;
579 }