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