};
static struct drvs_map lowlevel_drivers_map[] = {
-#if BUILD_USB_BLASTER_LIBFTDI
+#if BUILD_USB_BLASTER
{ .name = "ftdi", .drv_register = ublast_register_ftdi },
#endif
-#if BUILD_USB_BLASTER_FTD2XX
- { .name = "ftd2xx", .drv_register = ublast_register_ftd2xx },
-#endif
#if BUILD_USB_BLASTER_2
{ .name = "ublast2", .drv_register = ublast2_register_libusb },
#endif
int ret = info.drv->read(info.drv, buf, size, bytes_read);
char *str = hexdump(buf, *bytes_read);
- DEBUG_JTAG_IO("(size=%d, buf=[%s]) -> %u", size, str,
+ LOG_DEBUG_IO("(size=%d, buf=[%s]) -> %u", size, str,
*bytes_read);
free(str);
return ret;
int ret = info.drv->write(info.drv, buf, size, bytes_written);
char *str = hexdump(buf, *bytes_written);
- DEBUG_JTAG_IO("(size=%d, buf=[%s]) -> %u", size, str,
+ LOG_DEBUG_IO("(size=%d, buf=[%s]) -> %u", size, str,
*bytes_written);
free(str);
return ret;
info.buf[info.bufidx++] = abyte;
if (nb_buf_remaining() == 0)
ublast_flush_buffer();
- DEBUG_JTAG_IO("(byte=0x%02x)", abyte);
+ LOG_DEBUG_IO("(byte=0x%02x)", abyte);
}
/**
{
uint8_t out;
- DEBUG_JTAG_IO("(tms=%d)", !!tms);
+ LOG_DEBUG_IO("(tms=%d)", !!tms);
info.tms = !!tms;
info.tdi = 0;
out = ublast_build_out(SCAN_OUT);
{
uint8_t out = ublast_build_out(SCAN_OUT);
- DEBUG_JTAG_IO(".");
+ LOG_DEBUG_IO(".");
ublast_queue_byte(out);
}
{
uint8_t out;
- DEBUG_JTAG_IO("(tdi=%d)", !!tdi);
+ LOG_DEBUG_IO("(tdi=%d)", !!tdi);
info.tdi = !!tdi;
out = ublast_build_out(SCAN_OUT);
{
uint8_t out;
- DEBUG_JTAG_IO("(tdi=%d)", !!tdi);
+ LOG_DEBUG_IO("(tdi=%d)", !!tdi);
info.tdi = !!tdi;
info.tms = !info.tms;
info.bufidx + nb_bytes);
exit(-1);
}
- DEBUG_JTAG_IO("(nb_bytes=%d, bytes=[0x%02x, ...])", nb_bytes,
+ LOG_DEBUG_IO("(nb_bytes=%d, bytes=[0x%02x, ...])", nb_bytes,
bytes ? bytes[0] : 0);
if (bytes)
memcpy(&info.buf[info.bufidx], bytes, nb_bytes);
* ublast_tms_seq - write a TMS sequence transition to JTAG
* @bits: TMS bits to be written (bit0, bit1 .. bitN)
* @nb_bits: number of TMS bits (between 1 and 8)
+ * @skip: number of TMS bits to skip at the beginning of the series
*
* Write a serie of TMS transitions, where each transition consists in :
* - writing out TCK=0, TMS=<new_state>, TDI=<???>
* The function ensures that at the end of the sequence, the clock (TCK) is put
* low.
*/
-static void ublast_tms_seq(const uint8_t *bits, int nb_bits)
+static void ublast_tms_seq(const uint8_t *bits, int nb_bits, int skip)
{
int i;
- DEBUG_JTAG_IO("(bits=%02x..., nb_bits=%d)", bits[0], nb_bits);
- for (i = 0; i < nb_bits; i++)
+ LOG_DEBUG_IO("(bits=%02x..., nb_bits=%d)", bits[0], nb_bits);
+ for (i = skip; i < nb_bits; i++)
ublast_clock_tms((bits[i / 8] >> (i % 8)) & 0x01);
ublast_idle_clock();
}
*/
static void ublast_tms(struct tms_command *cmd)
{
- DEBUG_JTAG_IO("(num_bits=%d)", cmd->num_bits);
- ublast_tms_seq(cmd->bits, cmd->num_bits);
+ LOG_DEBUG_IO("(num_bits=%d)", cmd->num_bits);
+ ublast_tms_seq(cmd->bits, cmd->num_bits, 0);
}
/**
{
int i;
- DEBUG_JTAG_IO("(num_states=%d, last_state=%d)",
+ LOG_DEBUG_IO("(num_states=%d, last_state=%d)",
cmd->num_states, cmd->path[cmd->num_states - 1]);
for (i = 0; i < cmd->num_states; i++) {
if (tap_state_transition(tap_get_state(), false) == cmd->path[i])
/**
* ublast_state_move - move JTAG state to the target state
* @state: the target state
+ * @skip: number of bits to skip at the beginning of the path
*
* Input the correct TMS sequence to the JTAG TAP so that we end up in the
* target state. This assumes the current state (tap_get_state()) is correct.
*/
-static void ublast_state_move(tap_state_t state)
+static void ublast_state_move(tap_state_t state, int skip)
{
uint8_t tms_scan;
int tms_len;
- DEBUG_JTAG_IO("(from %s to %s)", tap_state_name(tap_get_state()),
+ LOG_DEBUG_IO("(from %s to %s)", tap_state_name(tap_get_state()),
tap_state_name(state));
if (tap_get_state() == state)
return;
tms_scan = tap_get_tms_path(tap_get_state(), state);
tms_len = tap_get_tms_path_len(tap_get_state(), state);
- ublast_tms_seq(&tms_scan, tms_len);
+ ublast_tms_seq(&tms_scan, tms_len, skip);
tap_set_state(state);
}
unsigned int retlen;
int ret = ERROR_OK;
- DEBUG_JTAG_IO("%s(buf=%p, num_bits=%d)", __func__, buf, nb_bytes * 8);
+ LOG_DEBUG_IO("%s(buf=%p, num_bits=%d)", __func__, buf, nb_bytes * 8);
ublast_flush_buffer();
while (ret == ERROR_OK && nb_bytes > 0) {
ret = ublast_buf_read(buf, nb_bytes, &retlen);
unsigned int retlen;
uint8_t tmp[8];
- DEBUG_JTAG_IO("%s(buf=%p, num_bits=%d)", __func__, buf, nb_bits);
+ LOG_DEBUG_IO("%s(buf=%p, num_bits=%d)", __func__, buf, nb_bits);
/*
* Ensure all previous bitbang writes were issued to the dongle, so that
static void ublast_runtest(int cycles, tap_state_t state)
{
- DEBUG_JTAG_IO("%s(cycles=%i, end_state=%d)", __func__, cycles, state);
+ LOG_DEBUG_IO("%s(cycles=%i, end_state=%d)", __func__, cycles, state);
- ublast_state_move(TAP_IDLE);
+ ublast_state_move(TAP_IDLE, 0);
ublast_queue_tdi(NULL, cycles, SCAN_OUT);
- ublast_state_move(state);
+ ublast_state_move(state, 0);
}
static void ublast_stableclocks(int cycles)
{
- DEBUG_JTAG_IO("%s(cycles=%i)", __func__, cycles);
+ LOG_DEBUG_IO("%s(cycles=%i)", __func__, cycles);
ublast_queue_tdi(NULL, cycles, SCAN_OUT);
}
scan_bits = jtag_build_buffer(cmd, &buf);
if (cmd->ir_scan)
- ublast_state_move(TAP_IRSHIFT);
+ ublast_state_move(TAP_IRSHIFT, 0);
else
- ublast_state_move(TAP_DRSHIFT);
+ ublast_state_move(TAP_DRSHIFT, 0);
log_buf = hexdump(buf, DIV_ROUND_UP(scan_bits, 8));
- DEBUG_JTAG_IO("%s(scan=%s, type=%s, bits=%d, buf=[%s], end_state=%d)", __func__,
+ LOG_DEBUG_IO("%s(scan=%s, type=%s, bits=%d, buf=[%s], end_state=%d)", __func__,
cmd->ir_scan ? "IRSCAN" : "DRSCAN",
type2str[type],
scan_bits, log_buf, cmd->end_state);
ublast_queue_tdi(buf, scan_bits, type);
- /*
- * As our JTAG is in an unstable state (IREXIT1 or DREXIT1), move it
- * forward to a stable IRPAUSE or DRPAUSE.
- */
- ublast_clock_tms(0);
- if (cmd->ir_scan)
- tap_set_state(TAP_IRPAUSE);
- else
- tap_set_state(TAP_DRPAUSE);
-
ret = jtag_read_buffer(buf, cmd);
if (buf)
free(buf);
- ublast_state_move(cmd->end_state);
+ /*
+ * ublast_queue_tdi sends the last bit with TMS=1. We are therefore
+ * already in Exit1-DR/IR and have to skip the first step on our way
+ * to end_state.
+ */
+ ublast_state_move(cmd->end_state, 1);
return ret;
}
static void ublast_usleep(int us)
{
- DEBUG_JTAG_IO("%s(us=%d)", __func__, us);
+ LOG_DEBUG_IO("%s(us=%d)", __func__, us);
jtag_sleep(us);
}
/*
* Put JTAG in RESET state (five 1 on TMS)
*/
- ublast_tms_seq(&tms_reset, 5);
+ ublast_tms_seq(&tms_reset, 5, 0);
tap_set_state(TAP_RESET);
}
ublast_stableclocks(cmd->cmd.stableclocks->num_cycles);
break;
case JTAG_TLR_RESET:
- ublast_state_move(cmd->cmd.statemove->end_state);
+ ublast_state_move(cmd->cmd.statemove->end_state, 0);
break;
case JTAG_PATHMOVE:
ublast_path_move(cmd->cmd.pathmove);
case JTAG_SCAN:
ret = ublast_scan(cmd->cmd.scan);
break;
+ default:
+ LOG_ERROR("BUG: unknown JTAG command type 0x%X",
+ cmd->type);
+ ret = ERROR_FAIL;
+ break;
}
}
{
int ret, i;
- if (info.lowlevel_name) {
- for (i = 0; lowlevel_drivers_map[i].name; i++)
- if (!strcmp(lowlevel_drivers_map[i].name, info.lowlevel_name))
+ for (i = 0; lowlevel_drivers_map[i].name; i++) {
+ if (info.lowlevel_name) {
+ if (!strcmp(lowlevel_drivers_map[i].name, info.lowlevel_name)) {
+ info.drv = lowlevel_drivers_map[i].drv_register();
+ if (!info.drv) {
+ LOG_ERROR("Error registering lowlevel driver \"%s\"",
+ info.lowlevel_name);
+ return ERROR_JTAG_DEVICE_ERROR;
+ }
break;
- if (lowlevel_drivers_map[i].name)
- info.drv = lowlevel_drivers_map[i].drv_register();
- if (!info.drv) {
- LOG_ERROR("no lowlevel driver found for %s or lowlevel driver opening error",
- info.lowlevel_name);
- return ERROR_JTAG_DEVICE_ERROR;
- }
- } else {
- LOG_INFO("No lowlevel driver configured, will try them all");
- for (i = 0; !info.drv && lowlevel_drivers_map[i].name; i++)
+ }
+ } else {
info.drv = lowlevel_drivers_map[i].drv_register();
- if (!info.drv) {
- LOG_ERROR("no lowlevel driver found");
- return ERROR_JTAG_DEVICE_ERROR;
+ if (info.drv) {
+ info.lowlevel_name = strdup(lowlevel_drivers_map[i].name);
+ LOG_INFO("No lowlevel driver configured, using %s", info.lowlevel_name);
+ break;
+ }
}
- info.lowlevel_name = strdup(lowlevel_drivers_map[i-1].name);
+ }
+
+ if (!info.drv) {
+ LOG_ERROR("No lowlevel driver available");
+ return ERROR_JTAG_DEVICE_ERROR;
}
/*
.name = "usb_blaster_lowlevel_driver",
.handler = ublast_handle_lowlevel_drv_command,
.mode = COMMAND_CONFIG,
- .help = "set the lowlevel access for the USB Blaster (ftdi, ftd2xx, ublast2)",
- .usage = "(ftdi|ftd2xx|ublast2)",
+ .help = "set the lowlevel access for the USB Blaster (ftdi, ublast2)",
+ .usage = "(ftdi|ublast2)",
},
{
.name = "usb_blaster_pin",
struct jtag_interface usb_blaster_interface = {
.name = "usb_blaster",
+ .transports = jtag_only,
.commands = ublast_command_handlers,
.supported = DEBUG_CAP_TMS_SEQ,