+// 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
/* project specific includes */
#include <helper/binarybuffer.h>
+#include <jtag/adapter.h>
#include <jtag/interface.h>
#include <jtag/hla/hla_layout.h>
#include <jtag/hla/hla_transport.h>
#include <target/cortex_m.h>
-#include <libusb.h>
+#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;
int result, retry = 0;
int transferred = 0;
- assert(handle != NULL);
+ assert(handle);
/* check we have a large enough buffer for checksum "#00" */
if (len + 3 > h->max_packet) {
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);
}
int offset = 0;
char ch;
- assert(handle != NULL);
+ assert(handle);
do {
ch = h->read_buffer[offset++];
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;
}
/* 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;
}
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;
}
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 = handle;
char cmd[10];
- 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;
/* convert result */
uint8_t buf[4];
- if (unhexify((char *)buf, h->read_buffer + 2, 4) != 4) {
+ if (unhexify(buf, h->read_buffer + 2, 4) != 4) {
LOG_ERROR("failed to convert result");
return ERROR_FAIL;
}
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, (const char *)buf, 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)
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 = handle;
- 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)
+ return ERROR_OK;
- if (h->write_buffer)
- free(h->write_buffer);
+ if (h->usb_dev)
+ 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;
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;
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;
}
.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,
};