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