drivers: Rename 'libusb1_common' to 'libusb_helper'
[openocd.git] / src / jtag / aice / aice_interface.c
1 /***************************************************************************
2 * Copyright (C) 2013 by Andes Technology *
3 * Hsiangkai Wang <hkwang@andestech.com> *
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, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include <jtag/interface.h>
24 #include <jtag/commands.h>
25 #include <transport/transport.h>
26 #include <target/target.h>
27 #include <jtag/aice/aice_transport.h>
28 #include "aice_usb.h"
29
30 #define AICE_KHZ_TO_SPEED_MAP_SIZE 16
31 static const int aice_khz_to_speed_map[AICE_KHZ_TO_SPEED_MAP_SIZE] = {
32 30000,
33 15000,
34 7500,
35 3750,
36 1875,
37 937,
38 468,
39 234,
40 48000,
41 24000,
42 12000,
43 6000,
44 3000,
45 1500,
46 750,
47 375,
48 };
49
50 static const struct aice_port *aice_port;
51 static struct aice_port_param_s param;
52 static uint32_t retry_times;
53 static uint32_t count_to_check_dbger;
54
55 /***************************************************************************/
56 /* External interface implementation */
57 static uint32_t aice_target_id_codes[AICE_MAX_NUM_CORE];
58 static uint8_t aice_num_of_target_id_codes;
59
60 /***************************************************************************/
61 /* AICE operations */
62 int aice_init_targets(void)
63 {
64 int res;
65 struct target *target;
66 struct aice_port_s *aice;
67
68 LOG_DEBUG("aice_init_targets");
69
70 if (aice_num_of_target_id_codes == 0) {
71 res = aice_port->api->idcode(aice_target_id_codes, &aice_num_of_target_id_codes);
72 if (res != ERROR_OK) {
73 LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore "
74 "JTAG Manufacture ID in the JTAG scan chain. "
75 "Failed to access EDM registers. -->");
76 return res;
77 }
78 }
79
80 for (target = all_targets; target; target = target->next) {
81 target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position];
82
83 unsigned ii, limit = target->tap->expected_ids_cnt;
84 int found = 0;
85
86 for (ii = 0; ii < limit; ii++) {
87 uint32_t expected = target->tap->expected_ids[ii];
88
89 /* treat "-expected-id 0" as a "don't-warn" wildcard */
90 if (!expected || (target->tap->idcode == expected)) {
91 found = 1;
92 break;
93 }
94 }
95
96 if (found == 0) {
97 LOG_ERROR
98 ("aice_init_targets: target not found: idcode: %" PRIx32,
99 target->tap->idcode);
100 return ERROR_FAIL;
101 }
102
103 aice = calloc(1, sizeof(struct aice_port_s));
104 aice->port = aice_port;
105 aice->coreid = target->tap->abs_chain_position;
106
107 target->tap->priv = aice;
108 target->tap->hasidcode = 1;
109 }
110
111 return ERROR_OK;
112 }
113
114 /***************************************************************************/
115 /* End of External interface implementation */
116
117 /* initial aice
118 * 1. open usb
119 * 2. get/show version number
120 * 3. reset
121 */
122 static int aice_init(void)
123 {
124 if (ERROR_OK != aice_port->api->open(&param)) {
125 LOG_ERROR("Cannot find AICE Interface! Please check "
126 "connection and permissions.");
127 return ERROR_JTAG_INIT_FAILED;
128 }
129
130 aice_port->api->set_retry_times(retry_times);
131 aice_port->api->set_count_to_check_dbger(count_to_check_dbger);
132
133 LOG_INFO("AICE JTAG Interface ready");
134
135 return ERROR_OK;
136 }
137
138 /* cleanup aice resource
139 * close usb
140 */
141 static int aice_quit(void)
142 {
143 aice_port->api->close();
144 return ERROR_OK;
145 }
146
147 static int aice_execute_reset(struct jtag_command *cmd)
148 {
149 static int last_trst;
150 int retval = ERROR_OK;
151
152 LOG_DEBUG_IO("reset trst: %d", cmd->cmd.reset->trst);
153
154 if (cmd->cmd.reset->trst != last_trst) {
155 if (cmd->cmd.reset->trst)
156 retval = aice_port->api->reset();
157
158 last_trst = cmd->cmd.reset->trst;
159 }
160
161 return retval;
162 }
163
164 static int aice_execute_command(struct jtag_command *cmd)
165 {
166 int retval;
167
168 switch (cmd->type) {
169 case JTAG_RESET:
170 retval = aice_execute_reset(cmd);
171 break;
172 default:
173 retval = ERROR_OK;
174 break;
175 }
176 return retval;
177 }
178
179 /* aice has no need to implement jtag execution model
180 */
181 static int aice_execute_queue(void)
182 {
183 struct jtag_command *cmd = jtag_command_queue; /* currently processed command */
184 int retval;
185
186 retval = ERROR_OK;
187
188 while (cmd) {
189 if (aice_execute_command(cmd) != ERROR_OK)
190 retval = ERROR_JTAG_QUEUE_FAILED;
191
192 cmd = cmd->next;
193 }
194
195 return retval;
196 }
197
198 /* set jtag frequency(base frequency/frequency divider) to your jtag adapter */
199 static int aice_speed(int speed)
200 {
201 return aice_port->api->set_jtag_clock(speed);
202 }
203
204 /* convert jtag adapter frequency(base frequency/frequency divider) to
205 * human readable KHz value */
206 static int aice_speed_div(int speed, int *khz)
207 {
208 *khz = aice_khz_to_speed_map[speed];
209
210 return ERROR_OK;
211 }
212
213 /* convert human readable KHz value to jtag adapter frequency
214 * (base frequency/frequency divider) */
215 static int aice_khz(int khz, int *jtag_speed)
216 {
217 int i;
218 for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++) {
219 if (khz == aice_khz_to_speed_map[i]) {
220 if (8 <= i)
221 *jtag_speed = i | AICE_TCK_CONTROL_TCK3048;
222 else
223 *jtag_speed = i;
224 break;
225 }
226 }
227
228 if (i == AICE_KHZ_TO_SPEED_MAP_SIZE) {
229 LOG_INFO("No support the jtag clock: %d", khz);
230 LOG_INFO("Supported jtag clocks are:");
231
232 for (i = 0 ; i < AICE_KHZ_TO_SPEED_MAP_SIZE ; i++)
233 LOG_INFO("* %d", aice_khz_to_speed_map[i]);
234
235 return ERROR_FAIL;
236 }
237
238 return ERROR_OK;
239 }
240
241 int aice_scan_jtag_chain(void)
242 {
243 LOG_DEBUG("=== %s ===", __func__);
244 uint8_t num_of_idcode = 0;
245 struct target *target;
246
247 int res = aice_port->api->idcode(aice_target_id_codes, &num_of_idcode);
248 if (res != ERROR_OK) {
249 LOG_ERROR("<-- TARGET ERROR! Failed to identify AndesCore "
250 "JTAG Manufacture ID in the JTAG scan chain. "
251 "Failed to access EDM registers. -->");
252 return res;
253 }
254
255 for (uint32_t i = 0; i < num_of_idcode; i++)
256 LOG_DEBUG("id_codes[%d] = 0x%x", i, aice_target_id_codes[i]);
257
258 /* Update tap idcode */
259 for (target = all_targets; target; target = target->next)
260 target->tap->idcode = aice_target_id_codes[target->tap->abs_chain_position];
261
262 return ERROR_OK;
263 }
264
265 /***************************************************************************/
266 /* Command handlers */
267 COMMAND_HANDLER(aice_handle_aice_info_command)
268 {
269 LOG_DEBUG("aice_handle_aice_info_command");
270
271 command_print(CMD, "Description: %s", param.device_desc);
272 command_print(CMD, "Serial number: %s", param.serial);
273 if (strncmp(aice_port->name, "aice_pipe", 9) == 0)
274 command_print(CMD, "Adapter: %s", param.adapter_name);
275
276 return ERROR_OK;
277 }
278
279 COMMAND_HANDLER(aice_handle_aice_port_command)
280 {
281 LOG_DEBUG("aice_handle_aice_port_command");
282
283 if (CMD_ARGC != 1) {
284 LOG_ERROR("Need exactly one argument to 'aice port'");
285 return ERROR_COMMAND_SYNTAX_ERROR;
286 }
287
288 for (const struct aice_port *l = aice_port_get_list(); l->name; l++) {
289 if (strcmp(l->name, CMD_ARGV[0]) == 0) {
290 aice_port = l;
291 return ERROR_OK;
292 }
293 }
294
295 LOG_ERROR("No AICE port '%s' found", CMD_ARGV[0]);
296 return ERROR_FAIL;
297 }
298
299 COMMAND_HANDLER(aice_handle_aice_desc_command)
300 {
301 LOG_DEBUG("aice_handle_aice_desc_command");
302
303 if (CMD_ARGC == 1)
304 param.device_desc = strdup(CMD_ARGV[0]);
305 else
306 LOG_ERROR("expected exactly one argument to aice desc <description>");
307
308 return ERROR_OK;
309 }
310
311 COMMAND_HANDLER(aice_handle_aice_serial_command)
312 {
313 LOG_DEBUG("aice_handle_aice_serial_command");
314
315 if (CMD_ARGC == 1)
316 param.serial = strdup(CMD_ARGV[0]);
317 else
318 LOG_ERROR("expected exactly one argument to aice serial <serial-number>");
319
320 return ERROR_OK;
321 }
322
323 COMMAND_HANDLER(aice_handle_aice_vid_pid_command)
324 {
325 LOG_DEBUG("aice_handle_aice_vid_pid_command");
326
327 if (CMD_ARGC != 2) {
328 LOG_WARNING("ignoring extra IDs in aice vid_pid (maximum is 1 pair)");
329 return ERROR_COMMAND_SYNTAX_ERROR;
330 }
331
332 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], param.vid);
333 COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], param.pid);
334
335 return ERROR_OK;
336 }
337
338 COMMAND_HANDLER(aice_handle_aice_adapter_command)
339 {
340 LOG_DEBUG("aice_handle_aice_adapter_command");
341
342 if (CMD_ARGC == 1)
343 param.adapter_name = strdup(CMD_ARGV[0]);
344 else
345 LOG_ERROR("expected exactly one argument to aice adapter <adapter-name>");
346
347 return ERROR_OK;
348 }
349
350 COMMAND_HANDLER(aice_handle_aice_retry_times_command)
351 {
352 LOG_DEBUG("aice_handle_aice_retry_times_command");
353
354 if (CMD_ARGC == 1)
355 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], retry_times);
356 else
357 LOG_ERROR("expected exactly one argument to aice retry_times <num_of_retry>");
358
359 return ERROR_OK;
360 }
361
362 COMMAND_HANDLER(aice_handle_aice_count_to_check_dbger_command)
363 {
364 LOG_DEBUG("aice_handle_aice_count_to_check_dbger_command");
365
366 if (CMD_ARGC == 1)
367 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], count_to_check_dbger);
368 else
369 LOG_ERROR("expected exactly one argument to aice count_to_check_dbger "
370 "<count_of_checking>");
371
372 return ERROR_OK;
373 }
374
375 COMMAND_HANDLER(aice_handle_aice_custom_srst_script_command)
376 {
377 LOG_DEBUG("aice_handle_aice_custom_srst_script_command");
378
379 if (CMD_ARGC > 0) {
380 aice_port->api->set_custom_srst_script(CMD_ARGV[0]);
381 return ERROR_OK;
382 }
383
384 return ERROR_FAIL;
385 }
386
387 COMMAND_HANDLER(aice_handle_aice_custom_trst_script_command)
388 {
389 LOG_DEBUG("aice_handle_aice_custom_trst_script_command");
390
391 if (CMD_ARGC > 0) {
392 aice_port->api->set_custom_trst_script(CMD_ARGV[0]);
393 return ERROR_OK;
394 }
395
396 return ERROR_FAIL;
397 }
398
399 COMMAND_HANDLER(aice_handle_aice_custom_restart_script_command)
400 {
401 LOG_DEBUG("aice_handle_aice_custom_restart_script_command");
402
403 if (CMD_ARGC > 0) {
404 aice_port->api->set_custom_restart_script(CMD_ARGV[0]);
405 return ERROR_OK;
406 }
407
408 return ERROR_FAIL;
409 }
410
411 COMMAND_HANDLER(aice_handle_aice_reset_command)
412 {
413 LOG_DEBUG("aice_handle_aice_reset_command");
414
415 return aice_port->api->reset();
416 }
417
418
419 static const struct command_registration aice_subcommand_handlers[] = {
420 {
421 .name = "info",
422 .handler = &aice_handle_aice_info_command,
423 .mode = COMMAND_EXEC,
424 .help = "show aice info",
425 .usage = "aice info",
426 },
427 {
428 .name = "port",
429 .handler = &aice_handle_aice_port_command,
430 .mode = COMMAND_CONFIG,
431 .help = "set the port of the AICE",
432 .usage = "aice port ['aice_pipe'|'aice_usb']",
433 },
434 {
435 .name = "desc",
436 .handler = &aice_handle_aice_desc_command,
437 .mode = COMMAND_CONFIG,
438 .help = "set the aice device description",
439 .usage = "aice desc [desciption string]",
440 },
441 {
442 .name = "serial",
443 .handler = &aice_handle_aice_serial_command,
444 .mode = COMMAND_CONFIG,
445 .help = "set the serial number of the AICE device",
446 .usage = "aice serial [serial string]",
447 },
448 {
449 .name = "vid_pid",
450 .handler = &aice_handle_aice_vid_pid_command,
451 .mode = COMMAND_CONFIG,
452 .help = "the vendor and product ID of the AICE device",
453 .usage = "aice vid_pid (vid pid)*",
454 },
455 {
456 .name = "adapter",
457 .handler = &aice_handle_aice_adapter_command,
458 .mode = COMMAND_CONFIG,
459 .help = "set the file name of adapter",
460 .usage = "aice adapter [adapter name]",
461 },
462 {
463 .name = "retry_times",
464 .handler = &aice_handle_aice_retry_times_command,
465 .mode = COMMAND_CONFIG,
466 .help = "set retry times as AICE timeout",
467 .usage = "aice retry_times num_of_retry",
468 },
469 {
470 .name = "count_to_check_dbger",
471 .handler = &aice_handle_aice_count_to_check_dbger_command,
472 .mode = COMMAND_CONFIG,
473 .help = "set retry times as checking $DBGER status",
474 .usage = "aice count_to_check_dbger count_of_checking",
475 },
476 {
477 .name = "custom_srst_script",
478 .handler = &aice_handle_aice_custom_srst_script_command,
479 .mode = COMMAND_CONFIG,
480 .usage = "custom_srst_script script_file_name",
481 .help = "set custom srst script",
482 },
483 {
484 .name = "custom_trst_script",
485 .handler = &aice_handle_aice_custom_trst_script_command,
486 .mode = COMMAND_CONFIG,
487 .usage = "custom_trst_script script_file_name",
488 .help = "set custom trst script",
489 },
490 {
491 .name = "custom_restart_script",
492 .handler = &aice_handle_aice_custom_restart_script_command,
493 .mode = COMMAND_CONFIG,
494 .usage = "custom_restart_script script_file_name",
495 .help = "set custom restart script",
496 },
497 {
498 .name = "reset",
499 .handler = &aice_handle_aice_reset_command,
500 .mode = COMMAND_EXEC,
501 .usage = "aice reset",
502 .help = "reset AICE",
503 },
504 COMMAND_REGISTRATION_DONE
505 };
506
507 static const struct command_registration aice_command_handlers[] = {
508 {
509 .name = "aice",
510 .mode = COMMAND_ANY,
511 .help = "perform aice management",
512 .usage = "aice [subcommand]",
513 .chain = aice_subcommand_handlers,
514 },
515 COMMAND_REGISTRATION_DONE
516 };
517 /***************************************************************************/
518 /* End of Command handlers */
519
520 static struct jtag_interface aice_interface = {
521 .execute_queue = aice_execute_queue,
522 };
523
524 struct adapter_driver aice_adapter_driver = {
525 .name = "aice",
526 .transports = aice_transports,
527 .commands = aice_command_handlers,
528
529 .init = aice_init,
530 .quit = aice_quit,
531 .speed = aice_speed, /* set interface speed */
532 .khz = aice_khz, /* convert khz to interface speed value */
533 .speed_div = aice_speed_div, /* return readable value */
534
535 .jtag_ops = &aice_interface,
536 };

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)