contrib/firmware: add new adapter ANGIE's firmware/bitstream code
[openocd.git] / contrib / firmware / angie / c / src / usb.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /****************************************************************************
4 File : usb.c *
5 Contents : usb communication handling code for NanoXplore USB-JTAG *
6 ANGIE adapter hardware. *
7 Based on openULINK project code by: Martin Schmoelzer. *
8 Copyright 2023, Ahmed Errached BOUDJELIDA, NanoXplore SAS. *
9 <aboudjelida@nanoxplore.com> *
10 <ahmederrachedbjld@gmail.com> *
11 *****************************************************************************/
12
13 #include "usb.h"
14 #include "stdint.h"
15 #include "delay.h"
16 #include "io.h"
17 #include "reg_ezusb.h"
18 #include <fx2macros.h>
19 #include <serial.h>
20 #include <stdio.h>
21
22 /* Also update external declarations in "include/usb.h" if making changes to
23 * these variables!
24 */
25 volatile bool ep1_out;
26 volatile bool ep1_in;
27
28 volatile __xdata __at 0xE6B8 struct setup_data setup_data;
29
30 /* Define number of endpoints (except Control Endpoint 0) in a central place.
31 * Be sure to include the necessary endpoint descriptors!
32 */
33 #define NUM_ENDPOINTS 3
34
35 __code struct usb_device_descriptor device_descriptor = {
36 .blength = sizeof(struct usb_device_descriptor),
37 .bdescriptortype = DESCRIPTOR_TYPE_DEVICE,
38 .bcdusb = 0x0200, /* BCD: 02.00 (Version 2.0 USB spec) */
39 .bdeviceclass = 0xFF, /* 0xFF = vendor-specific */
40 .bdevicesubclass = 0xFF,
41 .bdeviceprotocol = 0xFF,
42 .bmaxpacketsize0 = 64,
43 .idvendor = 0x584e,
44 .idproduct = 0x424e,
45 .bcddevice = 0x0000,
46 .imanufacturer = 1,
47 .iproduct = 2,
48 .iserialnumber = 3,
49 .bnumconfigurations = 1
50 };
51
52 /* WARNING: ALL config, interface and endpoint descriptors MUST be adjacent! */
53
54 __code struct usb_config_descriptor config_descriptor = {
55 .blength = sizeof(struct usb_config_descriptor),
56 .bdescriptortype = DESCRIPTOR_TYPE_CONFIGURATION,
57 .wtotallength = sizeof(struct usb_config_descriptor) +
58 sizeof(struct usb_interface_descriptor) +
59 (NUM_ENDPOINTS * sizeof(struct usb_endpoint_descriptor)),
60 .bnuminterfaces = 1,
61 .bconfigurationvalue = 1,
62 .iconfiguration = 4, /* String describing this configuration */
63 .bmattributes = 0x80, /* Only MSB set according to USB spec */
64 .maxpower = 50 /* 100 mA */
65 };
66
67 __code struct usb_interface_descriptor interface_descriptor00 = {
68 .blength = sizeof(struct usb_interface_descriptor),
69 .bdescriptortype = DESCRIPTOR_TYPE_INTERFACE,
70 .binterfacenumber = 0,
71 .balternatesetting = 0,
72 .bnumendpoints = NUM_ENDPOINTS,
73 .binterfaceclass = 0xFF,
74 .binterfacesubclass = 0xFF,
75 .binterfaceprotocol = 0xFF,
76 .iinterface = 0
77 };
78
79 __code struct usb_endpoint_descriptor bulk_ep1_out_endpoint_descriptor = {
80 .blength = sizeof(struct usb_endpoint_descriptor),
81 .bdescriptortype = 0x05,
82 .bendpointaddress = (1 | USB_DIR_OUT),
83 .bmattributes = 0x02,
84 .wmaxpacketsize = 64,
85 .binterval = 0
86 };
87
88 __code struct usb_endpoint_descriptor bulk_ep1_in_endpoint_descriptor = {
89 .blength = sizeof(struct usb_endpoint_descriptor),
90 .bdescriptortype = 0x05,
91 .bendpointaddress = (1 | USB_DIR_IN),
92 .bmattributes = 0x02,
93 .wmaxpacketsize = 64,
94 .binterval = 0
95 };
96
97 __code struct usb_endpoint_descriptor bulk_ep2_endpoint_descriptor = {
98 .blength = sizeof(struct usb_endpoint_descriptor),
99 .bdescriptortype = 0x05,
100 .bendpointaddress = (2 | USB_DIR_OUT),
101 .bmattributes = 0x02,
102 .wmaxpacketsize = 512,
103 .binterval = 0
104 };
105
106 __code struct usb_endpoint_descriptor bulk_ep4_endpoint_descriptor = {
107 .blength = sizeof(struct usb_endpoint_descriptor),
108 .bdescriptortype = 0x05,
109 .bendpointaddress = (4 | USB_DIR_IN),
110 .bmattributes = 0x02,
111 .wmaxpacketsize = 512,
112 .binterval = 0
113 };
114
115 __code struct usb_endpoint_descriptor bulk_ep6_endpoint_descriptor = {
116 .blength = sizeof(struct usb_endpoint_descriptor),
117 .bdescriptortype = 0x05,
118 .bendpointaddress = (6 | USB_DIR_OUT),
119 .bmattributes = 0x02,
120 .wmaxpacketsize = 512,
121 .binterval = 0
122 };
123
124 __code struct usb_endpoint_descriptor bulk_ep8_endpoint_descriptor = {
125 .blength = sizeof(struct usb_endpoint_descriptor),
126 .bdescriptortype = 0x05,
127 .bendpointaddress = (8 | USB_DIR_OUT),
128 .bmattributes = 0x02,
129 .wmaxpacketsize = 512,
130 .binterval = 0
131 };
132
133 __code struct usb_language_descriptor language_descriptor = {
134 .blength = 4,
135 .bdescriptortype = DESCRIPTOR_TYPE_STRING,
136 .wlangid = {0x0409 /* US English */}
137 };
138
139 __code struct usb_string_descriptor strmanufacturer =
140 STR_DESCR(16, 'N', 'a', 'n', 'o', 'X', 'p', 'l', 'o', 'r', 'e', ',', ' ', 'S', 'A', 'S', '.');
141
142 __code struct usb_string_descriptor strproduct =
143 STR_DESCR(13, 'A', 'N', 'G', 'I', 'E', ' ', 'A', 'd', 'a', 'p', 't', 'e', 'r');
144
145 __code struct usb_string_descriptor strserialnumber =
146 STR_DESCR(6, '0', '0', '0', '0', '0', '1');
147
148 __code struct usb_string_descriptor strconfigdescr =
149 STR_DESCR(12, 'J', 'T', 'A', 'G', ' ', 'A', 'd', 'a', 'p', 't', 'e', 'r');
150
151 /* Table containing pointers to string descriptors */
152 __code struct usb_string_descriptor *__code en_string_descriptors[4] = {
153 &strmanufacturer,
154 &strproduct,
155 &strserialnumber,
156 &strconfigdescr
157 };
158 void sudav_isr(void)__interrupt SUDAV_ISR
159 {
160 EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */
161 USBIRQ = SUDAVI;
162 EP0CS |= HSNAK;
163 usb_handle_setup_data();
164 }
165 void sof_isr(void)__interrupt SOF_ISR
166 {
167 }
168 void sutok_isr(void)__interrupt SUTOK_ISR
169 {
170 }
171 void suspend_isr(void)__interrupt SUSPEND_ISR
172 {
173 }
174 void usbreset_isr(void)__interrupt USBRESET_ISR
175 {
176 }
177 void highspeed_isr(void)__interrupt HIGHSPEED_ISR
178 {
179 }
180 void ep0ack_isr(void)__interrupt EP0ACK_ISR
181 {
182 }
183 void stub_isr(void)__interrupt STUB_ISR
184 {
185 }
186 void ep0in_isr(void)__interrupt EP0IN_ISR
187 {
188 }
189 void ep0out_isr(void)__interrupt EP0OUT_ISR
190 {
191 }
192 void ep1in_isr(void)__interrupt EP1IN_ISR
193 {
194 ep1_in = true;
195
196 EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */
197 EPIRQ = 0x04; /* Clear individual EP1IN IRQ */
198 }
199 void ep1out_isr(void)__interrupt EP1OUT_ISR
200 {
201 ep1_out = true;
202
203 EXIF &= ~0x10; /* Clear USBINT: Main global interrupt */
204 EPIRQ = 0x08; /* Clear individual EP1OUT IRQ */
205 }
206 void ep2_isr(void)__interrupt EP2_ISR
207 {
208 ep1_out = false; /* Does nothing but required by the compiler */
209 }
210 void ep4_isr(void)__interrupt EP4_ISR
211 {
212 }
213 void ep6_isr(void)__interrupt EP6_ISR
214 {
215 }
216 void ep8_isr(void)__interrupt EP8_ISR
217 {
218 }
219 void ibn_isr(void)__interrupt IBN_ISR
220 {
221 }
222 void ep0pingnak_isr(void)__interrupt EP0PINGNAK_ISR
223 {
224 }
225 void ep1pingnak_isr(void)__interrupt EP1PINGNAK_ISR
226 {
227 }
228 void ep2pingnak_isr(void)__interrupt EP2PINGNAK_ISR
229 {
230 }
231 void ep4pingnak_isr(void)__interrupt EP4PINGNAK_ISR
232 {
233 }
234 void ep6pingnak_isr(void)__interrupt EP6PINGNAK_ISR
235 {
236 }
237 void ep8pingnak_isr(void)__interrupt EP8PINGNAK_ISR
238 {
239 }
240 void errorlimit_isr(void)__interrupt ERRORLIMIT_ISR
241 {
242 }
243 void ep2piderror_isr(void)__interrupt EP2PIDERROR_ISR
244 {
245 }
246 void ep4piderror_isr(void)__interrupt EP4PIDERROR_ISR
247 {
248 }
249 void ep6piderror_isr(void)__interrupt EP6PIDERROR_ISR
250 {
251 }
252 void ep8piderror_isr(void)__interrupt EP8PIDERROR_ISR
253 {
254 }
255 void ep2pflag_isr(void)__interrupt EP2PFLAG_ISR
256 {
257 }
258 void ep4pflag_isr(void)__interrupt EP4PFLAG_ISR
259 {
260 }
261 void ep6pflag_isr(void)__interrupt EP6PFLAG_ISR
262 {
263 }
264 void ep8pflag_isr(void)__interrupt EP8PFLAG_ISR
265 {
266 }
267 void ep2eflag_isr(void)__interrupt EP2EFLAG_ISR
268 {
269 }
270 void ep4eflag_isr(void)__interrupt EP4EFLAG_ISR
271 {
272 }
273 void ep6eflag_isr(void)__interrupt EP6EFLAG_ISR
274 {
275 }
276 void ep8eflag_isr(void)__interrupt EP8EFLAG_ISR
277 {
278 }
279 void ep2fflag_isr(void)__interrupt EP2FFLAG_ISR
280 {
281 }
282 void ep4fflag_isr(void)__interrupt EP4FFLAG_ISR
283 {
284 }
285 void ep6fflag_isr(void)__interrupt EP6FFLAG_ISR
286 {
287 }
288 void ep8fflag_isr(void)__interrupt EP8FFLAG_ISR
289 {
290 }
291 void gpifcomplete_isr(void)__interrupt GPIFCOMPLETE_ISR
292 {
293 }
294 void gpifwaveform_isr(void)__interrupt GPIFWAVEFORM_ISR
295 {
296 }
297
298 /**
299 * Return the control/status register for an endpoint
300 *
301 * @param ep endpoint address
302 * @return on success: pointer to Control & Status register for endpoint
303 * specified in \a ep
304 * @return on failure: NULL
305 */
306 __xdata uint8_t *usb_get_endpoint_cs_reg(uint8_t ep)
307 {
308 /* Mask direction bit */
309 uint8_t ep_num = ep & ~0x80;
310
311 switch (ep_num) {
312 case 0:
313 return &EP0CS;
314 case 1:
315 return ep & 0x80 ? &EP1INCS : &EP1OUTCS;
316 case 2:
317 return &EP2CS;
318 case 4:
319 return &EP4CS;
320 case 6:
321 return &EP6CS;
322 case 8:
323 return &EP8CS;
324 default:
325 return NULL;
326 }
327 }
328
329 void usb_reset_data_toggle(uint8_t ep)
330 {
331 /* TOGCTL register:
332 +----+-----+-----+------+-----+-------+-------+-------+
333 | Q | S | R | IO | EP3 | EP2 | EP1 | EP0 |
334 +----+-----+-----+------+-----+-------+-------+-------+
335
336 To reset data toggle bits, we have to write the endpoint direction (IN/OUT)
337 to the IO bit and the endpoint number to the EP2..EP0 bits. Then, in a
338 separate write cycle, the R bit needs to be set.
339 */
340 TOGCTL = (((ep & 0x80) >> 3) + (ep & 0x0F));
341 TOGCTL |= BMRESETTOGGLE;
342 }
343
344 /**
345 * Handle GET_STATUS request.
346 *
347 * @return on success: true
348 * @return on failure: false
349 */
350 bool usb_handle_get_status(void)
351 {
352 uint8_t *ep_cs;
353 switch (setup_data.bmrequesttype) {
354 case GS_DEVICE:
355 /* Two byte response: Byte 0, Bit 0 = self-powered, Bit 1 = remote wakeup.
356 * Byte 1: reserved, reset to zero */
357 EP0BUF[0] = 0;
358 EP0BUF[1] = 0;
359
360 /* Send response */
361 EP0BCH = 0;
362 syncdelay(3);
363 EP0BCL = 2;
364 syncdelay(3);
365 break;
366 case GS_INTERFACE:
367 /* Always return two zero bytes according to USB 1.1 spec, p. 191 */
368 EP0BUF[0] = 0;
369 EP0BUF[1] = 0;
370
371 /* Send response */
372 EP0BCH = 0;
373 syncdelay(3);
374 EP0BCL = 2;
375 syncdelay(3);
376 break;
377 case GS_ENDPOINT:
378 /* Get stall bit for endpoint specified in low byte of wIndex */
379 ep_cs = usb_get_endpoint_cs_reg(setup_data.windex & 0xff);
380
381 if (*ep_cs & EPSTALL)
382 EP0BUF[0] = 0x01;
383 else
384 EP0BUF[0] = 0x00;
385
386 /* Second byte sent has to be always zero */
387 EP0BUF[1] = 0;
388
389 /* Send response */
390 EP0BCH = 0;
391 syncdelay(3);
392 EP0BCL = 2;
393 syncdelay(3);
394 break;
395 default:
396 return false;
397 }
398 return true;
399 }
400
401 /**
402 * Handle CLEAR_FEATURE request.
403 *
404 * @return on success: true
405 * @return on failure: false
406 */
407 bool usb_handle_clear_feature(void)
408 {
409 __xdata uint8_t *ep_cs;
410
411 switch (setup_data.bmrequesttype) {
412 case CF_DEVICE:
413 /* Clear remote wakeup not supported: stall EP0 */
414 STALL_EP0();
415 break;
416 case CF_ENDPOINT:
417 if (setup_data.wvalue == 0) {
418 /* Unstall the endpoint specified in wIndex */
419 ep_cs = usb_get_endpoint_cs_reg(setup_data.windex);
420 if (!ep_cs)
421 return false;
422 *ep_cs &= ~EPSTALL;
423 } else {
424 /* Unsupported feature, stall EP0 */
425 STALL_EP0();
426 }
427 break;
428 default:
429 /* Vendor commands... */
430 break;
431 }
432 return true;
433 }
434
435 /**
436 * Handle SET_FEATURE request.
437 *
438 * @return on success: true
439 * @return on failure: false
440 */
441 bool usb_handle_set_feature(void)
442 {
443 __xdata uint8_t *ep_cs;
444
445 switch (setup_data.bmrequesttype) {
446 case SF_DEVICE:
447 if (setup_data.wvalue == 2)
448 return true;
449 break;
450 case SF_ENDPOINT:
451 if (setup_data.wvalue == 0) {
452 /* Stall the endpoint specified in wIndex */
453 ep_cs = usb_get_endpoint_cs_reg(setup_data.windex);
454 if (!ep_cs)
455 return false;
456 *ep_cs |= EPSTALL;
457 } else {
458 /* Unsupported endpoint feature */
459 return false;
460 }
461 break;
462 default:
463 /* Vendor commands... */
464 break;
465 }
466
467 return true;
468 }
469
470 /**
471 * Handle GET_DESCRIPTOR request.
472 *
473 * @return on success: true
474 * @return on failure: false
475 */
476 bool usb_handle_get_descriptor(void)
477 {
478 __xdata uint8_t descriptor_type;
479 __xdata uint8_t descriptor_index;
480
481 descriptor_type = (setup_data.wvalue & 0xff00) >> 8;
482 descriptor_index = setup_data.wvalue & 0x00ff;
483
484 switch (descriptor_type) {
485 case DESCRIPTOR_TYPE_DEVICE:
486 SUDPTRH = HI8(&device_descriptor);
487 SUDPTRL = LO8(&device_descriptor);
488 break;
489 case DESCRIPTOR_TYPE_CONFIGURATION:
490 SUDPTRH = HI8(&config_descriptor);
491 SUDPTRL = LO8(&config_descriptor);
492 break;
493 case DESCRIPTOR_TYPE_STRING:
494 if (setup_data.windex == 0) {
495 /* Supply language descriptor */
496 SUDPTRH = HI8(&language_descriptor);
497 SUDPTRL = LO8(&language_descriptor);
498 } else if (setup_data.windex == 0x0409 /* US English */) {
499 /* Supply string descriptor */
500 SUDPTRH = HI8(en_string_descriptors[descriptor_index - 1]);
501 SUDPTRL = LO8(en_string_descriptors[descriptor_index - 1]);
502 } else {
503 return false;
504 }
505 break;
506 default:
507 /* Unsupported descriptor type */
508 return false;
509 }
510 return true;
511 }
512
513 /**
514 * Handle SET_INTERFACE request.
515 */
516 void usb_handle_set_interface(void)
517 {
518 /* Reset Data Toggle */
519 usb_reset_data_toggle(USB_DIR_IN | 4);
520 usb_reset_data_toggle(USB_DIR_OUT | 2);
521
522 /* Unstall & clear busy flag of all valid IN endpoints */
523 EP1INCS = 0 | EPBSY;
524
525 /* Unstall all valid OUT endpoints, reset bytecounts */
526 EP1OUTCS = 0;
527 EP1OUTBC = 0;
528 syncdelay(3);
529 }
530
531 /* Initialize GPIF interface transfer count */
532 void set_gpif_cnt(uint32_t count)
533 {
534 GPIFTCB3 = (uint8_t)(((uint32_t)(count) >> 24) & 0x000000ff);
535 syncdelay(3);
536 GPIFTCB2 = (uint8_t)(((uint32_t)(count) >> 16) & 0x000000ff);
537 syncdelay(3);
538 GPIFTCB1 = (uint8_t)(((uint32_t)(count) >> 8) & 0x000000ff);
539 syncdelay(3);
540 GPIFTCB0 = (uint8_t)((uint32_t)(count) & 0x000000ff);
541 }
542
543 /*
544 * Vendor commands handling:
545 */
546 #define VR_CFGOPEN 0xB0
547 #define VR_CFGCLOSE 0xB1
548
549 uint8_t ix;
550 uint8_t bcnt;
551 uint8_t __xdata *eptr;
552 uint16_t wcnt;
553 uint32_t __xdata gcnt;
554 bool usb_handle_send_bitstream(void)
555 {
556 eptr = EP0BUF; /* points to EP0BUF 64-byte register */
557 wcnt = setup_data.wlength; /* total transfer count */
558
559 /* Clear EP0BUF for OUT requests */
560 if (setup_data.bmrequesttype & 0x80) {
561 bcnt = ((wcnt > 64) ? 64 : wcnt);
562 for (ix = 0; ix < bcnt; ix++)
563 eptr[ix] = 0;
564 }
565
566 switch (setup_data.brequest) {
567 case VR_CFGOPEN:
568 /* Clear bytecount / to allow new data in / to stops NAKing */
569 EP0BCH = 0;
570 EP0BCL = 0;
571 while (EP0CS & EPBSY)
572 ; /* wait to finish transferring in EP0BUF, until not busy */
573 gcnt = ((uint32_t)(eptr[0]) << 24) | ((uint32_t)(eptr[1]) << 16)
574 | ((uint32_t)(eptr[2]) << 8) | (uint32_t)(eptr[3]);
575 /* Angie board FPGA bitstream download */
576 switch ((setup_data.wvalue) & 0x00C0) {
577 case 0x00:
578 PIN_PROGRAM_B = 0; /* Apply RPGM- pulse */
579 GPIFWFSELECT = 0xF2; /* Restore Config mode waveforms select */
580 syncdelay(3);
581 EP2FIFOCFG = BMAUTOOUT; /* and Automatic 8-bit GPIF OUT mode */
582 syncdelay(3);
583 PIN_PROGRAM_B = 1; /* Negate RPGM- pulse */
584 delay_ms(10); /* FPGA init time < 10mS */
585 set_gpif_cnt(gcnt); /* Initialize GPIF interface transfer count */
586 PIN_RDWR_B = 0;
587 PIN_CSI_B = 0;
588 GPIFTRIG = GPIF_EP2; /* Trigger GPIF OUT transfer on EP2 */
589 syncdelay(3);
590 break;
591 default:
592 break;
593 }
594 break;
595 case VR_CFGCLOSE:
596 ix = 10;
597 /* wait until GPIF transaction has been completed */
598 while ((GPIFTRIG & BMGPIFDONE) == 0) {
599 if (ix-- == 0) {
600 printf("GPIF done time out\n");
601 break;
602 }
603 delay_ms(1);
604 }
605 switch ((setup_data.wvalue) & 0x00C0) {
606 case 0x00:
607 PIN_CSI_B = 1;
608 PIN_RDWR_B = 1;
609 IFCONFIG &= 0xFC; /* Exit gpif mode */
610 break;
611 default:
612 break;
613 }
614 EP0BCH = 0;
615 EP0BCL = (uint8_t)(setup_data.wlength); /* Signal buffer is filled */
616 break;
617 default:
618 return true; /* Error: unknown VR command */
619 }
620 return false; /* no error; command handled OK */
621 }
622
623 /**
624 * Handle the arrival of a USB Control Setup Packet.
625 */
626 void usb_handle_setup_data(void)
627 {
628 switch (setup_data.brequest) {
629 case GET_STATUS:
630 if (!usb_handle_get_status())
631 STALL_EP0();
632 break;
633 case CLEAR_FEATURE:
634 if (!usb_handle_clear_feature())
635 STALL_EP0();
636 break;
637 case 2: case 4:
638 /* Reserved values */
639 STALL_EP0();
640 break;
641 case SET_FEATURE:
642 if (!usb_handle_set_feature())
643 STALL_EP0();
644 break;
645 case SET_ADDRESS:
646 /* Handled by USB core */
647 break;
648 case SET_DESCRIPTOR:
649 /* Set Descriptor not supported. */
650 STALL_EP0();
651 break;
652 case GET_DESCRIPTOR:
653 if (!usb_handle_get_descriptor())
654 STALL_EP0();
655 break;
656 case GET_CONFIGURATION:
657 /* ANGIE has only one configuration, return its index */
658 EP0BUF[0] = config_descriptor.bconfigurationvalue;
659 EP0BCH = 0;
660 EP0BCL = 1;
661 syncdelay(3);
662 break;
663 case SET_CONFIGURATION:
664 /* ANGIE has only one configuration -> nothing to do */
665 break;
666 case GET_INTERFACE:
667 /* ANGIE only has one interface, return its number */
668 EP0BUF[0] = interface_descriptor00.binterfacenumber;
669 EP0BCH = 0;
670 EP0BCL = 1;
671 syncdelay(3);
672 break;
673 case SET_INTERFACE:
674 usb_handle_set_interface();
675 break;
676 case SYNCH_FRAME:
677 /* Isochronous endpoints not used -> nothing to do */
678 break;
679 default:
680 /* if not Vendor command, Stall EndPoint 0 */
681 if (usb_handle_send_bitstream())
682 STALL_EP0();
683 break;
684 }
685 }
686
687 /**
688 * Handle the initialization of endpoints.
689 */
690 void ep_init(void)
691 {
692 EP1INCFG = 0xA0;
693 syncdelay(3);
694 EP1OUTCFG = 0xA0;
695 syncdelay(3);
696 EP2CFG = 0xA0;
697 syncdelay(3);
698 EP4CFG = 0x00;
699 syncdelay(3);
700 EP6CFG = 0x00;
701 syncdelay(3);
702 EP8CFG = 0x00;
703 syncdelay(3);
704
705 /* arm EP1-OUT */
706 EP1OUTBC = 0;
707 syncdelay(3);
708 EP1OUTBC = 0;
709 syncdelay(3);
710
711 /* arm EP1-IN */
712 EP1INBC = 0;
713 syncdelay(3);
714 EP1INBC = 0;
715 syncdelay(3);
716
717 /* Standard procedure to reset FIFOs */
718 FIFORESET = BMNAKALL; /* NAK all transfers during the reset */
719 syncdelay(3);
720 FIFORESET = 0x02; /* reset EP2 FIFO */
721 syncdelay(3);
722 FIFORESET = 0x00; /* deactivate the NAK all */
723 syncdelay(3);
724 EP2FIFOCFG = 0x00;
725 syncdelay(3);
726 EP2FIFOCFG = BMAUTOOUT; /* Automatic 8-bit GPIF OUT mode */
727 syncdelay(3);
728 }
729
730 /**
731 * Interrupt initialization. Configures USB interrupts.
732 */
733 void interrupt_init(void)
734 {
735 /* Enable Interrupts */
736 EA = 1;
737
738 /* Enable USB interrupt (EIE register) */
739 EUSB = 1;
740 EICON |= 0x20;
741
742 /* Enable INT 2 & 4 Autovectoring */
743 INTSETUP |= (AV2EN | AV4EN);
744
745 /* Enable individual EP1OUT&IN interrupts */
746 EPIE |= 0x0C;
747
748 /* Clear individual USB interrupt IRQ */
749 EPIRQ = 0x0C;
750
751 /* Enable SUDAV interrupt */
752 USBIEN |= SUDAVI;
753
754 /* Clear SUDAV interrupt */
755 USBIRQ = SUDAVI;
756 }
757
758 /**
759 * Handle the initialization of io ports.
760 */
761 void io_init(void)
762 {
763 /* PORT A */
764 PORTACFG = 0x01; /* 0: normal ou 1: alternate function (each bit) */
765 OEA = 0xEF; /* all OUT exept INIT_B IN */
766 IOA = 0xFF;
767 PIN_RDWR_B = 1;
768 PIN_CSI_B = 1;
769 PIN_PROGRAM_B = 1;
770
771 /* PORT B */
772 OEB = 0xEF; /* all OUT exept TDO */
773 IOB = 0xFF;
774 PIN_TRST = 1;
775 PIN_TMS = 0;
776 PIN_TCK = 0;
777 PIN_TDI = 0;
778 PIN_SRST = 1;
779
780 /* PORT C */
781 PORTCCFG = 0x00; /* 0: normal ou 1: alternate function (each bit) */
782 OEC = 0xEF;
783 IOC = 0xFF;
784 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)