openocd: src/jtag: replace the GPL-2.0-or-later license tag
[openocd.git] / src / jtag / drivers / OpenULINK / src / usb.c
blobfa0ff6c6d29d884f3ae0f6c476deb0486ed1e091
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Copyright (C) 2011-2013 by Martin Schmoelzer *
5 * <martin.schmoelzer@student.tuwien.ac.at> *
6 ***************************************************************************/
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
15 * Therefore, we do not have to support the Set Configuration USB request.
18 #include "usb.h"
19 #include "delay.h"
20 #include "io.h"
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;
27 volatile __xdata __at 0x7FE8 struct setup_data setup_data;
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
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
50 /* WARNING: ALL config, interface and endpoint descriptors MUST be adjacent! */
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 */
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
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
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
95 __code struct usb_language_descriptor language_descriptor = {
96 .bLength = 4,
97 .bDescriptorType = DESCRIPTOR_TYPE_STRING,
98 .wLANGID = {0x0409 /* US English */}
101 __code struct usb_string_descriptor strManufacturer =
102 STR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K');
104 __code struct usb_string_descriptor strProduct =
105 STR_DESCR(9, 'O', 'p', 'e', 'n', 'U', 'L', 'I', 'N', 'K');
107 __code struct usb_string_descriptor strSerialNumber =
108 STR_DESCR(6, '0', '0', '0', '0', '0', '1');
110 __code struct usb_string_descriptor strConfigDescr =
111 STR_DESCR(12, 'J', 'T', 'A', 'G', ' ', 'A', 'd', 'a', 'p', 't', 'e', 'r');
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
121 void sudav_isr(void) __interrupt SUDAV_ISR
123 CLEAR_IRQ();
125 usb_handle_setup_data();
127 USBIRQ = SUDAVIR;
128 EP0CS |= HSNAK;
131 void sof_isr(void) __interrupt SOF_ISR
134 void sutok_isr(void) __interrupt SUTOK_ISR
137 void suspend_isr(void) __interrupt SUSPEND_ISR
140 void usbreset_isr(void) __interrupt USBRESET_ISR
143 void ibn_isr(void) __interrupt IBN_ISR
147 void ep0in_isr(void) __interrupt EP0IN_ISR
150 void ep0out_isr(void) __interrupt EP0OUT_ISR
153 void ep1in_isr(void) __interrupt EP1IN_ISR
156 void ep1out_isr(void) __interrupt EP1OUT_ISR
161 * EP2 IN: called after the transfer from uC->Host has finished: we sent data
163 void ep2in_isr(void) __interrupt EP2IN_ISR
165 EP2_in = 1;
167 CLEAR_IRQ();
168 IN07IRQ = IN2IR;/* Clear OUT2 IRQ */
172 * EP2 OUT: called after the transfer from Host->uC has finished: we got data
174 void ep2out_isr(void) __interrupt EP2OUT_ISR
176 EP2_out = 1;
178 CLEAR_IRQ();
179 OUT07IRQ = OUT2IR; /* Clear OUT2 IRQ */
182 void ep3in_isr(void) __interrupt EP3IN_ISR
185 void ep3out_isr(void) __interrupt EP3OUT_ISR
188 void ep4in_isr(void) __interrupt EP4IN_ISR
191 void ep4out_isr(void) __interrupt EP4OUT_ISR
194 void ep5in_isr(void) __interrupt EP5IN_ISR
197 void ep5out_isr(void) __interrupt EP5OUT_ISR
200 void ep6in_isr(void) __interrupt EP6IN_ISR
203 void ep6out_isr(void) __interrupt EP6OUT_ISR
206 void ep7in_isr(void) __interrupt EP7IN_ISR
209 void ep7out_isr(void) __interrupt EP7OUT_ISR
214 * Return the control/status register for an endpoint
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
221 __xdata uint8_t *usb_get_endpoint_cs_reg(uint8_t ep)
223 /* Mask direction bit */
224 uint8_t ep_num = ep & 0x7F;
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;
253 return NULL;
256 void usb_reset_data_toggle(uint8_t ep)
258 /* TOGCTL register:
259 +----+-----+-----+------+-----+-------+-------+-------+
260 | Q | S | R | IO | 0 | EP2 | EP1 | EP0 |
261 +----+-----+-----+------+-----+-------+-------+-------+
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.
267 uint8_t togctl_value = (ep & 0x80 >> 3) | (ep & 0x7);
269 /* First step: Write EP number and direction bit */
270 TOGCTL = togctl_value;
272 /* Second step: Set R bit */
273 togctl_value |= TOG_R;
274 TOGCTL = togctl_value;
278 * Handle GET_STATUS request.
280 * @return on success: true
281 * @return on failure: false
283 bool usb_handle_get_status(void)
285 uint8_t *ep_cs;
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;
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;
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);
309 if (*ep_cs & EPSTALL)
310 IN0BUF[0] = 0x01;
311 else
312 IN0BUF[0] = 0x00;
314 /* Second byte sent has to be always zero */
315 IN0BUF[1] = 0;
317 /* Send response */
318 IN0BC = 2;
319 break;
320 default:
321 return false;
322 break;
325 return true;
329 * Handle CLEAR_FEATURE request.
331 * @return on success: true
332 * @return on failure: false
334 bool usb_handle_clear_feature(void)
336 __xdata uint8_t *ep_cs;
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();
354 break;
355 default:
356 /* Vendor commands... */
359 return true;
363 * Handle SET_FEATURE request.
365 * @return on success: true
366 * @return on failure: false
368 bool usb_handle_set_feature(void)
370 __xdata uint8_t *ep_cs;
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;
388 break;
389 default:
390 /* Vendor commands... */
391 break;
394 return true;
398 * Handle GET_DESCRIPTOR request.
400 * @return on success: true
401 * @return on failure: false
403 bool usb_handle_get_descriptor(void)
405 __xdata uint8_t descriptor_type;
406 __xdata uint8_t descriptor_index;
408 descriptor_type = (setup_data.wValue & 0xff00) >> 8;
409 descriptor_index = setup_data.wValue & 0x00ff;
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;
438 return true;
442 * Handle SET_INTERFACE request.
444 void usb_handle_set_interface(void)
446 /* Reset Data Toggle */
447 usb_reset_data_toggle(USB_DIR_IN | 2);
448 usb_reset_data_toggle(USB_DIR_OUT | 2);
450 /* Unstall & clear busy flag of all valid IN endpoints */
451 IN2CS = 0 | EPBSY;
453 /* Unstall all valid OUT endpoints, reset bytecounts */
454 OUT2CS = 0;
455 OUT2BC = 0;
459 * Handle the arrival of a USB Control Setup Packet.
461 void usb_handle_setup_data(void)
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;
517 * USB initialization. Configures USB interrupts, endpoints and performs
518 * ReNumeration.
520 void usb_init(void)
522 /* Mark endpoint 2 IN & OUT as valid */
523 IN07VAL = IN2VAL;
524 OUT07VAL = OUT2VAL;
526 /* Make sure no isochronous endpoints are marked valid */
527 INISOVAL = 0;
528 OUTISOVAL = 0;
530 /* Disable isochronous endpoints. This makes the isochronous data buffers
531 * available as 8051 XDATA memory at address 0x2000 - 0x27FF */
532 ISOCTL = ISODISAB;
534 /* Enable USB Autovectoring */
535 USBBAV |= AVEN;
537 /* Enable SUDAV interrupt */
538 USBIEN |= SUDAVIE;
540 /* Enable EP2 OUT & IN interrupts */
541 OUT07IEN = OUT2IEN;
542 IN07IEN = IN2IEN;
544 /* Enable USB interrupt (EIE register) */
545 EUSB = 1;
547 /* Perform ReNumeration */
548 USBCS = DISCON | RENUM;
549 delay_ms(200);
550 USBCS = DISCOE | RENUM;