Ejemplo n.º 1
0
static int presto_flush(void)
{
	if (presto->buff_out_pos == 0)
		return ERROR_OK;

	if (presto->retval < 0) {
		LOG_DEBUG("error in previous communication, canceling I/O operation");
		return ERROR_JTAG_DEVICE_ERROR;
	}

	if (presto_write(presto->buff_out, presto->buff_out_pos) != ERROR_OK) {
		presto->buff_out_pos = 0;
		return ERROR_JTAG_DEVICE_ERROR;
	}

	presto->total_out += presto->buff_out_pos;
	presto->buff_out_pos = 0;

	if (presto->buff_in_exp == 0)
		return ERROR_OK;

	presto->buff_in_pos = 0;
	presto->buff_in_len = 0;

	if (presto_read(presto->buff_in, presto->buff_in_exp) != ERROR_OK) {
		presto->buff_in_exp = 0;
		return ERROR_JTAG_DEVICE_ERROR;
	}

	presto->total_in += presto->buff_in_exp;
	presto->buff_in_len = presto->buff_in_exp;
	presto->buff_in_exp = 0;

	return ERROR_OK;
}
Ejemplo n.º 2
0
static int presto_open_libftdi(char *req_serial)
{
	uint8_t presto_data;

	LOG_DEBUG("searching for PRESTO using libftdi");

	/* initialize FTDI context structure */
	if (ftdi_init(&presto->ftdic) < 0) {
		LOG_ERROR("unable to init libftdi: %s", presto->ftdic.error_str);
		return ERROR_JTAG_DEVICE_ERROR;
	}

	/* context, vendor id, product id */
	if (ftdi_usb_open_desc(&presto->ftdic, PRESTO_VID, PRESTO_PID, NULL, req_serial) < 0) {
		LOG_ERROR("unable to open PRESTO: %s", presto->ftdic.error_str);
		return ERROR_JTAG_DEVICE_ERROR;
	}

	if (ftdi_usb_reset(&presto->ftdic) < 0) {
		LOG_ERROR("unable to reset PRESTO device");
		return ERROR_JTAG_DEVICE_ERROR;
	}

	if (ftdi_set_latency_timer(&presto->ftdic, 1) < 0) {
		LOG_ERROR("unable to set latency timer");
		return ERROR_JTAG_DEVICE_ERROR;
	}

	if (ftdi_usb_purge_buffers(&presto->ftdic) < 0) {
		LOG_ERROR("unable to purge PRESTO buffers");
		return ERROR_JTAG_DEVICE_ERROR;
	}

	presto_data = 0xD0;
	if (presto_write(&presto_data, 1) != ERROR_OK) {
		LOG_ERROR("error writing to PRESTO");
		return ERROR_JTAG_DEVICE_ERROR;
	}

	if (presto_read(&presto_data, 1) != ERROR_OK) {
		LOG_DEBUG("no response from PRESTO, retrying");

		if (ftdi_usb_purge_buffers(&presto->ftdic) < 0)
			return ERROR_JTAG_DEVICE_ERROR;

		presto_data = 0xD0;
		if (presto_write(&presto_data, 1) != ERROR_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		if (presto_read(&presto_data, 1) != ERROR_OK) {
			LOG_ERROR("no response from PRESTO, giving up");
			return ERROR_JTAG_DEVICE_ERROR;
		}
	}

	if (presto_write(presto_init_seq, sizeof(presto_init_seq)) != ERROR_OK) {
		LOG_ERROR("error writing PRESTO init sequence");
		return ERROR_JTAG_DEVICE_ERROR;
	}

	return ERROR_OK;
}
Ejemplo n.º 3
0
static int presto_flush(void)
{
	if (presto->buff_out_pos == 0)
		return ERROR_OK;

#if BUILD_PRESTO_FTD2XX == 1
	if (presto->status != FT_OK) {
#elif BUILD_PRESTO_LIBFTDI == 1
	if (presto->retval < 0) {
#endif
		LOG_DEBUG("error in previous communication, canceling I/O operation");
		return ERROR_JTAG_DEVICE_ERROR;
	}

	if (presto_write(presto->buff_out, presto->buff_out_pos) != ERROR_OK) {
		presto->buff_out_pos = 0;
		return ERROR_JTAG_DEVICE_ERROR;
	}

	presto->total_out += presto->buff_out_pos;
	presto->buff_out_pos = 0;

	if (presto->buff_in_exp == 0)
		return ERROR_OK;

	presto->buff_in_pos = 0;
	presto->buff_in_len = 0;

	if (presto_read(presto->buff_in, presto->buff_in_exp) != ERROR_OK) {
		presto->buff_in_exp = 0;
		return ERROR_JTAG_DEVICE_ERROR;
	}

	presto->total_in += presto->buff_in_exp;
	presto->buff_in_len = presto->buff_in_exp;
	presto->buff_in_exp = 0;

	return ERROR_OK;
}

static int presto_sendbyte(int data)
{
	if (data == EOF)
		return presto_flush();

	if (presto->buff_out_pos < BUFFER_SIZE) {
		presto->buff_out[presto->buff_out_pos++] = (uint8_t)data;
		if (((data & 0xC0) == 0x40) || ((data & 0xD0) == 0xD0))
			presto->buff_in_exp++;
	} else
		return ERROR_JTAG_DEVICE_ERROR;

#if BUILD_PRESTO_FTD2XX == 1
	if (presto->buff_out_pos >= BUFFER_SIZE)
#elif BUILD_PRESTO_LIBFTDI == 1
	/* libftdi does not do background read, be sure that USB IN buffer does not overflow (128
	 *bytes only!) */
	if (presto->buff_out_pos >= BUFFER_SIZE || presto->buff_in_exp == 128)
#endif
		return presto_flush();

	return ERROR_OK;
}

#if 0
static int presto_getbyte(void)
{
	if (presto->buff_in_pos < presto->buff_in_len)
		return presto->buff_in[presto->buff_in_pos++];

	if (presto->buff_in_exp == 0)
		return -1;

	if (presto_flush() != ERROR_OK)
		return -1;

	if (presto->buff_in_pos < presto->buff_in_len)
		return presto->buff_in[presto->buff_in_pos++];

	return -1;
}
#endif

/* -------------------------------------------------------------------------- */

static int presto_tdi_flush(void)
{
	if (presto->jtag_tdi_count == 0)
		return 0;

	if (presto->jtag_tck == 0) {
		LOG_ERROR("BUG: unexpected TAP condition, TCK low");
		return -1;
	}

	presto->jtag_tdi_data |= (presto->jtag_tdi_count - 1) << 4;
	presto_sendbyte(presto->jtag_tdi_data);
	presto->jtag_tdi_count = 0;
	presto->jtag_tdi_data = 0;

	return 0;
}

static int presto_tck_idle(void)
{
	if (presto->jtag_tck == 1) {
		presto_sendbyte(0xCA);
		presto->jtag_tck = 0;
	}

	return 0;
}

/* -------------------------------------------------------------------------- */

static int presto_bitq_out(int tms, int tdi, int tdo_req)
{
	int i;
	unsigned char cmd;

	if (presto->jtag_tck == 0)
		presto_sendbyte(0xA4);	/* LED idicator - JTAG active */
	else if (presto->jtag_speed == 0 && !tdo_req && tms == presto->jtag_tms) {
		presto->jtag_tdi_data |= (tdi != 0) << presto->jtag_tdi_count;

		if (++presto->jtag_tdi_count == 4)
			presto_tdi_flush();

		return 0;
	}

	presto_tdi_flush();

	cmd = tdi ? 0xCB : 0xCA;
	presto_sendbyte(cmd);

	if (tms != presto->jtag_tms) {
		presto_sendbyte((tms ? 0xEC : 0xE8) | (presto->jtag_rst ? 0x02 : 0));
		presto->jtag_tms = tms;
	}

	/* delay with TCK low */
	for (i = presto->jtag_speed; i > 1; i--)
		presto_sendbyte(cmd);

	cmd |= 0x04;
	presto_sendbyte(cmd | (tdo_req ? 0x10 : 0));

	/* delay with TCK high */
	for (i = presto->jtag_speed; i > 1; i--)
		presto_sendbyte(cmd);

	presto->jtag_tck = 1;

	return 0;
}