contrib/firmware: add new adapter ANGIE's firmware/bitstream code
[openocd.git] / contrib / firmware / angie / c / src / protocol.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /****************************************************************************
4 File : protocol.c *
5 Contents : Jtag commands handling protocol code for NanoXplore *
6 USB-JTAG 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 "protocol.h"
15 #include "jtag.h"
16 #include "delay.h"
17 #include "io.h"
18 #include "msgtypes.h"
19 #include "reg_ezusb.h"
20 #include <serial.h>
21 #include <stdio.h>
22
23 /** Index in EP1 Bulk-OUT data buffer that contains the current command ID */
24 volatile uint8_t cmd_id_index;
25
26 /** Number of data bytes already in EP1 Bulk-IN buffer */
27 volatile uint8_t payload_index_in;
28
29 /**
30 * Executes one command and updates global command indexes.
31 *
32 * @return true if this command was the last command.
33 * @return false if there are more commands within the current contents of the
34 * Bulk EP1-OUT data buffer.
35 */
36 bool execute_command(void)
37 {
38 uint8_t usb_out_bytecount, usb_in_bytecount;
39 uint16_t signal_state = 0;
40 uint16_t count;
41
42 /* Most commands do not transfer IN data. To save code space, we write 0 to
43 * usb_in_bytecount here, then modify it in the switch statement below where
44 * necessary */
45 usb_in_bytecount = 0;
46
47 switch (EP1OUTBUF[cmd_id_index] /* Command ID */) {
48 case CMD_SCAN_IN:
49 usb_out_bytecount = 5;
50 usb_in_bytecount = EP1OUTBUF[cmd_id_index + 1];
51 jtag_scan_in((cmd_id_index + 1), payload_index_in);
52 break;
53 case CMD_SCAN_OUT:
54 usb_out_bytecount = EP1OUTBUF[cmd_id_index + 1] + 5;
55 jtag_scan_out(cmd_id_index + 1);
56 break;
57 case CMD_SCAN_IO:
58 usb_in_bytecount = EP1OUTBUF[cmd_id_index + 1];
59 usb_out_bytecount = usb_in_bytecount + 5;
60 jtag_scan_io((cmd_id_index + 1), payload_index_in);
61 break;
62 case CMD_CLOCK_TMS:
63 usb_out_bytecount = 2;
64 jtag_clock_tms(EP1OUTBUF[cmd_id_index + 1], EP1OUTBUF[cmd_id_index + 2]);
65 break;
66 case CMD_CLOCK_TCK:
67 usb_out_bytecount = 2;
68 count = (uint16_t)EP1OUTBUF[cmd_id_index + 1];
69 count |= ((uint16_t)EP1OUTBUF[cmd_id_index + 2]) << 8;
70 jtag_clock_tck(count);
71 break;
72 case CMD_SLOW_SCAN_IN:
73 usb_out_bytecount = 5;
74 usb_in_bytecount = EP1OUTBUF[cmd_id_index + 1];
75 jtag_slow_scan_in(cmd_id_index + 1, payload_index_in);
76 break;
77 case CMD_SLOW_SCAN_OUT:
78 usb_out_bytecount = EP1OUTBUF[cmd_id_index + 1] + 5;
79 jtag_slow_scan_out(cmd_id_index + 1);
80 break;
81 case CMD_SLOW_SCAN_IO:
82 usb_in_bytecount = EP1OUTBUF[cmd_id_index + 1];
83 usb_out_bytecount = usb_in_bytecount + 5;
84 jtag_slow_scan_io(cmd_id_index + 1, payload_index_in);
85 break;
86 case CMD_SLOW_CLOCK_TMS:
87 usb_out_bytecount = 2;
88 jtag_slow_clock_tms(EP1OUTBUF[cmd_id_index + 1], EP1OUTBUF[cmd_id_index + 2]);
89 break;
90 case CMD_SLOW_CLOCK_TCK:
91 usb_out_bytecount = 2;
92 count = (uint16_t)EP1OUTBUF[cmd_id_index + 1];
93 count |= ((uint16_t)EP1OUTBUF[cmd_id_index + 2]) << 8;
94 jtag_slow_clock_tck(count);
95 break;
96 case CMD_SLEEP_US:
97 usb_out_bytecount = 2;
98 count = (uint16_t)EP1OUTBUF[cmd_id_index + 1];
99 count |= ((uint16_t)EP1OUTBUF[cmd_id_index + 2]) << 8;
100 delay_us(count);
101 break;
102 case CMD_SLEEP_MS:
103 usb_out_bytecount = 2;
104 count = (uint16_t)EP1OUTBUF[cmd_id_index + 1];
105 count |= ((uint16_t)EP1OUTBUF[cmd_id_index + 2]) << 8;
106 delay_ms(count);
107 break;
108 case CMD_GET_SIGNALS:
109 usb_out_bytecount = 0;
110 usb_in_bytecount = 2;
111 signal_state = jtag_get_signals();
112 EP1INBUF[payload_index_in] = (signal_state >> 8);
113 EP1INBUF[payload_index_in + 1] = (signal_state & 0xFF);
114 break;
115 case CMD_SET_SIGNALS:
116 usb_out_bytecount = 2;
117 jtag_set_signals(EP1OUTBUF[cmd_id_index + 1], EP1OUTBUF[cmd_id_index + 2]);
118 break;
119 case CMD_CONFIGURE_TCK_FREQ:
120 usb_out_bytecount = 5;
121 jtag_configure_tck_delay(EP1OUTBUF[cmd_id_index + 1], /* scan_in */
122 EP1OUTBUF[cmd_id_index + 2], /* scan_out */
123 EP1OUTBUF[cmd_id_index + 3], /* scan_io */
124 EP1OUTBUF[cmd_id_index + 4], /* clock_tck */
125 EP1OUTBUF[cmd_id_index + 5]); /* clock_tms */
126 break;
127 case CMD_TEST:
128 usb_out_bytecount = 1;
129 /* Do nothing... This command is only used to test if the device is ready
130 * to accept new commands */
131 break;
132 default:
133 /* Should never be reached */
134 usb_out_bytecount = 0;
135 break;
136 }
137
138 /* Update EP1 Bulk-IN data byte count */
139 payload_index_in += usb_in_bytecount;
140
141 /* Determine if this was the last command */
142 if ((cmd_id_index + usb_out_bytecount + 1) >= EP1OUTBC) {
143 return true;
144 /* Line between return and else required by checkpatch: */
145 uint8_t a = 0;
146 } else {
147 /* Not the last command, update cmd_id_index */
148 cmd_id_index += (usb_out_bytecount + 1);
149 return false;
150 }
151 }
152
153 /**
154 * Forever wait for commands and execute them as they arrive.
155 */
156 void command_loop(void)
157 {
158 bool last_command;
159 while (1) {
160 cmd_id_index = 0;
161 payload_index_in = 0;
162
163 /* Wait until host sends EP1 Bulk-OUT packet */
164 while (!ep1_out)
165 ;
166 ep1_out = false;
167
168 /* Execute the commands */
169 last_command = false;
170 while (!last_command)
171 last_command = execute_command();
172
173 /* Send back EP6 Bulk-IN packet if required */
174 if (payload_index_in > 0) {
175 EP1INBC = payload_index_in;
176 syncdelay(3);
177
178 while (!ep1_in)
179 ;
180 ep1_in = false;
181 }
182
183 /* Re-arm EP1-OUT after command execution */
184 EP1OUTBC = 0;
185 syncdelay(3);
186 EP1OUTBC = 0;
187 syncdelay(3);
188 }
189 }

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)