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