X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fjtag.c;h=90d52d0f0093c0a91e1b8da51c9ad06616b2156c;hb=68c598e88d5e09728ea845a81ab279c615bbaf0f;hp=34147651ada25916192fb48ae874c92721561b9f;hpb=afe5371bc8bde3fc1a833c3d7e459920711a9584;p=openocd.git diff --git a/src/jtag/jtag.c b/src/jtag/jtag.c index 34147651ad..90d52d0f00 100644 --- a/src/jtag/jtag.c +++ b/src/jtag/jtag.c @@ -2,6 +2,9 @@ * Copyright (C) 2005 by Dominic Rath * * Dominic.Rath@gmx.de * * * + * Copyright (C) 2007,2008 Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * @@ -27,13 +30,11 @@ #include "command.h" #include "log.h" -#include "interpreter.h" #include "stdlib.h" #include "string.h" #include - /* note that this is not marked as static as it must be available from outside jtag.c for those that implement the jtag_xxx() minidriver layer */ @@ -106,9 +107,14 @@ tap_transition_t tap_transitions[16] = char* jtag_event_strings[] = { - "JTAG controller reset(tms or TRST)" + "JTAG controller reset (TLR or TRST)" }; +/* kludge!!!! these are just global variables that the + * interface use internally. They really belong + * inside the drivers, but we don't want to break + * linking the drivers!!!! + */ enum tap_state end_state = TAP_TLR; enum tap_state cur_state = TAP_TLR; int jtag_trst = 0; @@ -136,6 +142,11 @@ int jtag_ntrst_delay = 0; /* default to no nTRST delay */ /* callbacks to inform high-level handlers about JTAG state changes */ jtag_event_callback_t *jtag_event_callbacks; +/* speed in kHz*/ +static int speed_khz = 0; +/* flag if the kHz speed was defined */ +static int hasKHz = 0; + /* jtag interfaces (parport, FTDI-USB, TI-USB, ...) */ @@ -146,7 +157,11 @@ jtag_event_callback_t *jtag_event_callbacks; #if BUILD_PARPORT == 1 extern jtag_interface_t parport_interface; #endif - + +#if BUILD_DUMMY == 1 + extern jtag_interface_t dummy_interface; +#endif + #if BUILD_FT2232_FTD2XX == 1 extern jtag_interface_t ft2232_interface; #endif @@ -179,6 +194,10 @@ jtag_event_callback_t *jtag_event_callbacks; extern jtag_interface_t usbprog_interface; #endif +#if BUILD_JLINK == 1 + extern jtag_interface_t jlink_interface; +#endif + jtag_interface_t *jtag_interfaces[] = { #if BUILD_ECOSBOARD == 1 &eCosBoard_interface, @@ -186,6 +205,9 @@ jtag_interface_t *jtag_interfaces[] = { #if BUILD_PARPORT == 1 &parport_interface, #endif +#if BUILD_DUMMY == 1 + &dummy_interface, +#endif #if BUILD_FT2232_FTD2XX == 1 &ft2232_interface, #endif @@ -209,6 +231,9 @@ jtag_interface_t *jtag_interfaces[] = { #endif #if BUILD_USBPROG == 1 &usbprog_interface, +#endif +#if BUILD_JLINK == 1 + &jlink_interface, #endif NULL, }; @@ -218,7 +243,7 @@ jtag_interface_t *jtag = NULL; /* configuration */ jtag_interface_t *jtag_interface = NULL; int jtag_speed = 0; -int jtag_speed_post_reset = 0; + /* forward declarations */ @@ -227,7 +252,7 @@ void jtag_add_runtest(int num_cycles, enum tap_state endstate); void jtag_add_end_state(enum tap_state endstate); void jtag_add_sleep(u32 us); int jtag_execute_queue(void); -int jtag_cancel_queue(void); + /* jtag commands */ int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -244,7 +269,7 @@ int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char * int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); -int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *argv); int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); @@ -351,6 +376,7 @@ void* cmd_queue_alloc(size_t size) { cmd_queue_page_t **p_page = &cmd_queue_pages; int offset; + u8 *t; if (*p_page) { @@ -371,11 +397,11 @@ void* cmd_queue_alloc(size_t size) offset = (*p_page)->used; (*p_page)->used += size; - u8 *t=(u8 *)((*p_page)->address); + t=(u8 *)((*p_page)->address); return t + offset; } -void cmd_queue_free() +void cmd_queue_free(void) { cmd_queue_page_t *page = cmd_queue_pages; @@ -390,7 +416,7 @@ void cmd_queue_free() cmd_queue_pages = NULL; } -static void jtag_prelude1() +static void jtag_prelude1(void) { if (jtag_trst == 1) { @@ -415,9 +441,11 @@ static void jtag_prelude(enum tap_state state) void jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) { + int retval; + jtag_prelude(state); - int retval=interface_jtag_add_ir_scan(num_fields, fields, cmd_queue_end_state); + retval=interface_jtag_add_ir_scan(num_fields, fields, cmd_queue_end_state); if (retval!=ERROR_OK) jtag_error=retval; } @@ -501,9 +529,11 @@ int MINIDRIVER(interface_jtag_add_ir_scan)(int num_fields, scan_field_t *fields, void jtag_add_plain_ir_scan(int num_fields, scan_field_t *fields, enum tap_state state) { + int retval; + jtag_prelude(state); - int retval=interface_jtag_add_plain_ir_scan(num_fields, fields, cmd_queue_end_state); + retval=interface_jtag_add_plain_ir_scan(num_fields, fields, cmd_queue_end_state); if (retval!=ERROR_OK) jtag_error=retval; } @@ -547,9 +577,11 @@ int MINIDRIVER(interface_jtag_add_plain_ir_scan)(int num_fields, scan_field_t *f void jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) { + int retval; + jtag_prelude(state); - int retval=interface_jtag_add_dr_scan(num_fields, fields, cmd_queue_end_state); + retval=interface_jtag_add_dr_scan(num_fields, fields, cmd_queue_end_state); if (retval!=ERROR_OK) jtag_error=retval; } @@ -571,6 +603,11 @@ int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, bypass_devices++; device = device->next; } + if (bypass_devices >= jtag_num_devices) + { + LOG_ERROR("all devices in bypass"); + return ERROR_JTAG_DEVICE_ERROR; + } /* allocate memory for a new list member */ *last_cmd = cmd_queue_alloc(sizeof(jtag_command_t)); @@ -643,8 +680,8 @@ int MINIDRIVER(interface_jtag_add_dr_scan)(int num_fields, scan_field_t *fields, void MINIDRIVER(interface_jtag_add_dr_out)(int device_num, int num_fields, - int *num_bits, - u32 *value, + const int *num_bits, + const u32 *value, enum tap_state end_state) { int i; @@ -727,14 +764,13 @@ void MINIDRIVER(interface_jtag_add_dr_out)(int device_num, } } - - - void jtag_add_plain_dr_scan(int num_fields, scan_field_t *fields, enum tap_state state) { + int retval; + jtag_prelude(state); - int retval=interface_jtag_add_plain_dr_scan(num_fields, fields, cmd_queue_end_state); + retval=interface_jtag_add_plain_dr_scan(num_fields, fields, cmd_queue_end_state); if (retval!=ERROR_OK) jtag_error=retval; } @@ -775,17 +811,17 @@ int MINIDRIVER(interface_jtag_add_plain_dr_scan)(int num_fields, scan_field_t *f return ERROR_OK; } -void jtag_add_tms() +void jtag_add_tlr(void) { jtag_prelude(TAP_TLR); int retval; - retval=interface_jtag_add_tms(); + retval=interface_jtag_add_tlr(); if (retval!=ERROR_OK) jtag_error=retval; } -int MINIDRIVER(interface_jtag_add_tms)() +int MINIDRIVER(interface_jtag_add_tlr)() { enum tap_state state = TAP_TLR; jtag_command_t **last_cmd = jtag_get_last_command_p(); @@ -805,6 +841,10 @@ int MINIDRIVER(interface_jtag_add_tms)() void jtag_add_pathmove(int num_states, enum tap_state *path) { + enum tap_state cur_state=cmd_queue_cur_state; + int i; + int retval; + /* the last state has to be a stable state */ if (tap_move_map[path[num_states - 1]] == -1) { @@ -812,10 +852,13 @@ void jtag_add_pathmove(int num_states, enum tap_state *path) exit(-1); } - enum tap_state cur_state=cmd_queue_cur_state; - int i; for (i=0; i 0,0 transition.... */ + //LOG_ERROR("BUG: transition of req_tlr_or_trst and req_srst in the same jtag_add_reset() call is undefined"); + } + } + /* Make sure that jtag_reset_config allows the requested reset */ /* if SRST pulls TRST, we can't fulfill srst == 1 with trst == 0 */ - if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (!req_tms_or_trst)) + if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (!req_tlr_or_trst)) { LOG_ERROR("BUG: requested reset would assert trst"); jtag_error=ERROR_FAIL; @@ -898,9 +959,9 @@ void jtag_add_reset(int req_tms_or_trst, int req_srst) } /* if TRST pulls SRST, we reset with TAP T-L-R */ - if (((jtag_reset_config & RESET_TRST_PULLS_SRST) && (req_tms_or_trst)) && (req_srst == 0)) + if (((jtag_reset_config & RESET_TRST_PULLS_SRST) && (req_tlr_or_trst)) && (req_srst == 0)) { - trst_with_tms = 1; + trst_with_tlr = 1; } if (req_srst && !(jtag_reset_config & RESET_HAS_SRST)) @@ -910,14 +971,14 @@ void jtag_add_reset(int req_tms_or_trst, int req_srst) return; } - if (req_tms_or_trst) + if (req_tlr_or_trst) { - if (!trst_with_tms && (jtag_reset_config & RESET_HAS_TRST)) + if (!trst_with_tlr && (jtag_reset_config & RESET_HAS_TRST)) { jtag_trst = 1; } else { - trst_with_tms = 1; + trst_with_tlr = 1; } } else { @@ -944,11 +1005,11 @@ void jtag_add_reset(int req_tms_or_trst, int req_srst) jtag_add_sleep(jtag_nsrst_delay * 1000); } - if (trst_with_tms) + if (trst_with_tlr) { - LOG_DEBUG("JTAG reset with tms instead of TRST"); + LOG_DEBUG("JTAG reset with TLR instead of TRST"); jtag_add_end_state(TAP_TLR); - jtag_add_tms(); + jtag_add_tlr(); jtag_call_event_callbacks(JTAG_TRST_ASSERTED); return; } @@ -983,14 +1044,13 @@ int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst) (*last_cmd)->cmd.reset->trst = req_trst; (*last_cmd)->cmd.reset->srst = req_srst; - return ERROR_OK; } void jtag_add_end_state(enum tap_state state) { cmd_queue_end_state = state; - if ((cmd_queue_end_state == TAP_SD)||(cmd_queue_end_state == TAP_SD)) + if ((cmd_queue_end_state == TAP_SD)||(cmd_queue_end_state == TAP_SI)) { LOG_ERROR("BUG: TAP_SD/SI can't be end state. Calling code should use a larger scan field"); } @@ -1014,6 +1074,7 @@ int MINIDRIVER(interface_jtag_add_sleep)(u32 us) void jtag_add_sleep(u32 us) { + keep_alive(); /* we might be running on a very slow JTAG clk */ int retval=interface_jtag_add_sleep(us); if (retval!=ERROR_OK) jtag_error=retval; @@ -1062,7 +1123,6 @@ int jtag_build_buffer(scan_command_t *cmd, u8 **buffer) } return bit_count; - } int jtag_read_buffer(u8 *buffer, scan_command_t *cmd) @@ -1182,7 +1242,7 @@ void jtag_set_check_value(scan_field_t *field, u8 *value, u8 *mask, error_handle field->in_handler = jtag_check_value; else field->in_handler = NULL; /* No check, e.g. embeddedice uses value==NULL to indicate no check */ - field->in_handler_priv = NULL; /* this will be filled in at the invocation site to point to the field duplicate */ + field->in_handler_priv = NULL; field->in_check_value = value; field->in_check_mask = mask; } @@ -1206,7 +1266,13 @@ enum scan_type jtag_scan_type(scan_command_t *cmd) int MINIDRIVER(interface_jtag_execute_queue)(void) { int retval; - + + if (jtag==NULL) + { + LOG_ERROR("No JTAG interface configured yet. Issue 'init' command in startup scripts before communicating with targets."); + return ERROR_FAIL; + } + retval = jtag->execute_queue(); cmd_queue_free(); @@ -1245,12 +1311,12 @@ int jtag_reset_callback(enum jtag_event event, void *priv) void jtag_sleep(u32 us) { - usleep(us); + alive_sleep(us/1000); } /* Try to examine chain layout according to IEEE 1149.1 §12 */ -int jtag_examine_chain() +int jtag_examine_chain(void) { jtag_device_t *device = jtag_devices; scan_field_t field; @@ -1298,7 +1364,8 @@ int jtag_examine_chain() if ((idcode & 1) == 0) { /* LSB must not be 0, this indicates a device in bypass */ - device_count++; + LOG_WARNING("Device does not have IDCODE"); + idcode=0; bit_count += 1; } @@ -1310,17 +1377,31 @@ int jtag_examine_chain() if (idcode == 0x000000FF) { - /* End of chain (invalid manufacturer ID) */ + int unexpected=0; + /* End of chain (invalid manufacturer ID) + * + * The JTAG examine is the very first thing that happens + * + * A single JTAG device requires only 64 bits to be read back correctly. + * + * The code below adds a check that the rest of the data scanned (640 bits) + * are all as expected. This helps diagnose/catch problems with the JTAG chain + * + * earlier and gives more helpful/explicit error messages. + */ + for (bit_count += 32; bit_count < (JTAG_MAX_CHAIN_SIZE * 32) - 31;bit_count += 32) + { + idcode = buf_get_u32(idcode_buffer, bit_count, 32); + if (unexpected||(idcode != 0x000000FF)) + { + LOG_WARNING("Unexpected idcode after end of chain! %d 0x%08x", bit_count, idcode); + unexpected = 1; + } + } + break; } - if (device) - { - device->idcode = idcode; - device = device->next; - } - device_count++; - manufacturer = (idcode & 0xffe) >> 1; part = (idcode & 0xffff000) >> 12; version = (idcode & 0xf0000000) >> 28; @@ -1330,6 +1411,12 @@ int jtag_examine_chain() bit_count += 32; } + if (device) + { + device->idcode = idcode; + device = device->next; + } + device_count++; } /* see if number of discovered devices matches configuration */ @@ -1344,7 +1431,7 @@ int jtag_examine_chain() return ERROR_OK; } -int jtag_validate_chain() +int jtag_validate_chain(void) { jtag_device_t *device = jtag_devices; int total_ir_length = 0; @@ -1404,12 +1491,73 @@ int jtag_validate_chain() return ERROR_OK; } + +static int +jim_jtag_command( Jim_Interp *interp, int argc, Jim_Obj *const *argv ) +{ + Jim_GetOptInfo goi; + int e; + Jim_Nvp *n; + struct command_context_s *context; + + enum { + JTAG_CMD_INTERFACE, + JTAG_CMD_INIT_RESET, + }; + + const Jim_Nvp jtag_cmds[] = { + { .name = "interface" , .value = JTAG_CMD_INTERFACE }, + { .name = "arp_init-reset", .value = JTAG_CMD_INIT_RESET }, + + { .name = NULL, .value = -1 }, + }; + + context = Jim_GetAssocData(interp, "context"); + // go past the command + Jim_GetOpt_Setup( &goi, interp, argc-1, argv+1 ); + + e = Jim_GetOpt_Nvp( &goi, jtag_cmds, &n ); + if( e != JIM_OK ){ + Jim_GetOpt_NvpUnknown( &goi, jtag_cmds, 0 ); + return e; + } + Jim_SetEmptyResult( goi.interp ); + switch( n->value ){ + case JTAG_CMD_INTERFACE: + // return the name of the interface + // TCL code might need to know the exact type... + // FUTURE: we allow this as a means to "set" the interface. + if( goi.argc != 0 ){ + Jim_WrongNumArgs( goi.interp, 1, goi.argv-1, "(no params)"); + return JIM_ERR; + } + Jim_SetResultString( goi.interp, jtag_interface->name, -1 ); + return JIM_OK; + case JTAG_CMD_INIT_RESET: + if( goi.argc != 0 ){ + Jim_WrongNumArgs( goi.interp, 1, goi.argv-1, "(no params)"); + return JIM_ERR; + } + e = jtag_init_reset(context); + if( e != ERROR_OK ){ + Jim_SetResult_sprintf( goi.interp, "error: %d", e); + return JIM_ERR; + } + return JIM_OK; + } + + + return JIM_ERR; +} + int jtag_register_commands(struct command_context_s *cmd_ctx) { + register_jim( cmd_ctx, "jtag", jim_jtag_command, "perform jtag tap actions"); + register_command(cmd_ctx, NULL, "interface", handle_interface_command, COMMAND_CONFIG, NULL); register_command(cmd_ctx, NULL, "jtag_speed", handle_jtag_speed_command, - COMMAND_ANY, "set jtag speed (if supported) []"); + COMMAND_ANY, "set jtag speed (if supported)"); register_command(cmd_ctx, NULL, "jtag_khz", handle_jtag_khz_command, COMMAND_ANY, "same as jtag_speed, except it takes maximum khz as arguments. 0 KHz = RTCK."); register_command(cmd_ctx, NULL, "jtag_device", handle_jtag_device_command, @@ -1417,9 +1565,9 @@ int jtag_register_commands(struct command_context_s *cmd_ctx) register_command(cmd_ctx, NULL, "reset_config", handle_reset_config_command, COMMAND_CONFIG, NULL); register_command(cmd_ctx, NULL, "jtag_nsrst_delay", handle_jtag_nsrst_delay_command, - COMMAND_CONFIG, NULL); + COMMAND_ANY, "jtag_nsrst_delay - delay after deasserting srst in ms"); register_command(cmd_ctx, NULL, "jtag_ntrst_delay", handle_jtag_ntrst_delay_command, - COMMAND_CONFIG, NULL); + COMMAND_ANY, "jtag_ntrst_delay - delay after deasserting trst in ms"); register_command(cmd_ctx, NULL, "scan_chain", handle_scan_chain_command, COMMAND_EXEC, "print current scan chain configuration"); @@ -1432,8 +1580,7 @@ int jtag_register_commands(struct command_context_s *cmd_ctx) COMMAND_EXEC, "move to Run-Test/Idle, and execute "); register_command(cmd_ctx, NULL, "irscan", handle_irscan_command, COMMAND_EXEC, "execute IR scan [dev2] [instr2] ..."); - register_command(cmd_ctx, NULL, "drscan", handle_drscan_command, - COMMAND_EXEC, "execute DR scan [dev2] [var2] ..."); + register_jim(cmd_ctx, "drscan", Jim_Command_drscan, "execute DR scan ..."); register_command(cmd_ctx, NULL, "verify_ircapture", handle_verify_ircapture_command, COMMAND_ANY, "verify value captured during Capture-IR "); @@ -1442,30 +1589,37 @@ int jtag_register_commands(struct command_context_s *cmd_ctx) int jtag_interface_init(struct command_context_s *cmd_ctx) { + if (jtag) + return ERROR_OK; + if (!jtag_interface) { /* nothing was previously specified by "interface" command */ LOG_ERROR("JTAG interface has to be specified, see \"interface\" command"); return ERROR_JTAG_INVALID_INTERFACE; } + if(hasKHz) + { + jtag_interface->khz(speed_khz, &jtag_speed); + hasKHz = 0; + } if (jtag_interface->init() != ERROR_OK) return ERROR_JTAG_INIT_FAILED; + + jtag = jtag_interface; return ERROR_OK; } -int jtag_init(struct command_context_s *cmd_ctx) +static int jtag_init_inner(struct command_context_s *cmd_ctx) { - int validate_tries = 0; jtag_device_t *device; + int retval; - LOG_DEBUG("-"); + LOG_DEBUG("Init JTAG chain"); - if (!jtag && jtag_interface_init(cmd_ctx) != ERROR_OK) - return ERROR_JTAG_INIT_FAILED; - device = jtag_devices; jtag_ir_scan_size = 0; jtag_num_devices = 0; @@ -1476,8 +1630,9 @@ int jtag_init(struct command_context_s *cmd_ctx) device = device->next; } - jtag_add_tms(); - jtag_execute_queue(); + jtag_add_tlr(); + if ((retval=jtag_execute_queue())!=ERROR_OK) + return retval; /* examine chain first, as this could discover the real chain layout */ if (jtag_examine_chain() != ERROR_OK) @@ -1485,20 +1640,70 @@ int jtag_init(struct command_context_s *cmd_ctx) LOG_ERROR("trying to validate configured JTAG chain anyway..."); } - while (jtag_validate_chain() != ERROR_OK) + if (jtag_validate_chain() != ERROR_OK) { - validate_tries++; - if (validate_tries > 5) - { - LOG_ERROR("Could not validate JTAG chain, exit"); - return ERROR_JTAG_INVALID_INTERFACE; - } - usleep(10000); + LOG_ERROR("Could not validate JTAG chain, continuing anyway..."); } - + return ERROR_OK; } +int jtag_init_reset(struct command_context_s *cmd_ctx) +{ + int retval; + + if ((retval=jtag_interface_init(cmd_ctx)) != ERROR_OK) + return retval; + + LOG_DEBUG("Trying to bring the JTAG controller to life by asserting TRST / TLR"); + + /* Reset can happen after a power cycle. + * + * Ideally we would only assert TRST or run TLR before the target reset. + * + * However w/srst_pulls_trst, trst is asserted together with the target + * reset whether we want it or not. + * + * NB! Some targets have JTAG circuitry disabled until a + * trst & srst has been asserted. + * + * NB! here we assume nsrst/ntrst delay are sufficient! + * + * NB! order matters!!!! srst *can* disconnect JTAG circuitry + * + */ + jtag_add_reset(1, 0); /* TLR or TRST */ + if (jtag_reset_config & RESET_HAS_SRST) + { + jtag_add_reset(1, 1); + if ((jtag_reset_config & RESET_SRST_PULLS_TRST)==0) + jtag_add_reset(0, 1); + } + jtag_add_reset(0, 0); + if ((retval = jtag_execute_queue()) != ERROR_OK) + return retval; + + /* Check that we can communication on the JTAG chain + eventually we want to + * be able to perform enumeration only after OpenOCD has started + * telnet and GDB server + * + * That would allow users to more easily perform any magic they need to before + * reset happens. + */ + return jtag_init_inner(cmd_ctx); +} + +int jtag_init(struct command_context_s *cmd_ctx) +{ + int retval; + if ((retval=jtag_interface_init(cmd_ctx)) != ERROR_OK) + return retval; + if (jtag_init_inner(cmd_ctx)==ERROR_OK) + { + return ERROR_OK; + } + return jtag_init_reset(cmd_ctx); +} static int default_khz(int khz, int *jtag_speed) { @@ -1506,6 +1711,12 @@ static int default_khz(int khz, int *jtag_speed) return ERROR_FAIL; } +static int default_speed_div(int speed, int *khz) +{ + LOG_ERROR("Translation from jtag_speed to khz not implemented"); + return ERROR_FAIL; +} + int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { int i; @@ -1536,6 +1747,10 @@ int handle_interface_command(struct command_context_s *cmd_ctx, char *cmd, char { jtag_interface->khz = default_khz; } + if (jtag_interface->speed_div == NULL) + { + jtag_interface->speed_div = default_speed_div; + } return ERROR_OK; } } @@ -1715,59 +1930,76 @@ int handle_jtag_ntrst_delay_command(struct command_context_s *cmd_ctx, char *cmd int handle_jtag_speed_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - int cur_speed = 0; - if ((argc<1) || (argc>2)) - return ERROR_COMMAND_SYNTAX_ERROR; - - if (argc >= 1) - cur_speed = jtag_speed = jtag_speed_post_reset = strtoul(args[0], NULL, 0); - if (argc == 2) - cur_speed = jtag_speed_post_reset = strtoul(args[1], NULL, 0); - - /* this command can be called during CONFIG, - * in which case jtag isn't initialized */ - if (jtag) - jtag->speed(cur_speed); + int retval=ERROR_OK; + + if (argc == 1) + { + LOG_DEBUG("handle jtag speed"); - return ERROR_OK; + int cur_speed = 0; + cur_speed = jtag_speed = strtoul(args[0], NULL, 0); + + /* this command can be called during CONFIG, + * in which case jtag isn't initialized */ + if (jtag) + { + retval=jtag->speed(cur_speed); + } + } else if (argc == 0) + { + } else + { + return ERROR_COMMAND_SYNTAX_ERROR; + } + command_print(cmd_ctx, "jtag_speed: %d", jtag_speed); + + return retval; } int handle_jtag_khz_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { - int cur_speed = 0; - int speed1, speed2; - if ((argc<1) || (argc>2)) + int retval=ERROR_OK; + LOG_DEBUG("handle jtag khz"); + + if(argc == 1) + { + speed_khz = strtoul(args[0], NULL, 0); + if (jtag != NULL) + { + int cur_speed = 0; + LOG_DEBUG("have interface set up"); + int speed_div1; + if ((retval=jtag->khz(speed_khz, &speed_div1))!=ERROR_OK) + { + speed_khz = 0; + return retval; + } + + cur_speed = jtag_speed = speed_div1; + + retval=jtag->speed(cur_speed); + } else + { + hasKHz = 1; + } + } else if (argc==0) + { + } else + { return ERROR_COMMAND_SYNTAX_ERROR; + } - if (jtag == NULL) + if (jtag!=NULL) { - LOG_ERROR("Interface not selected yet"); - return ERROR_COMMAND_SYNTAX_ERROR; + if ((retval=jtag->speed_div(jtag_speed, &speed_khz))!=ERROR_OK) + return retval; } - if (argc >= 1) - speed1 = strtoul(args[0], NULL, 0); - if (argc == 2) - speed2 = strtoul(args[1], NULL, 0); - - if (jtag->khz(speed1, &speed1)!=ERROR_OK) - return ERROR_OK; - - if (jtag->khz(speed2, &speed2)!=ERROR_OK) - return ERROR_OK; - - if (argc >= 1) - cur_speed = jtag_speed = jtag_speed_post_reset = speed1; - - if (argc == 2) - cur_speed = jtag_speed_post_reset = speed2; - - jtag->speed(cur_speed); + command_print(cmd_ctx, "jtag_khz: %d", speed_khz); + return retval; - return ERROR_OK; } - int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { enum tap_state state; @@ -1787,7 +2019,7 @@ int handle_endstate_command(struct command_context_s *cmd_ctx, char *cmd, char * } } } - command_print(cmd_ctx, "current endstate: %s", tap_state_strings[end_state]); + command_print(cmd_ctx, "current endstate: %s", tap_state_strings[cmd_queue_end_state]); return ERROR_OK; } @@ -1820,7 +2052,7 @@ int handle_jtag_reset_command(struct command_context_s *cmd_ctx, char *cmd, char return ERROR_COMMAND_SYNTAX_ERROR; } - if (!jtag && jtag_interface_init(cmd_ctx) != ERROR_OK) + if (jtag_interface_init(cmd_ctx) != ERROR_OK) return ERROR_JTAG_INIT_FAILED; jtag_add_reset(trst, srst); @@ -1843,7 +2075,6 @@ int handle_runtest_command(struct command_context_s *cmd_ctx, char *cmd, char ** } - int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { int i; @@ -1881,63 +2112,92 @@ int handle_irscan_command(struct command_context_s *cmd_ctx, char *cmd, char **a return ERROR_OK; } -int handle_drscan_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +int Jim_Command_drscan(Jim_Interp *interp, int argc, Jim_Obj *const *args) { + int retval; scan_field_t *fields; - int num_fields = 0; + int num_fields; int field_count = 0; - var_t *var; - int i, j; - - if ((argc < 2) || (argc % 2)) + int i, e; + long device; + + /* args[1] = device + * args[2] = num_bits + * args[3] = hex string + * ... repeat num bits and hex string ... + */ + if ((argc < 4) || ((argc % 2)!=0)) { - return ERROR_COMMAND_SYNTAX_ERROR; + Jim_WrongNumArgs(interp, 1, args, "wrong arguments"); + return JIM_ERR; } - for (i = 0; i < argc; i+=2) + for (i = 2; i < argc; i+=2) { - var = get_var_by_namenum(args[i+1]); - if (var) - { - num_fields += var->num_fields; - } - else - { - command_print(cmd_ctx, "variable %s doesn't exist", args[i+1]); - return ERROR_OK; - } + long bits; + + e = Jim_GetLong(interp, args[i], &bits); + if (e != JIM_OK) + return e; } - fields = malloc(sizeof(scan_field_t) * num_fields); + e = Jim_GetLong(interp, args[1], &device); + if (e != JIM_OK) + return e; - for (i = 0; i < argc; i+=2) + num_fields=(argc-2)/2; + fields = malloc(sizeof(scan_field_t) * num_fields); + for (i = 2; i < argc; i+=2) { - var = get_var_by_namenum(args[i+1]); - - for (j = 0; j < var->num_fields; j++) - { - fields[field_count].device = strtol(args[i], NULL, 0); - fields[field_count].num_bits = var->fields[j].num_bits; - fields[field_count].out_value = malloc(CEIL(var->fields[j].num_bits, 8)); - buf_set_u32(fields[field_count].out_value, 0, var->fields[j].num_bits, var->fields[j].value); - fields[field_count].out_mask = NULL; - fields[field_count].in_value = fields[field_count].out_value; - fields[field_count].in_check_mask = NULL; - fields[field_count].in_check_value = NULL; - fields[field_count].in_handler = field_le_to_host; - fields[field_count++].in_handler_priv = &(var->fields[j]); - } + long bits; + int len; + const char *str; + + Jim_GetLong(interp, args[i], &bits); + str = Jim_GetString(args[i+1], &len); + + fields[field_count].device = device; + fields[field_count].num_bits = bits; + fields[field_count].out_value = malloc(CEIL(bits, 8)); + str_to_buf(str, len, fields[field_count].out_value, bits, 0); + fields[field_count].out_mask = NULL; + fields[field_count].in_value = fields[field_count].out_value; + fields[field_count].in_check_mask = NULL; + fields[field_count].in_check_value = NULL; + fields[field_count].in_handler = NULL; + fields[field_count++].in_handler_priv = NULL; } jtag_add_dr_scan(num_fields, fields, -1); - jtag_execute_queue(); - - for (i = 0; i < argc / 2; i++) - free(fields[i].out_value); + retval = jtag_execute_queue(); + if (retval != ERROR_OK) + { + Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); + Jim_AppendStrings(interp, Jim_GetResult(interp), "drscan: jtag execute failed", NULL); + return JIM_ERR; + } + + field_count=0; + Jim_Obj *list = Jim_NewListObj(interp, NULL, 0); + for (i = 2; i < argc; i+=2) + { + long bits; + char *str; + + Jim_GetLong(interp, args[i], &bits); + str = buf_to_str(fields[field_count].in_value, bits, 16); + free(fields[field_count].out_value); + + Jim_ListAppendElement(interp, list, Jim_NewStringObj(interp, str, strlen(str))); + free(str); + field_count++; + } + Jim_SetResult(interp, list); + free(fields); - return ERROR_OK; + return JIM_OK; } int handle_verify_ircapture_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)