X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fjtag.c;h=a34a16fd66aab4b6135823fed26ae6aa8598e811;hp=073ce1f4553a429ef605301f5bddf7ca02fe6692;hb=02f3765351c9e25185b745b84f1a2604fb2149c7;hpb=054b091623edcdc962e8c65066039f38edf2f814 diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 073ce1f455..a34a16fd66 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -58,6 +58,8 @@ static cmd_queue_page_t *cmd_queue_pages = NULL; * 3: Pause-DR * 4: Shift-IR * 5: Pause-IR + * + * SD->SD and SI->SI have to be caught in interface specific code */ u8 tap_move[6][6] = { @@ -160,6 +162,14 @@ jtag_event_callback_t *jtag_event_callbacks; extern jtag_interface_t gw16012_interface; #endif +#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1 + extern jtag_interface_t presto_interface; +#endif + +#if BUILD_USBPROG == 1 + extern jtag_interface_t usbprog_interface; +#endif + jtag_interface_t *jtag_interfaces[] = { #if BUILD_PARPORT == 1 &parport_interface, @@ -181,6 +191,12 @@ jtag_interface_t *jtag_interfaces[] = { #endif #if BUILD_GW16012 == 1 &gw16012_interface, +#endif +#if BUILD_PRESTO_LIBFTDI == 1 || BUILD_PRESTO_FTD2XX == 1 + &presto_interface, +#endif +#if BUILD_USBPROG == 1 + &usbprog_interface, #endif NULL, }; @@ -1086,9 +1102,6 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) if (compare_failed) { - char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16); - char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, (num_bits > 64) ? 64 : num_bits, 16); - if (cmd->error_handler) { /* ask the error handler if once has been specified if this is a real problem */ @@ -1109,6 +1122,9 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) */ if (compare_failed) { + char *captured_char = buf_to_str(captured, (num_bits > 64) ? 64 : num_bits, 16); + char *in_check_value_char = buf_to_str(cmd->fields[i].in_check_value, (num_bits > 64) ? 64 : num_bits, 16); + if (cmd->fields[i].in_check_mask) { char *in_check_mask_char; @@ -1120,10 +1136,11 @@ int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) { WARNING("value captured during scan didn't pass the requested check: captured: 0x%s check_value: 0x%s", captured_char, in_check_value_char); } + + free(captured_char); + free(in_check_value_char); } - free(captured_char); - free(in_check_value_char); } } free(captured); @@ -1234,7 +1251,7 @@ int jtag_examine_chain() if ((zero_check == 0x00) || (one_check == 0xff)) { ERROR("JTAG communication failure, check connection, JTAG interface, target power etc."); - exit(-1); + return ERROR_JTAG_INIT_FAILED; } for (bit_count = 0; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;) @@ -1270,7 +1287,7 @@ int jtag_examine_chain() part = (idcode & 0xffff000) >> 12; version = (idcode & 0xf0000000) >> 28; - DEBUG("JTAG device found: 0x%8.8x (Manufacturer: 0x%3.3x, Part: 0x%4.4x, Version: 0x%1.1x", + INFO("JTAG device found: 0x%8.8x (Manufacturer: 0x%3.3x, Part: 0x%4.4x, Version: 0x%1.1x)", idcode, manufacturer, part, version); bit_count += 32; @@ -1282,7 +1299,8 @@ int jtag_examine_chain() { ERROR("number of discovered devices in JTAG chain (%i) doesn't match configuration (%i)", device_count, jtag_num_devices); - exit(-1); + ERROR("check the config file and ensure proper JTAG communication (connections, speed, ...)"); + return ERROR_JTAG_INIT_FAILED; } return ERROR_OK; @@ -1327,7 +1345,8 @@ int jtag_validate_chain() char *cbuf = buf_to_str(ir_test, total_ir_length, 16); ERROR("Error validating JTAG scan chain, IR mismatch, scan returned 0x%s", cbuf); free(cbuf); - exit(-1); + free(ir_test); + return ERROR_JTAG_INIT_FAILED; } chain_pos += device->ir_length; device = device->next; @@ -1338,7 +1357,8 @@ int jtag_validate_chain() char *cbuf = buf_to_str(ir_test, total_ir_length, 16); ERROR("Error validating JTAG scan chain, IR mismatch, scan returned 0x%s", cbuf); free(cbuf); - exit(-1); + free(ir_test); + return ERROR_JTAG_INIT_FAILED; } free(ir_test); @@ -1384,7 +1404,7 @@ int jtag_register_commands(struct command_context_s *cmd_ctx) int jtag_init(struct command_context_s *cmd_ctx) { - int i; + int i, validate_tries = 0; DEBUG("-"); @@ -1415,11 +1435,25 @@ int jtag_init(struct command_context_s *cmd_ctx) jtag_add_statemove(TAP_TLR); jtag_execute_queue(); + + /* examine chain first, as this could discover the real chain layout */ + if (jtag_examine_chain() != ERROR_OK) + { + ERROR("trying to validate configured JTAG chain anyway..."); + } - jtag_examine_chain(); - - jtag_validate_chain(); - + while (jtag_validate_chain() != ERROR_OK) + { + validate_tries++; + if (validate_tries > 5) + { + ERROR("Could not validate JTAG chain, exit"); + jtag = NULL; + return ERROR_JTAG_INVALID_INTERFACE; + } + usleep(10000); + } + return ERROR_OK; } } @@ -1537,8 +1571,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch jtag_reset_config = RESET_TRST_AND_SRST; else { - ERROR("invalid reset_config argument"); - exit(-1); + ERROR("invalid reset_config argument, defaulting to none"); + jtag_reset_config = RESET_NONE; + return ERROR_INVALID_ARGUMENTS; } } @@ -1554,8 +1589,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch jtag_reset_config &= ~(RESET_SRST_PULLS_TRST | RESET_TRST_PULLS_SRST); else { - ERROR("invalid reset_config argument"); - exit(-1); + ERROR("invalid reset_config argument, defaulting to none"); + jtag_reset_config = RESET_NONE; + return ERROR_INVALID_ARGUMENTS; } } @@ -1567,8 +1603,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch jtag_reset_config &= ~RESET_TRST_OPEN_DRAIN; else { - ERROR("invalid reset_config argument"); - exit(-1); + ERROR("invalid reset_config argument, defaulting to none"); + jtag_reset_config = RESET_NONE; + return ERROR_INVALID_ARGUMENTS; } } @@ -1580,8 +1617,9 @@ int handle_reset_config_command(struct command_context_s *cmd_ctx, char *cmd, ch jtag_reset_config &= ~RESET_SRST_PUSH_PULL; else { - ERROR("invalid reset_config argument"); - exit(-1); + ERROR("invalid reset_config argument, defaulting to none"); + jtag_reset_config = RESET_NONE; + return ERROR_INVALID_ARGUMENTS; } }