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