示例#1
0
static int presto_write(uint8_t *buf, uint32_t size)
{
#if BUILD_PRESTO_FTD2XX == 1
	DWORD ftbytes;
	presto->status = FT_Write(presto->handle, buf, size, &ftbytes);
	if (presto->status != FT_OK) {
		LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(presto->status));
		return ERROR_JTAG_DEVICE_ERROR;
	}

#elif BUILD_PRESTO_LIBFTDI == 1
	uint32_t ftbytes;
	presto->retval = ftdi_write_data(&presto->ftdic, buf, size);
	if (presto->retval < 0) {
		LOG_ERROR("ftdi_write_data: %s", ftdi_get_error_string(&presto->ftdic));
		return ERROR_JTAG_DEVICE_ERROR;
	}
	ftbytes = presto->retval;
#endif

	if (ftbytes != size) {
		LOG_ERROR("couldn't write the requested number of bytes to PRESTO (%u < %u)",
			(unsigned)ftbytes, (unsigned)size);
		return ERROR_JTAG_DEVICE_ERROR;
	}

	return ERROR_OK;
}
示例#2
0
static int
usbconn_ftd2xx_read (urj_usbconn_t *conn, uint8_t *buf, int len)
{
    ftd2xx_param_t *p = conn->params;
    int cpy_len;
    FT_STATUS status = FT_OK;
    DWORD recvd = 0;

    urj_log (URJ_LOG_LEVEL_COMM, "%sread begin: len %d\n", module, len);

    if (!p->fc)
        return -1;

    /* flush send buffer to get all scheduled receive bytes */
    if (usbconn_ftd2xx_flush (p) < 0)
        return -1;

    if (len == 0)
        return 0;

    /* check for number of remaining bytes in receive buffer */
    cpy_len = p->recv_write_idx - p->recv_read_idx;
    if (cpy_len > len)
        cpy_len = len;
    len -= cpy_len;

    if (cpy_len > 0)
    {
        /* get data from the receive buffer */
        memcpy (buf, &p->recv_buf[p->recv_read_idx], cpy_len);
        p->recv_read_idx += cpy_len;
        if (p->recv_read_idx == p->recv_write_idx)
            p->recv_read_idx = p->recv_write_idx = 0;
    }

    if (len > 0)
    {
        /* need to get more data directly from the device */
        while (recvd == 0)
            if ((status =
                 FT_Read (p->fc, &buf[cpy_len], len, &recvd)) != FT_OK)
                urj_error_set (URJ_ERROR_FTD, _("Error from FT_Read(): %s"),
                               ftd2xx_status_string(status));
    }

    urj_log (URJ_LOG_LEVEL_COMM, "%sread end  : status %ld, length %d\n",
             module, status, cpy_len + len);

    return status != FT_OK ? -1 : cpy_len + len;
}
示例#3
0
static int ublast_ftd2xx_read(struct ublast_lowlevel *low, uint8_t *buf,
			     unsigned size, uint32_t *bytes_read)
{
	DWORD dw_bytes_read;
	FT_STATUS status;
	FT_HANDLE *ftdih = ublast_getftdih(low);

	status = FT_Read(*ftdih, buf, size, &dw_bytes_read);
	if (status != FT_OK) {
		*bytes_read = dw_bytes_read;
		LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(status));
		return ERROR_JTAG_DEVICE_ERROR;
	}
	*bytes_read = dw_bytes_read;
	return ERROR_OK;
}
示例#4
0
static int ublast_ftd2xx_write(struct ublast_lowlevel *low, uint8_t *buf, int size,
			      uint32_t *bytes_written)
{
	FT_STATUS status;
	DWORD dw_bytes_written;
	FT_HANDLE *ftdih = ublast_getftdih(low);

	status = FT_Write(*ftdih, buf, size, &dw_bytes_written);
	if (status != FT_OK) {
		*bytes_written = dw_bytes_written;
		LOG_ERROR("FT_Write returned: %s", ftd2xx_status_string(status));
		return ERROR_JTAG_DEVICE_ERROR;
	}
	*bytes_written = dw_bytes_written;
	return ERROR_OK;
}
示例#5
0
static int presto_read(uint8_t *buf, uint32_t size)
{
#if BUILD_PRESTO_FTD2XX == 1
	DWORD ftbytes;
	presto->status = FT_Read(presto->handle, buf, size, &ftbytes);
	if (presto->status != FT_OK) {
		LOG_ERROR("FT_Read returned: %s", ftd2xx_status_string(presto->status));
		return ERROR_JTAG_DEVICE_ERROR;
	}

#elif BUILD_PRESTO_LIBFTDI == 1
	uint32_t ftbytes = 0;

	struct timeval timeout, now;
	gettimeofday(&timeout, NULL);
	timeval_add_time(&timeout, 1, 0);	/* one second timeout */

	while (ftbytes < size) {
		presto->retval = ftdi_read_data(&presto->ftdic, buf + ftbytes, size - ftbytes);
		if (presto->retval < 0) {
			LOG_ERROR("ftdi_read_data: %s", ftdi_get_error_string(&presto->ftdic));
			return ERROR_JTAG_DEVICE_ERROR;
		}
		ftbytes += presto->retval;

		gettimeofday(&now, NULL);
		if ((now.tv_sec > timeout.tv_sec) ||
				((now.tv_sec == timeout.tv_sec) && (now.tv_usec > timeout.tv_usec)))
			break;
	}
#endif

	if (ftbytes != size) {
		/* this is just a warning, there might have been timeout when detecting PRESTO,
		 *which is not fatal */
		LOG_WARNING("couldn't read the requested number of bytes from PRESTO (%u < %u)",
			(unsigned)ftbytes, (unsigned)size);
		return ERROR_JTAG_DEVICE_ERROR;
	}

	return ERROR_OK;
}
示例#6
0
static int ublast_ftd2xx_init(struct ublast_lowlevel *low)
{
	FT_STATUS status;
	FT_HANDLE *ftdih = ublast_getftdih(low);
	uint8_t latency_timer;

	LOG_INFO("usb blaster interface using FTD2XX");
	/* Open by device description */
	if (low->ublast_device_desc == NULL) {
		LOG_WARNING("no usb blaster device description specified, "
			    "using default 'USB-Blaster'");
		low->ublast_device_desc = "USB-Blaster";
	}

#if IS_WIN32 == 0
	/* Add non-standard Vid/Pid to the linux driver */
	status = FT_SetVIDPID(low->ublast_vid, low->ublast_pid);
	if (status != FT_OK) {
		LOG_WARNING("couldn't add %4.4x:%4.4x",
			    low->ublast_vid, low->ublast_pid);
	}
#endif
	status = FT_OpenEx(low->ublast_device_desc, FT_OPEN_BY_DESCRIPTION,
			   ftdih);
	if (status != FT_OK) {
		DWORD num_devices;

		LOG_ERROR("unable to open ftdi device: %s",
			  ftd2xx_status_string(status));
		status = FT_ListDevices(&num_devices, NULL, FT_LIST_NUMBER_ONLY);
		if (status == FT_OK) {
			char **desc_array =
				malloc(sizeof(char *) * (num_devices + 1));
			unsigned int i;

			for (i = 0; i < num_devices; i++)
				desc_array[i] = malloc(64);
			desc_array[num_devices] = NULL;

			status = FT_ListDevices(desc_array, &num_devices,
						FT_LIST_ALL | FT_OPEN_BY_DESCRIPTION);

			if (status == FT_OK) {
				LOG_ERROR("ListDevices: %" PRIu32, (uint32_t)num_devices);
				for (i = 0; i < num_devices; i++)
					LOG_ERROR("%i: %s", i, desc_array[i]);
			}

			for (i = 0; i < num_devices; i++)
				free(desc_array[i]);
			free(desc_array);
		} else {
			printf("ListDevices: NONE\n");
		}
		return ERROR_JTAG_INIT_FAILED;
	}

	status = FT_SetLatencyTimer(*ftdih, 2);
	if (status != FT_OK) {
		LOG_ERROR("unable to set latency timer: %s",
				ftd2xx_status_string(status));
		return ERROR_JTAG_INIT_FAILED;
	}

	status = FT_GetLatencyTimer(*ftdih, &latency_timer);
	if (status != FT_OK) {
		LOG_ERROR("unable to get latency timer: %s",
				ftd2xx_status_string(status));
		return ERROR_JTAG_INIT_FAILED;
	}
	LOG_DEBUG("current latency timer: %i", latency_timer);

	status = FT_SetBitMode(*ftdih, 0x00, 0);
	if (status != FT_OK) {
		LOG_ERROR("unable to disable bit i/o mode: %s",
				ftd2xx_status_string(status));
		return ERROR_JTAG_INIT_FAILED;
	}
	return ERROR_OK;
}
示例#7
0
static int presto_open_ftd2xx(char *req_serial)
{
	uint32_t i;
	DWORD numdevs;
	DWORD vidpid;
	char devname[FT_DEVICE_NAME_LEN];
	FT_DEVICE device;

	BYTE presto_data;
	DWORD ftbytes;

	presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;

#if IS_WIN32 == 0
	/* Add non-standard Vid/Pid to the linux driver */
	presto->status = FT_SetVIDPID(PRESTO_VID, PRESTO_PID);
	if (presto->status != FT_OK) {
		LOG_ERROR("couldn't add PRESTO VID/PID");
		exit(-1);
	}
#endif

	presto->status = FT_ListDevices(&numdevs, NULL, FT_LIST_NUMBER_ONLY);
	if (presto->status != FT_OK) {
		LOG_ERROR("FT_ListDevices failed: %s", ftd2xx_status_string(presto->status));
		return ERROR_JTAG_DEVICE_ERROR;
	}

	LOG_DEBUG("FTDI devices available: %" PRIu32, (uint32_t)numdevs);
	for (i = 0; i < numdevs; i++) {
		presto->status = FT_Open(i, &(presto->handle));
		if (presto->status != FT_OK) {
			/* this is not fatal, the device may be legitimately open by other process,
			 *hence debug message only */
			LOG_DEBUG("FT_Open failed: %s", ftd2xx_status_string(presto->status));
			continue;
		}
		LOG_DEBUG("FTDI device %i open", (int)i);

		presto->status = FT_GetDeviceInfo(presto->handle, &device,
				&vidpid, presto->serial, devname, NULL);
		if (presto->status == FT_OK) {
			if (vidpid == PRESTO_VID_PID && (req_serial == NULL ||
					!strcmp(presto->serial, req_serial)))
				break;
		} else
			LOG_DEBUG("FT_GetDeviceInfo failed: %s", ftd2xx_status_string(
					presto->status));

		LOG_DEBUG("FTDI device %i does not match, closing", (int)i);
		FT_Close(presto->handle);
		presto->handle = (FT_HANDLE)INVALID_HANDLE_VALUE;
	}

	if (presto->handle == (FT_HANDLE)INVALID_HANDLE_VALUE)
		return ERROR_JTAG_DEVICE_ERROR;	/* presto not open, return */

	presto->status = FT_SetLatencyTimer(presto->handle, 1);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	presto->status = FT_SetTimeouts(presto->handle, 100, 0);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	presto_data = 0xD0;
	presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	/* delay between first write/read turnaround (after purge?) necessary
	 * under Linux for unknown reason,
	 * probably a bug in library threading */
	usleep(100000);
	presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	if (ftbytes != 1) {
		LOG_DEBUG("PRESTO reset");

		presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;
		presto->status = FT_SetBitMode(presto->handle, 0x80, 1);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;
		presto->status = FT_SetBaudRate(presto->handle, 9600);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		presto_data = 0;
		for (i = 0; i < 4 * 62; i++) {
			presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
			if (presto->status != FT_OK)
				return ERROR_JTAG_DEVICE_ERROR;
		}
		usleep(100000);

		presto->status = FT_SetBitMode(presto->handle, 0x00, 0);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		presto->status = FT_Purge(presto->handle, FT_PURGE_TX | FT_PURGE_RX);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		presto_data = 0xD0;
		presto->status = FT_Write(presto->handle, &presto_data, 1, &ftbytes);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		/* delay between first write/read turnaround (after purge?) necessary under Linux for unknown reason,
		   probably a bug in library threading */
		usleep(100000);
		presto->status = FT_Read(presto->handle, &presto_data, 1, &ftbytes);
		if (presto->status != FT_OK)
			return ERROR_JTAG_DEVICE_ERROR;

		if (ftbytes != 1) {
			LOG_DEBUG("PRESTO not responding");
			return ERROR_JTAG_DEVICE_ERROR;
		}
	}

	presto->status = FT_SetTimeouts(presto->handle, 0, 0);
	if (presto->status != FT_OK)
		return ERROR_JTAG_DEVICE_ERROR;

	presto->status = FT_Write(presto->handle, &presto_init_seq,
			sizeof(presto_init_seq), &ftbytes);

	if (presto->status != FT_OK || ftbytes != sizeof(presto_init_seq))
		return ERROR_JTAG_DEVICE_ERROR;

	return ERROR_OK;
}
示例#8
0
/** @return number of flushed bytes on success; -1 on error */
static int
usbconn_ftd2xx_flush (ftd2xx_param_t *p)
{
    FT_STATUS status;
    DWORD xferred;
    DWORD recvd = 0;

    if (!p->fc)
        return -1;

    urj_log (URJ_LOG_LEVEL_COMM, "%sflush begin:\n", module);
    urj_log (URJ_LOG_LEVEL_COMM, "  send_buf_len %d, send_buffered %d\n",
             p->send_buf_len, p->send_buffered);
    urj_log (URJ_LOG_LEVEL_COMM, "  recv_buf_len %d, to_recv %d\n",
             p->recv_buf_len, p->to_recv);
    urj_log (URJ_LOG_LEVEL_COMM, "  recv_write_idx %d, recv_read_idx %d\n",
             p->recv_write_idx, p->recv_read_idx);

    if (p->send_buffered == 0)
        return 0;

    if ((status = FT_Write (p->fc, p->send_buf, p->send_buffered,
                            &xferred)) != FT_OK)
    {
        urj_error_set (URJ_ERROR_FTD, _("FT_Write() failed: %s"),
                       ftd2xx_status_string(status));
        return -1;
    }

    if (xferred < p->send_buffered)
    {
        urj_error_set (URJ_ERROR_ILLEGAL_STATE,
                       _("Written fewer bytes than requested"));
        return -1;
    }

    p->send_buffered = 0;

    /* now read all scheduled receive bytes */
    if (p->to_recv)
    {
        if (p->recv_write_idx + p->to_recv > p->recv_buf_len)
        {
            /* extend receive buffer */
            p->recv_buf_len = p->recv_write_idx + p->to_recv;
            if (p->recv_buf)
                p->recv_buf = realloc (p->recv_buf, p->recv_buf_len);
        }

        if (!p->recv_buf)
        {
            urj_error_set (URJ_ERROR_ILLEGAL_STATE,
                           _("Receive buffer does not exist"));
            return -1;
        }

        while (recvd == 0)
            if ((status = FT_Read (p->fc, &p->recv_buf[p->recv_write_idx],
                                   p->to_recv, &recvd)) != FT_OK)
                urj_error_set (URJ_ERROR_FTD, _("Error from FT_Read(): %s"),
                               ftd2xx_status_string(status));

        if (recvd < p->to_recv)
            urj_log (URJ_LOG_LEVEL_NORMAL,
                     _("%s(): Received fewer bytes than requested.\n"),
                    __func__);

        p->to_recv -= recvd;
        p->recv_write_idx += recvd;
    }

    urj_log (URJ_LOG_LEVEL_COMM,
             "%sflush end: status %ld, xferred %ld, recvd %ld\n", module,
            status, xferred, recvd);

    return status != FT_OK ? -1 : xferred;
}