X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fjtag%2Fdrivers%2Fti_icdi_usb.c;h=f316c8256e596ba43f3f2bf7a7b38d4ca99b6d38;hp=c9b8435f2c9297e404be405a5f913d95676d3def;hb=HEAD;hpb=ff94e02b7cfe5df892824e60140dcdd07ed2b01c diff --git a/src/jtag/drivers/ti_icdi_usb.c b/src/jtag/drivers/ti_icdi_usb.c index c9b8435f2c..4260e2d39d 100644 --- a/src/jtag/drivers/ti_icdi_usb.c +++ b/src/jtag/drivers/ti_icdi_usb.c @@ -1,22 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + /*************************************************************************** * * * Copyright (C) 2012 by Spencer Oliver * * spen@spen-soft.co.uk * - * * - * 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 * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -25,6 +12,7 @@ /* project specific includes */ #include +#include #include #include #include @@ -33,21 +21,20 @@ #include -#include +#include "libusb_helper.h" #define ICDI_WRITE_ENDPOINT 0x02 #define ICDI_READ_ENDPOINT 0x83 -#define ICDI_WRITE_TIMEOUT 1000 -#define ICDI_READ_TIMEOUT 1000 +#define ICDI_WRITE_TIMEOUT (LIBUSB_TIMEOUT_MS) +#define ICDI_READ_TIMEOUT (LIBUSB_TIMEOUT_MS) #define ICDI_PACKET_SIZE 2048 #define PACKET_START "$" #define PACKET_END "#" struct icdi_usb_handle_s { - libusb_context *usb_ctx; - libusb_device_handle *usb_dev; + struct libusb_device_handle *usb_dev; char *read_buffer; char *write_buffer; @@ -121,12 +108,11 @@ static int remote_unescape_input(const char *buffer, int len, char *out_buf, int static int icdi_send_packet(void *handle, int len) { unsigned char cksum = 0; - struct icdi_usb_handle_s *h; + struct icdi_usb_handle_s *h = handle; int result, retry = 0; int transferred = 0; - assert(handle != NULL); - h = (struct icdi_usb_handle_s *)handle; + assert(handle); /* check we have a large enough buffer for checksum "#00" */ if (len + 3 > h->max_packet) { @@ -234,8 +220,7 @@ static int icdi_send_packet(void *handle, int len) static int icdi_send_cmd(void *handle, const char *cmd) { - struct icdi_usb_handle_s *h; - h = (struct icdi_usb_handle_s *)handle; + struct icdi_usb_handle_s *h = handle; int cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "%s", cmd); return icdi_send_packet(handle, cmd_len); @@ -243,23 +228,22 @@ static int icdi_send_cmd(void *handle, const char *cmd) static int icdi_send_remote_cmd(void *handle, const char *data) { - struct icdi_usb_handle_s *h; - h = (struct icdi_usb_handle_s *)handle; + struct icdi_usb_handle_s *h = handle; size_t cmd_len = sprintf(h->write_buffer, PACKET_START "qRcmd,"); - cmd_len += hexify(h->write_buffer + cmd_len, data, 0, h->max_packet - cmd_len); + cmd_len += hexify(h->write_buffer + cmd_len, (const uint8_t *)data, + strlen(data), h->max_packet - cmd_len); return icdi_send_packet(handle, cmd_len); } static int icdi_get_cmd_result(void *handle) { - struct icdi_usb_handle_s *h; + struct icdi_usb_handle_s *h = handle; int offset = 0; char ch; - assert(handle != NULL); - h = (struct icdi_usb_handle_s *)handle; + assert(handle); do { ch = h->read_buffer[offset++]; @@ -272,7 +256,7 @@ static int icdi_get_cmd_result(void *handle) if (h->read_buffer[offset] == 'E') { /* get error code */ - char result; + uint8_t result; if (unhexify(&result, h->read_buffer + offset + 1, 1) != 1) return ERROR_FAIL; return result; @@ -290,21 +274,27 @@ static int icdi_usb_idcode(void *handle, uint32_t *idcode) static int icdi_usb_write_debug_reg(void *handle, uint32_t addr, uint32_t val) { - return icdi_usb_write_mem(handle, addr, 4, 1, (uint8_t *)&val); + uint8_t buf[4]; + /* REVISIT: There's no target pointer here so there's no way to use target_buffer_set_u32(). + * I guess all supported chips are little-endian anyway. */ + h_u32_to_le(buf, val); + return icdi_usb_write_mem(handle, addr, 4, 1, buf); } static enum target_state icdi_usb_state(void *handle) { int result; - struct icdi_usb_handle_s *h; + struct icdi_usb_handle_s *h = handle; uint32_t dhcsr; + uint8_t buf[4]; - h = (struct icdi_usb_handle_s *)handle; - - result = icdi_usb_read_mem(h, DCB_DHCSR, 4, 1, (uint8_t *)&dhcsr); + result = icdi_usb_read_mem(h, DCB_DHCSR, 4, 1, buf); if (result != ERROR_OK) return TARGET_UNKNOWN; + /* REVISIT: There's no target pointer here so there's no way to use target_buffer_get_u32(). + * I guess all supported chips are little-endian anyway. */ + dhcsr = le_to_h_u32(buf); if (dhcsr & S_HALT) return TARGET_HALTED; @@ -313,8 +303,7 @@ static enum target_state icdi_usb_state(void *handle) static int icdi_usb_version(void *handle) { - struct icdi_usb_handle_s *h; - h = (struct icdi_usb_handle_s *)handle; + struct icdi_usb_handle_s *h = handle; char version[20]; @@ -329,7 +318,7 @@ static int icdi_usb_version(void *handle) } /* convert reply */ - if (unhexify(version, h->read_buffer + 2, 4) != 4) { + if (unhexify((uint8_t *)version, h->read_buffer + 2, 4) != 4) { LOG_WARNING("unable to get ICDI version"); return ERROR_OK; } @@ -346,8 +335,7 @@ static int icdi_usb_query(void *handle) { int result; - struct icdi_usb_handle_s *h; - h = (struct icdi_usb_handle_s *)handle; + struct icdi_usb_handle_s *h = handle; result = icdi_send_cmd(handle, "qSupported"); if (result != ERROR_OK) @@ -368,12 +356,12 @@ static int icdi_usb_query(void *handle) char *separator; int max_packet; - max_packet = strtoul(offset + 11, &separator, 16); + max_packet = strtol(offset + 11, &separator, 16); if (!max_packet) LOG_ERROR("invalid max packet, using defaults"); else h->max_packet = max_packet; - LOG_DEBUG("max packet supported : %" PRIu32 " bytes", h->max_packet); + LOG_DEBUG("max packet supported : %i bytes", h->max_packet); } @@ -381,7 +369,7 @@ static int icdi_usb_query(void *handle) if (h->max_packet != ICDI_PACKET_SIZE) { h->read_buffer = realloc(h->read_buffer, h->max_packet); h->write_buffer = realloc(h->write_buffer, h->max_packet); - if (h->read_buffer == 0 || h->write_buffer == 0) { + if (!h->read_buffer || !h->write_buffer) { LOG_ERROR("unable to reallocate memory"); return ERROR_FAIL; } @@ -477,15 +465,13 @@ static int icdi_usb_read_regs(void *handle) return ERROR_OK; } -static int icdi_usb_read_reg(void *handle, int num, uint32_t *val) +static int icdi_usb_read_reg(void *handle, unsigned int regsel, uint32_t *val) { int result; - struct icdi_usb_handle_s *h; + struct icdi_usb_handle_s *h = handle; char cmd[10]; - h = (struct icdi_usb_handle_s *)handle; - - snprintf(cmd, sizeof(cmd), "p%x", num); + snprintf(cmd, sizeof(cmd), "p%x", regsel); result = icdi_send_cmd(handle, cmd); if (result != ERROR_OK) return result; @@ -498,21 +484,25 @@ static int icdi_usb_read_reg(void *handle, int num, uint32_t *val) } /* convert result */ - if (unhexify((char *)val, h->read_buffer + 2, 4) != 4) { + uint8_t buf[4]; + if (unhexify(buf, h->read_buffer + 2, 4) != 4) { LOG_ERROR("failed to convert result"); return ERROR_FAIL; } + *val = le_to_h_u32(buf); return result; } -static int icdi_usb_write_reg(void *handle, int num, uint32_t val) +static int icdi_usb_write_reg(void *handle, unsigned int regsel, uint32_t val) { int result; char cmd[20]; + uint8_t buf[4]; + h_u32_to_le(buf, val); - int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", num); - hexify(cmd + cmd_len, (char *)&val, 4, sizeof(cmd)); + int cmd_len = snprintf(cmd, sizeof(cmd), "P%x=", regsel); + hexify(cmd + cmd_len, buf, 4, sizeof(cmd)); result = icdi_send_cmd(handle, cmd); if (result != ERROR_OK) @@ -531,12 +521,10 @@ static int icdi_usb_write_reg(void *handle, int num, uint32_t val) static int icdi_usb_read_mem_int(void *handle, uint32_t addr, uint32_t len, uint8_t *buffer) { int result; - struct icdi_usb_handle_s *h; + struct icdi_usb_handle_s *h = handle; char cmd[20]; - h = (struct icdi_usb_handle_s *)handle; - - snprintf(cmd, sizeof(cmd), "x%x,%x", addr, len); + snprintf(cmd, sizeof(cmd), "x%" PRIx32 ",%" PRIx32, addr, len); result = icdi_send_cmd(handle, cmd); if (result != ERROR_OK) return result; @@ -551,7 +539,7 @@ static int icdi_usb_read_mem_int(void *handle, uint32_t addr, uint32_t len, uint /* unescape input */ int read_len = remote_unescape_input(h->read_buffer + 5, h->read_count - 8, (char *)buffer, len); if (read_len != (int)len) { - LOG_ERROR("read more bytes than expected: actual 0x%" PRIx32 " expected 0x%" PRIx32, read_len, len); + LOG_ERROR("read more bytes than expected: actual 0x%x expected 0x%" PRIx32, read_len, len); return ERROR_FAIL; } @@ -561,19 +549,17 @@ static int icdi_usb_read_mem_int(void *handle, uint32_t addr, uint32_t len, uint static int icdi_usb_write_mem_int(void *handle, uint32_t addr, uint32_t len, const uint8_t *buffer) { int result; - struct icdi_usb_handle_s *h; + struct icdi_usb_handle_s *h = handle; - h = (struct icdi_usb_handle_s *)handle; - - size_t cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "X%x,%x:", addr, len); + size_t cmd_len = snprintf(h->write_buffer, h->max_packet, PACKET_START "X%" PRIx32 ",%" PRIx32 ":", addr, len); int out_len; - cmd_len += remote_escape_output((char *)buffer, len, h->write_buffer + cmd_len, + cmd_len += remote_escape_output((const char *)buffer, len, h->write_buffer + cmd_len, &out_len, h->max_packet - cmd_len); if (out_len < (int)len) { /* for now issue a error as we have no way of allocating a larger buffer */ - LOG_ERROR("memory buffer too small: requires 0x%" PRIx32 " actual 0x%" PRIx32, out_len, len); + LOG_ERROR("memory buffer too small: requires 0x%x actual 0x%" PRIx32, out_len, len); return ERROR_FAIL; } @@ -595,7 +581,7 @@ static int icdi_usb_read_mem(void *handle, uint32_t addr, uint32_t size, uint32_t count, uint8_t *buffer) { int retval = ERROR_OK; - struct icdi_usb_handle_s *h = (struct icdi_usb_handle_s *)handle; + struct icdi_usb_handle_s *h = handle; uint32_t bytes_remaining; /* calculate byte count */ @@ -623,7 +609,7 @@ static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size, uint32_t count, const uint8_t *buffer) { int retval = ERROR_OK; - struct icdi_usb_handle_s *h = (struct icdi_usb_handle_s *)handle; + struct icdi_usb_handle_s *h = handle; uint32_t bytes_remaining; /* calculate byte count */ @@ -647,31 +633,30 @@ static int icdi_usb_write_mem(void *handle, uint32_t addr, uint32_t size, return retval; } +static int icdi_usb_override_target(const char *targetname) +{ + return !strcmp(targetname, "cortex_m"); +} + static int icdi_usb_close(void *handle) { - struct icdi_usb_handle_s *h; + struct icdi_usb_handle_s *h = handle; - h = (struct icdi_usb_handle_s *)handle; + if (!h) + return ERROR_OK; if (h->usb_dev) - libusb_close(h->usb_dev); - - if (h->usb_ctx) - libusb_exit(h->usb_ctx); - - if (h->read_buffer) - free(h->read_buffer); - - if (h->write_buffer) - free(h->write_buffer); + jtag_libusb_close(h->usb_dev); + free(h->read_buffer); + free(h->write_buffer); free(handle); - return ERROR_OK; } static int icdi_usb_open(struct hl_interface_param_s *param, void **fd) { + /* TODO: Convert remaining libusb_ calls to jtag_libusb_ */ int retval; struct icdi_usb_handle_s *h; @@ -679,20 +664,19 @@ static int icdi_usb_open(struct hl_interface_param_s *param, void **fd) h = calloc(1, sizeof(struct icdi_usb_handle_s)); - if (h == 0) { + if (!h) { LOG_ERROR("unable to allocate memory"); return ERROR_FAIL; } - LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param->transport, - param->vid, param->pid); + for (uint8_t i = 0; param->vid[i] && param->pid[i]; ++i) + LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", param->transport, + param->vid[i], param->pid[i], adapter_get_required_serial() ? adapter_get_required_serial() : ""); - if (libusb_init(&h->usb_ctx) != 0) { - LOG_ERROR("libusb init failed"); - goto error_open; - } + /* TI (Stellaris) ICDI provides its serial number in the USB descriptor; + no need to provide a callback here. */ + jtag_libusb_open(param->vid, param->pid, NULL, &h->usb_dev, NULL); - h->usb_dev = libusb_open_device_with_vid_pid(h->usb_ctx, param->vid, param->pid); if (!h->usb_dev) { LOG_ERROR("open failed"); goto error_open; @@ -728,7 +712,7 @@ static int icdi_usb_open(struct hl_interface_param_s *param, void **fd) h->write_buffer = malloc(ICDI_PACKET_SIZE); h->max_packet = ICDI_PACKET_SIZE; - if (h->read_buffer == 0 || h->write_buffer == 0) { + if (!h->read_buffer || !h->write_buffer) { LOG_DEBUG("malloc failed"); goto error_open; } @@ -774,5 +758,7 @@ struct hl_layout_api_s icdi_usb_layout_api = { .write_reg = icdi_usb_write_reg, .read_mem = icdi_usb_read_mem, .write_mem = icdi_usb_write_mem, - .write_debug_reg = icdi_usb_write_debug_reg + .write_debug_reg = icdi_usb_write_debug_reg, + .override_target = icdi_usb_override_target, + .custom_command = icdi_send_remote_cmd, };