+// SPDX-License-Identifier: GPL-2.0-or-later
+
/*******************************************************************************
* Driver for OpenJTAG Project (www.openjtag.org) *
- * Compatible with libftdi and ftd2xx drivers. *
+ * Compatible with libftdi drivers. *
* *
* Cypress CY7C65215 support *
* Copyright (C) 2015 Vianney le Clément de Saint-Marcq, Essensium NV *
* And jlink.c *
* Copyright (C) 2008 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, see <http://www.gnu.org/licenses/>. *
***************************************************************************/
/***************************************************************************
} openjtag_tap_state_t;
/* OPENJTAG access library includes */
-#include <ftdi.h>
+#include "libftdi_helper.h"
/* OpenJTAG vid/pid */
static uint16_t openjtag_vid = 0x0403;
ret = jtag_libusb_control_transfer(usbh, CY7C65215_JTAG_REQUEST,
CY7C65215_JTAG_WRITE, size, 0,
- NULL, 0, CY7C65215_USB_TIMEOUT);
- if (ret < 0) {
- LOG_ERROR("vendor command failed, error %d", ret);
- return ERROR_JTAG_DEVICE_ERROR;
+ NULL, 0, CY7C65215_USB_TIMEOUT, NULL);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("vendor command failed");
+ return ret;
}
if (jtag_libusb_bulk_write(usbh, ep_out, (char *)buf, size,
ret = jtag_libusb_control_transfer(usbh, CY7C65215_JTAG_REQUEST,
CY7C65215_JTAG_READ, qty, 0,
- NULL, 0, CY7C65215_USB_TIMEOUT);
- if (ret < 0) {
- LOG_ERROR("vendor command failed, error %d", ret);
- return ERROR_JTAG_DEVICE_ERROR;
+ NULL, 0, CY7C65215_USB_TIMEOUT, NULL);
+ if (ret != ERROR_OK) {
+ LOG_ERROR("vendor command failed");
+ return ret;
}
if (jtag_libusb_bulk_read(usbh, ep_in, (char *)buf, qty,
uint8_t latency_timer;
/* Open by device description */
- if (openjtag_device_desc == NULL) {
+ if (!openjtag_device_desc) {
LOG_WARNING("no openjtag device description specified, "
"using default 'Open JTAG Project'");
openjtag_device_desc = "Open JTAG Project";
return ERROR_JTAG_DEVICE_ERROR;
}
- if (ftdi_usb_purge_buffers(&ftdic) < 0) {
- LOG_ERROR("ftdi_purge_buffers: %s", ftdic.error_str);
+ if (ftdi_tcioflush(&ftdic) < 0) {
+ LOG_ERROR("ftdi flush: %s", ftdic.error_str);
return ERROR_JTAG_INIT_FAILED;
}
ret = jtag_libusb_control_transfer(usbh,
CY7C65215_JTAG_REQUEST,
CY7C65215_JTAG_ENABLE,
- 0, 0, NULL, 0, CY7C65215_USB_TIMEOUT);
- if (ret < 0) {
+ 0, 0, NULL, 0, CY7C65215_USB_TIMEOUT, NULL);
+ if (ret != ERROR_OK) {
LOG_ERROR("could not enable JTAG module");
goto err;
}
return ERROR_OK;
err:
- if (usbh != NULL)
+ if (usbh)
jtag_libusb_close(usbh);
- return ERROR_JTAG_INIT_FAILED;
+ return ret;
}
static int openjtag_init(void)
ret = jtag_libusb_control_transfer(usbh,
CY7C65215_JTAG_REQUEST,
CY7C65215_JTAG_DISABLE,
- 0, 0, NULL, 0, CY7C65215_USB_TIMEOUT);
- if (ret < 0)
+ 0, 0, NULL, 0, CY7C65215_USB_TIMEOUT, NULL);
+ if (ret != ERROR_OK)
LOG_WARNING("could not disable JTAG module");
jtag_libusb_close(usbh);
static void openjtag_write_tap_buffer(void)
{
uint32_t written;
+ uint32_t rx_expected = 0;
+
+ /* calculate expected number of return bytes */
+ for (int tx_offs = 0; tx_offs < usb_tx_buf_offs; tx_offs++) {
+ if ((usb_tx_buf[tx_offs] & 0x0F) == 6) {
+ rx_expected++;
+ tx_offs++;
+ } else if ((usb_tx_buf[tx_offs] & 0x0F) == 2) {
+ rx_expected++;
+ }
+ }
openjtag_buf_write(usb_tx_buf, usb_tx_buf_offs, &written);
- openjtag_buf_read(usb_rx_buf, usb_tx_buf_offs, &usb_rx_buf_len);
+ openjtag_buf_read(usb_rx_buf, rx_expected, &usb_rx_buf_len);
usb_tx_buf_offs = 0;
}
#endif
jtag_read_buffer(buffer, openjtag_scan_result_buffer[res_count].command);
- if (openjtag_scan_result_buffer[res_count].buffer)
- free(openjtag_scan_result_buffer[res_count].buffer);
+ free(openjtag_scan_result_buffer[res_count].buffer);
res_count++;
}
uint8_t buf = 0x00;
- if (cmd->cmd.reset->trst) {
- buf = 0x03;
- } else {
+ /* Pull SRST low for 5 TCLK cycles */
+ if (cmd->cmd.reset->srst) {
buf |= 0x04;
buf |= 0x05 << 4;
+ openjtag_add_byte(buf);
}
-
- openjtag_add_byte(buf);
}
static void openjtag_execute_sleep(struct jtag_command *cmd)
uint8_t state = openjtag_get_tap_state(openocd_state);
uint8_t buf = 0;
- buf = 0x01;
- buf |= state << 4;
+
+ if (state != OPENJTAG_TAP_RESET) {
+ buf = 0x01;
+ buf |= state << 4;
+ } else {
+ /* Force software TLR */
+ buf = 0x03;
+ }
openjtag_add_byte(buf);
}
tap_set_state(TAP_IDLE);
}
- if (cmd->cmd.runtest->num_cycles > 16)
- LOG_WARNING("num_cycles > 16 on run test");
-
if (openjtag_variant != OPENJTAG_VARIANT_CY7C65215 ||
cmd->cmd.runtest->num_cycles) {
uint8_t command;
- command = 7;
- command |= ((cmd->cmd.runtest->num_cycles - 1) & 0x0F) << 4;
+ int cycles = cmd->cmd.runtest->num_cycles;
- openjtag_add_byte(command);
+ do {
+ command = 7;
+ command |= (((cycles > 16 ? 16 : cycles) - 1) & 0x0F) << 4;
+
+ openjtag_add_byte(command);
+ cycles -= 16;
+ } while (cycles > 0);
}
tap_set_end_state(end_state);
}
}
-static int openjtag_execute_queue(void)
+static int openjtag_execute_queue(struct jtag_command *cmd_queue)
{
- struct jtag_command *cmd = jtag_command_queue;
+ struct jtag_command *cmd = cmd_queue;
- while (cmd != NULL) {
+ while (cmd) {
openjtag_execute_command(cmd);
cmd = cmd->next;
}
return ERROR_OK;
}
-static const struct command_registration openjtag_command_handlers[] = {
+COMMAND_HANDLER(openjtag_handle_vid_pid_command)
+{
+ if (CMD_ARGC != 2)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[0], openjtag_vid);
+ COMMAND_PARSE_NUMBER(u16, CMD_ARGV[1], openjtag_pid);
+
+ return ERROR_OK;
+}
+
+static const struct command_registration openjtag_subcommand_handlers[] = {
{
- .name = "openjtag_device_desc",
+ .name = "device_desc",
.handler = openjtag_handle_device_desc_command,
.mode = COMMAND_CONFIG,
.help = "set the USB device description of the OpenJTAG",
.usage = "description-string",
},
{
- .name = "openjtag_variant",
+ .name = "variant",
.handler = openjtag_handle_variant_command,
.mode = COMMAND_CONFIG,
.help = "set the OpenJTAG variant",
.usage = "variant-string",
},
+ {
+ .name = "vid_pid",
+ .handler = openjtag_handle_vid_pid_command,
+ .mode = COMMAND_CONFIG,
+ .help = "USB VID and PID of the adapter",
+ .usage = "vid pid",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration openjtag_command_handlers[] = {
+ {
+ .name = "openjtag",
+ .mode = COMMAND_ANY,
+ .help = "perform openjtag management",
+ .chain = openjtag_subcommand_handlers,
+ .usage = "",
+ },
COMMAND_REGISTRATION_DONE
};