X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fjlink.c;h=1c7a39887f0b2487aac0f738c3b755a1b4472a34;hb=5b4679618a0f1b14f6ee47fc30cf27f77375f2d4;hp=bfd3a7803a6f40cd42ca1e9e3e3f0dc4ba15bda9;hpb=e77ae9096a40707d3b878b46969a60a06656dc06;p=openocd.git diff --git a/src/jtag/jlink.c b/src/jtag/jlink.c index bfd3a7803a..1c7a39887f 100644 --- a/src/jtag/jlink.c +++ b/src/jtag/jlink.c @@ -34,18 +34,6 @@ #include "log.h" -/* enable this to debug communication - */ -#if 0 -#define _DEBUG_USB_COMMS_ -#endif - -#ifdef _DEBUG_JTAG_IO_ -#define DEBUG_JTAG_IO(expr ...) LOG_DEBUG(expr) -#else -#define DEBUG_JTAG_IO(expr ...) -#endif - #define VID 0x1366 #define PID 0x0101 @@ -77,32 +65,33 @@ static u8 usb_emu_result_buffer[JLINK_EMU_RESULT_BUFFER_SIZE]; #define JLINK_MAX_SPEED 12000 /* External interface functions */ -int jlink_execute_queue(void); -int jlink_speed(int speed); -int jlink_khz(int khz, int *jtag_speed); -int jlink_register_commands(struct command_context_s *cmd_ctx); -int jlink_init(void); -int jlink_quit(void); +static int jlink_execute_queue(void); +static int jlink_speed(int speed); +static int jlink_speed_div(int speed, int* khz); +static int jlink_khz(int khz, int *jtag_speed); +static int jlink_register_commands(struct command_context_s *cmd_ctx); +static int jlink_init(void); +static int jlink_quit(void); /* CLI command handler functions */ -int jlink_handle_jlink_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); +static int jlink_handle_jlink_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); /* Queue command functions */ -void jlink_end_state(tap_state_t state); -void jlink_state_move(void); -void jlink_path_move(int num_states, tap_state_t *path); -void jlink_runtest(int num_cycles); -void jlink_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size, scan_command_t *command); -void jlink_reset(int trst, int srst); -void jlink_simple_command(u8 command); -int jlink_get_status(void); +static void jlink_end_state(tap_state_t state); +static void jlink_state_move(void); +static void jlink_path_move(int num_states, tap_state_t *path); +static void jlink_runtest(int num_cycles); +static void jlink_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size, scan_command_t *command); +static void jlink_reset(int trst, int srst); +static void jlink_simple_command(u8 command); +static int jlink_get_status(void); /* J-Link tap buffer functions */ -void jlink_tap_init(void); -int jlink_tap_execute(void); -void jlink_tap_ensure_space(int scans, int bits); -void jlink_tap_append_step(int tms, int tdi); -void jlink_tap_append_scan(int length, u8 *buffer, scan_command_t *command); +static void jlink_tap_init(void); +static int jlink_tap_execute(void); +static void jlink_tap_ensure_space(int scans, int bits); +static void jlink_tap_append_step(int tms, int tdi); +static void jlink_tap_append_scan(int length, u8 *buffer, scan_command_t *command); /* Jlink lowlevel functions */ typedef struct jlink_jtag @@ -110,21 +99,21 @@ typedef struct jlink_jtag struct usb_dev_handle* usb_handle; } jlink_jtag_t; -jlink_jtag_t *jlink_usb_open(void); -void jlink_usb_close(jlink_jtag_t *jlink_jtag); -int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length); -int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length); -int jlink_usb_read(jlink_jtag_t *jlink_jtag); -int jlink_usb_read_emu_result(jlink_jtag_t *jlink_jtag); +static jlink_jtag_t *jlink_usb_open(void); +static void jlink_usb_close(jlink_jtag_t *jlink_jtag); +static int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length); +static int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length); +static int jlink_usb_read(jlink_jtag_t *jlink_jtag, int expected_size); +static int jlink_usb_read_emu_result(jlink_jtag_t *jlink_jtag); /* helper functions */ -int jlink_get_version_info(void); +static int jlink_get_version_info(void); #ifdef _DEBUG_USB_COMMS_ -void jlink_debug_buffer(u8 *buffer, int length); +static void jlink_debug_buffer(u8 *buffer, int length); #endif -jlink_jtag_t* jlink_jtag_handle; +static jlink_jtag_t* jlink_jtag_handle; /***************************************************************************/ /* External interface implementation */ @@ -134,13 +123,14 @@ jtag_interface_t jlink_interface = .name = "jlink", .execute_queue = jlink_execute_queue, .speed = jlink_speed, + .speed_div = jlink_speed_div, .khz = jlink_khz, .register_commands = jlink_register_commands, .init = jlink_init, .quit = jlink_quit }; -int jlink_execute_queue(void) +static int jlink_execute_queue(void) { jtag_command_t *cmd = jtag_command_queue; int scan_size; @@ -154,7 +144,7 @@ int jlink_execute_queue(void) case JTAG_END_STATE: DEBUG_JTAG_IO("end_state: %i", cmd->cmd.end_state->end_state); - if (cmd->cmd.end_state->end_state != -1) + if (cmd->cmd.end_state->end_state != TAP_INVALID) { jlink_end_state(cmd->cmd.end_state->end_state); } @@ -164,7 +154,7 @@ int jlink_execute_queue(void) DEBUG_JTAG_IO( "runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, \ cmd->cmd.runtest->end_state); - if (cmd->cmd.runtest->end_state != -1) + if (cmd->cmd.runtest->end_state != TAP_INVALID) { jlink_end_state(cmd->cmd.runtest->end_state); } @@ -174,7 +164,7 @@ int jlink_execute_queue(void) case JTAG_STATEMOVE: DEBUG_JTAG_IO("statemove end in %i", cmd->cmd.statemove->end_state); - if (cmd->cmd.statemove->end_state != -1) + if (cmd->cmd.statemove->end_state != TAP_INVALID) { jlink_end_state(cmd->cmd.statemove->end_state); } @@ -192,7 +182,7 @@ int jlink_execute_queue(void) case JTAG_SCAN: DEBUG_JTAG_IO("scan end in %i", cmd->cmd.scan->end_state); - if (cmd->cmd.scan->end_state != -1) + if (cmd->cmd.scan->end_state != TAP_INVALID) { jlink_end_state(cmd->cmd.scan->end_state); } @@ -236,7 +226,7 @@ int jlink_execute_queue(void) } /* Sets speed in kHz. */ -int jlink_speed(int speed) +static int jlink_speed(int speed) { int result; @@ -270,21 +260,28 @@ int jlink_speed(int speed) return ERROR_OK; } -int jlink_khz(int khz, int *jtag_speed) +static int jlink_speed_div(int speed, int* khz) +{ + *khz = speed; + + return ERROR_OK; +} + +static int jlink_khz(int khz, int *jtag_speed) { *jtag_speed = khz; return ERROR_OK; } -int jlink_register_commands(struct command_context_s *cmd_ctx) +static int jlink_register_commands(struct command_context_s *cmd_ctx) { register_command(cmd_ctx, NULL, "jlink_info", jlink_handle_jlink_info_command, COMMAND_EXEC, "query jlink info"); return ERROR_OK; } -int jlink_init(void) +static int jlink_init(void) { int check_cnt; @@ -322,7 +319,7 @@ int jlink_init(void) return ERROR_OK; } -int jlink_quit(void) +static int jlink_quit(void) { jlink_usb_close(jlink_jtag_handle); return ERROR_OK; @@ -331,7 +328,7 @@ int jlink_quit(void) /***************************************************************************/ /* Queue command implementations */ -void jlink_end_state(tap_state_t state) +static void jlink_end_state(tap_state_t state) { if (tap_is_state_stable(state)) { @@ -345,7 +342,7 @@ void jlink_end_state(tap_state_t state) } /* Goes to the end state. */ -void jlink_state_move(void) +static void jlink_state_move(void) { int i; int tms = 0; @@ -360,7 +357,7 @@ void jlink_state_move(void) tap_set_state(tap_get_end_state()); } -void jlink_path_move(int num_states, tap_state_t *path) +static void jlink_path_move(int num_states, tap_state_t *path) { int i; @@ -386,7 +383,7 @@ void jlink_path_move(int num_states, tap_state_t *path) tap_set_end_state(tap_get_state()); } -void jlink_runtest(int num_cycles) +static void jlink_runtest(int num_cycles) { int i; @@ -413,7 +410,7 @@ void jlink_runtest(int num_cycles) } } -void jlink_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size, scan_command_t *command) +static void jlink_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size, scan_command_t *command) { tap_state_t saved_end_state; @@ -424,7 +421,10 @@ void jlink_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size, sca /* Move to appropriate scan state */ jlink_end_state(ir_scan ? TAP_IRSHIFT : TAP_DRSHIFT); - jlink_state_move(); + /* Only move if we're not already there */ + if (tap_get_state() != tap_get_end_state()) + jlink_state_move(); + jlink_end_state(saved_end_state); /* Scan */ @@ -441,7 +441,7 @@ void jlink_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size, sca } } -void jlink_reset(int trst, int srst) +static void jlink_reset(int trst, int srst) { LOG_DEBUG("trst: %i, srst: %i", trst, srst); @@ -465,7 +465,7 @@ void jlink_reset(int trst, int srst) } } -void jlink_simple_command(u8 command) +static void jlink_simple_command(u8 command) { int result; @@ -480,12 +480,12 @@ void jlink_simple_command(u8 command) } } -int jlink_get_status(void) +static int jlink_get_status(void) { int result; jlink_simple_command(EMU_CMD_GET_STATE); - result = jlink_usb_read(jlink_jtag_handle); + result = jlink_usb_read(jlink_jtag_handle, 8); if (result == 8) { @@ -508,24 +508,24 @@ int jlink_get_status(void) return ERROR_OK; } -int jlink_get_version_info(void) +static int jlink_get_version_info(void) { int result; int len = 0; /* query hardware version */ jlink_simple_command(EMU_CMD_VERSION); - result = jlink_usb_read(jlink_jtag_handle); + result = jlink_usb_read(jlink_jtag_handle, 2); if (result == 2) { len = buf_get_u32(usb_in_buffer, 0, 16); - result = jlink_usb_read(jlink_jtag_handle); + result = jlink_usb_read(jlink_jtag_handle, len); if (result == len) { usb_in_buffer[result] = 0; - LOG_INFO(usb_in_buffer); + LOG_INFO("%s", (char *)usb_in_buffer); return ERROR_OK; } } @@ -534,7 +534,7 @@ int jlink_get_version_info(void) return ERROR_JTAG_DEVICE_ERROR; } -int jlink_handle_jlink_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +static int jlink_handle_jlink_info_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) { if (jlink_get_version_info() == ERROR_OK) { @@ -571,13 +571,13 @@ static pending_scan_result_t pending_scan_results_buffer[MAX_PENDING_SCAN_RESULT static int last_tms; -void jlink_tap_init(void) +static void jlink_tap_init(void) { tap_length = 0; pending_scan_results_length = 0; } -void jlink_tap_ensure_space(int scans, int bits) +static void jlink_tap_ensure_space(int scans, int bits) { int available_scans = MAX_PENDING_SCAN_RESULTS - pending_scan_results_length; int available_bits = JLINK_TAP_BUFFER_SIZE * 8 - tap_length; @@ -588,7 +588,7 @@ void jlink_tap_ensure_space(int scans, int bits) } } -void jlink_tap_append_step(int tms, int tdi) +static void jlink_tap_append_step(int tms, int tdi) { last_tms = tms; int index = tap_length / 8; @@ -624,7 +624,7 @@ void jlink_tap_append_step(int tms, int tdi) } } -void jlink_tap_append_scan(int length, u8 *buffer, scan_command_t *command) +static void jlink_tap_append_scan(int length, u8 *buffer, scan_command_t *command) { pending_scan_result_t *pending_scan_result = &pending_scan_results_buffer[pending_scan_results_length]; int i; @@ -643,7 +643,7 @@ void jlink_tap_append_scan(int length, u8 *buffer, scan_command_t *command) /* Pad and send a tap sequence to the device, and receive the answer. * For the purpose of padding we assume that we are in idle or pause state. */ -int jlink_tap_execute(void) +static int jlink_tap_execute(void) { int byte_length; int tms_offset; @@ -733,7 +733,7 @@ int jlink_tap_execute(void) /*****************************************************************************/ /* JLink USB low-level functions */ -jlink_jtag_t* jlink_usb_open() +static jlink_jtag_t* jlink_usb_open() { struct usb_bus *busses; struct usb_bus *bus; @@ -779,14 +779,14 @@ jlink_jtag_t* jlink_usb_open() return NULL; } -void jlink_usb_close(jlink_jtag_t *jlink_jtag) +static void jlink_usb_close(jlink_jtag_t *jlink_jtag) { usb_close(jlink_jtag->usb_handle); free(jlink_jtag); } /* Send a message and receive the reply. */ -int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length) +static int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length) { int result; int result2; @@ -794,7 +794,7 @@ int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length) result = jlink_usb_write(jlink_jtag, out_length); if (result == out_length) { - result = jlink_usb_read(jlink_jtag); + result = jlink_usb_read(jlink_jtag, in_length); if (result == in_length || result == in_length+1) { if (result == in_length) @@ -847,8 +847,43 @@ int jlink_usb_message(jlink_jtag_t *jlink_jtag, int out_length, int in_length) } } +/* calls the given usb_bulk_* function, allowing for the data to trickle in with some timeouts */ +static int usb_bulk_with_retries( + int (*f)(usb_dev_handle *, int, char *, int, int), + usb_dev_handle *dev, int ep, + char *bytes, int size, int timeout) +{ + int rc = 0, tries = 3, this_size; + + while (tries && size) { + + this_size = f(dev, ep, bytes, size, timeout); + if (this_size > 0) { + + size -= this_size; + rc += this_size; + bytes += this_size; + + } else + tries --; + } + return rc; +} +static inline int usb_bulk_write_ex(usb_dev_handle *dev, int ep, + char *bytes, int size, int timeout) +{ + return usb_bulk_with_retries(&usb_bulk_write, + dev, ep, bytes, size, timeout); +} +static inline int usb_bulk_read_ex(usb_dev_handle *dev, int ep, + char *bytes, int size, int timeout) +{ + return usb_bulk_with_retries(&usb_bulk_read, + dev, ep, bytes, size, timeout); +} + /* Write data from out_buffer to USB. */ -int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length) +static int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length) { int result; @@ -858,8 +893,8 @@ int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length) return -1; } - result = usb_bulk_write(jlink_jtag->usb_handle, JLINK_WRITE_ENDPOINT, \ - usb_out_buffer, out_length, JLINK_USB_TIMEOUT); + result = usb_bulk_write_ex(jlink_jtag->usb_handle, JLINK_WRITE_ENDPOINT, + (char *)usb_out_buffer, out_length, JLINK_USB_TIMEOUT); DEBUG_JTAG_IO("jlink_usb_write, out_length = %d, result = %d", out_length, result); @@ -870,10 +905,10 @@ int jlink_usb_write(jlink_jtag_t *jlink_jtag, int out_length) } /* Read data from USB into in_buffer. */ -int jlink_usb_read(jlink_jtag_t *jlink_jtag) +static int jlink_usb_read(jlink_jtag_t *jlink_jtag, int expected_size) { - int result = usb_bulk_read(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT, \ - usb_in_buffer, JLINK_IN_BUFFER_SIZE, JLINK_USB_TIMEOUT); + int result = usb_bulk_read_ex(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT, + (char *)usb_in_buffer, expected_size, JLINK_USB_TIMEOUT); DEBUG_JTAG_IO("jlink_usb_read, result = %d", result); @@ -884,10 +919,11 @@ int jlink_usb_read(jlink_jtag_t *jlink_jtag) } /* Read the result from the previous EMU cmd into result_buffer. */ -int jlink_usb_read_emu_result(jlink_jtag_t *jlink_jtag) +static int jlink_usb_read_emu_result(jlink_jtag_t *jlink_jtag) { - int result = usb_bulk_read(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT, \ - usb_emu_result_buffer, JLINK_EMU_RESULT_BUFFER_SIZE, JLINK_USB_TIMEOUT); + int result = usb_bulk_read_ex(jlink_jtag->usb_handle, JLINK_READ_ENDPOINT, + (char *)usb_emu_result_buffer, 1 /* JLINK_EMU_RESULT_BUFFER_SIZE */, + JLINK_USB_TIMEOUT); DEBUG_JTAG_IO("jlink_usb_read_result, result = %d", result); @@ -900,7 +936,7 @@ int jlink_usb_read_emu_result(jlink_jtag_t *jlink_jtag) #ifdef _DEBUG_USB_COMMS_ #define BYTES_PER_LINE 16 -void jlink_debug_buffer(u8 *buffer, int length) +static void jlink_debug_buffer(u8 *buffer, int length) { char line[81]; char s[4]; @@ -915,7 +951,7 @@ void jlink_debug_buffer(u8 *buffer, int length) snprintf(s, 4, " %02x", buffer[j]); strcat(line, s); } - LOG_DEBUG(line); + LOG_DEBUG("%s", line); } } #endif