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

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)