static int ublast2_libusb_init(struct ublast_lowlevel *low)
{
	const uint16_t vids[] = { low->ublast_vid_uninit, 0 };
	const uint16_t pids[] = { low->ublast_pid_uninit, 0 };
	struct jtag_libusb_device_handle *temp;
	bool renumeration = false;
	int ret;

	if (jtag_libusb_open(vids, pids, NULL, &temp) == ERROR_OK) {
		LOG_INFO("Altera USB-Blaster II (uninitialized) found");
		LOG_INFO("Loading firmware...");
		ret = load_usb_blaster_firmware(temp, low);
		jtag_libusb_close(temp);
		if (ret != ERROR_OK)
			return ret;
		renumeration = true;
	}

	const uint16_t vids_renum[] = { low->ublast_vid, 0 };
	const uint16_t pids_renum[] = { low->ublast_pid, 0 };

	if (renumeration == false) {
		if (jtag_libusb_open(vids_renum, pids_renum, NULL, &low->libusb_dev) != ERROR_OK) {
			LOG_ERROR("Altera USB-Blaster II not found");
			return ERROR_FAIL;
		}
	} else {
		int retry = 10;
		while (jtag_libusb_open(vids_renum, pids_renum, NULL, &low->libusb_dev) != ERROR_OK && retry--) {
			usleep(1000000);
			LOG_INFO("Waiting for renumerate...");
		}

		if (!retry) {
			LOG_ERROR("Altera USB-Blaster II not found");
			return ERROR_FAIL;
		}
	}

	char buffer[5];
	jtag_libusb_control_transfer(low->libusb_dev,
				     LIBUSB_REQUEST_TYPE_VENDOR | \
				     LIBUSB_ENDPOINT_IN,
				     USBBLASTER_CTRL_READ_REV,
				     0,
				     0,
				     buffer,
				     5,
				     100);

	LOG_INFO("Altera USB-Blaster II found (Firm. rev. = %s)", buffer);

	return ERROR_OK;
}
Exemple #2
0
/*	Basic operation for opening USB device */
static int osbdm_open(struct osbdm *osbdm)
{
	(void)memset(osbdm, 0, sizeof(*osbdm));
	if (jtag_libusb_open(osbdm_vid, osbdm_pid, NULL, &osbdm->devh) != ERROR_OK)
		return ERROR_FAIL;

	if (jtag_libusb_claim_interface(osbdm->devh, 0) != ERROR_OK)
		return ERROR_FAIL;

	return ERROR_OK;
}
Exemple #3
0
static int stlink_usb_open(struct stlink_interface_param_s *param, void **fd)
{
	int err;
	struct stlink_usb_handle_s *h;
	enum stlink_jtag_api_version api;

	LOG_DEBUG("stlink_usb_open");

	h = malloc(sizeof(struct stlink_usb_handle_s));

	if (h == 0) {
		LOG_DEBUG("malloc failed");
		return ERROR_FAIL;
	}

	h->transport = param->transport;

	const uint16_t vids[] = { param->vid, 0 };
	const uint16_t pids[] = { param->pid, 0 };

	LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param->transport,
		param->vid, param->pid);

	if (jtag_libusb_open(vids, pids, &h->fd) != ERROR_OK) {
		LOG_ERROR("open failed");
		return ERROR_FAIL;
	}

	jtag_libusb_set_configuration(h->fd, 0);

	if (jtag_libusb_claim_interface(h->fd, 0) != ERROR_OK) {
		LOG_DEBUG("claim interface failed");
		return ERROR_FAIL;
	}

	/* wrap version for first read */
	switch (param->pid) {
		case 0x3744:
			h->version.stlink = 1;
			break;
		default:
			h->version.stlink = 2;
			break;
	}

	/* get the device version */
	err = stlink_usb_version(h);

	if (err != ERROR_OK) {
		LOG_ERROR("read version failed");
		jtag_libusb_close(h->fd);
		free(h);
		return err;
	}

	/* compare usb vid/pid */
	if ((param->vid != h->vid) || (param->pid != h->pid))
		LOG_INFO("vid/pid are not identical: 0x%04X/0x%04X 0x%04X/0x%04X",
			param->vid, param->pid,
			h->vid, h->pid);

	/* check if mode is supported */
	err = ERROR_OK;

	switch (h->transport) {
		case STLINK_TRANSPORT_SWD:
		case STLINK_TRANSPORT_JTAG:
			if (h->version.jtag == 0)
				err = ERROR_FAIL;
			break;
		case STLINK_TRANSPORT_SWIM:
			if (h->version.swim == 0)
				err = ERROR_FAIL;
			break;
		default:
			err = ERROR_FAIL;
			break;
	}

	if (err != ERROR_OK) {
		LOG_ERROR("mode (transport) not supported by device");
		jtag_libusb_close(h->fd);
		free(h);
		return err;
	}

	api = h->version.jtag_api_max;

	/* check that user has not requested certain api version
	 * and if they have check it is supported */
	if ((param->api != 0) && (param->api <= h->version.jtag_api_max)) {
		api = param->api;
		LOG_INFO("using stlink api v%d", api);
	}

	/* set the used jtag api, this will default to the newest supported version */
	h->jtag_api = api;

	/* initialize the debug hardware */
	err = stlink_usb_init_mode(h);

	if (err != ERROR_OK) {
		LOG_ERROR("init mode failed");
		jtag_libusb_close(h->fd);
		free(h);
		return err;
	}

	*fd = h;

	return ERROR_OK;
}
Exemple #4
0
static int stlink_usb_open(struct hl_interface_param_s *param, void **fd)
{
	int err, retry_count = 1;
	struct stlink_usb_handle_s *h;
	enum stlink_jtag_api_version api;

	LOG_DEBUG("stlink_usb_open");

	h = calloc(1, sizeof(struct stlink_usb_handle_s));

	if (h == 0) {
		LOG_DEBUG("malloc failed");
		return ERROR_FAIL;
	}

	h->transport = param->transport;

	const uint16_t vids[] = { param->vid, 0 };
	const uint16_t pids[] = { param->pid, 0 };

	LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param->transport,
		param->vid, param->pid);

	/*
	  On certain host USB configurations(e.g. MacBook Air)
	  STLINKv2 dongle seems to have its FW in a funky state if,
	  after plugging it in, you try to use openocd with it more
	  then once (by launching and closing openocd). In cases like
	  that initial attempt to read the FW info via
	  stlink_usb_version will fail and the device has to be reset
	  in order to become operational.
	 */
	do {
		if (jtag_libusb_open(vids, pids, &h->fd) != ERROR_OK) {
			LOG_ERROR("open failed");
			goto error_open;
		}

		jtag_libusb_set_configuration(h->fd, 0);

		if (jtag_libusb_claim_interface(h->fd, 0) != ERROR_OK) {
			LOG_DEBUG("claim interface failed");
			goto error_open;
		}

		/* RX EP is common for all versions */
		h->rx_ep = STLINK_RX_EP;

		/* wrap version for first read */
		switch (param->pid) {
			case STLINK_V1_PID:
				h->version.stlink = 1;
				h->tx_ep = STLINK_TX_EP;
				h->trace_ep = STLINK_TRACE_EP;
				break;
			case STLINK_V2_1_PID:
				h->version.stlink = 2;
				h->tx_ep = STLINK_V2_1_TX_EP;
				h->trace_ep = STLINK_V2_1_TRACE_EP;
				break;
			default:
			/* fall through - we assume V2 to be the default version*/
			case STLINK_V2_PID:
				h->version.stlink = 2;
				h->tx_ep = STLINK_TX_EP;
				h->trace_ep = STLINK_TRACE_EP;
				break;
		}

		/* get the device version */
		err = stlink_usb_version(h);

		if (err == ERROR_OK) {
			break;
		} else if (h->version.stlink == 1 ||
			   retry_count == 0) {
			LOG_ERROR("read version failed");
			goto error_open;
		} else {
			err = jtag_libusb_release_interface(h->fd, 0);
			if (err != ERROR_OK) {
				LOG_ERROR("release interface failed");
				goto error_open;
			}

			err = jtag_libusb_reset_device(h->fd);
			if (err != ERROR_OK) {
				LOG_ERROR("reset device failed");
				goto error_open;
			}

			jtag_libusb_close(h->fd);
			/*
			  Give the device one second to settle down and
			  reenumerate.
			 */
			usleep(1 * 1000 * 1000);
			retry_count--;
		}
	} while (1);

	/* compare usb vid/pid */
	if ((param->vid != h->vid) || (param->pid != h->pid))
		LOG_INFO("vid/pid are not identical: 0x%04X/0x%04X 0x%04X/0x%04X",
			param->vid, param->pid,
			h->vid, h->pid);

	/* check if mode is supported */
	err = ERROR_OK;

	switch (h->transport) {
		case HL_TRANSPORT_SWD:
		case HL_TRANSPORT_JTAG:
			if (h->version.jtag == 0)
				err = ERROR_FAIL;
			break;
		case HL_TRANSPORT_SWIM:
			if (h->version.swim == 0)
				err = ERROR_FAIL;
			break;
		default:
			err = ERROR_FAIL;
			break;
	}

	if (err != ERROR_OK) {
		LOG_ERROR("mode (transport) not supported by device");
		goto error_open;
	}

	api = h->version.jtag_api_max;

	LOG_INFO("using stlink api v%d", api);

	/* set the used jtag api, this will default to the newest supported version */
	h->jtag_api = api;

	if (h->jtag_api >= 2 && param->trace_source_hz > 0) {
		uint32_t prescale;

		prescale = param->trace_source_hz > STLINK_TRACE_MAX_HZ ?
			(param->trace_source_hz / STLINK_TRACE_MAX_HZ) - 1 : 0;

		h->trace.output_f = param->trace_f;
		h->trace.source_hz = param->trace_source_hz;
		h->trace.prescale = prescale;
	}

	/* initialize the debug hardware */
	err = stlink_usb_init_mode(h, param->connect_under_reset);

	if (err != ERROR_OK) {
		LOG_ERROR("init mode failed");
		goto error_open;
	}

	/* get cpuid, so we can determine the max page size
	 * start with a safe default */
	h->max_mem_packet = (1 << 10);

	uint8_t buffer[4];
	err = stlink_usb_read_mem32(h, CPUID, 4, buffer);
	if (err == ERROR_OK) {
		uint32_t cpuid = le_to_h_u32(buffer);
		int i = (cpuid >> 4) & 0xf;
		if (i == 4 || i == 3) {
			/* Cortex-M3/M4 has 4096 bytes autoincrement range */
			h->max_mem_packet = (1 << 12);
		}
	}
Exemple #5
0
static int icdi_usb_open(struct hl_interface_param_s *param, void **fd)
{
	int retval;
	struct icdi_usb_handle_s *h;

	LOG_DEBUG("icdi_usb_open");

	h = calloc(1, sizeof(struct icdi_usb_handle_s));

	if (h == 0) {
		LOG_ERROR("unable to allocate memory");
		return ERROR_FAIL;
	}

	LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x serial: %s", param->transport,
		param->vid, param->pid, param->serial ? param->serial : "");


	/* Derived from stlink_usb.c */
	const uint16_t vids[] = { param->vid, 0 };
	const uint16_t pids[] = { param->pid, 0 };

	jtag_libusb_open(vids, pids, param->serial, &h->usb_dev);

	if (!h->usb_dev) {
		LOG_ERROR("open failed");
		goto error_open;
	}

	if (libusb_claim_interface(h->usb_dev, 2)) {
		LOG_DEBUG("claim interface failed");
		goto error_open;
	}

	/* check if mode is supported */
	retval = ERROR_OK;

	switch (param->transport) {
#if 0
		/* TODO place holder as swd is not currently supported */
		case HL_TRANSPORT_SWD:
#endif
		case HL_TRANSPORT_JTAG:
			break;
		default:
			retval = ERROR_FAIL;
			break;
	}

	if (retval != ERROR_OK) {
		LOG_ERROR("mode (transport) not supported by device");
		goto error_open;
	}

	/* allocate buffer */
	h->read_buffer = malloc(ICDI_PACKET_SIZE);
	h->write_buffer = malloc(ICDI_PACKET_SIZE);
	h->max_packet = ICDI_PACKET_SIZE;

	if (h->read_buffer == 0 || h->write_buffer == 0) {
		LOG_DEBUG("malloc failed");
		goto error_open;
	}

	/* query icdi version etc */
	retval = icdi_usb_version(h);
	if (retval != ERROR_OK)
		goto error_open;

	/* query icdi support */
	retval = icdi_usb_query(h);
	if (retval != ERROR_OK)
		goto error_open;

	*fd = h;

	/* set the max target read/write buffer in bytes
	 * as we are using gdb binary packets to transfer memory we have to
	 * reserve half the buffer for any possible escape chars plus
	 * at least 64 bytes for the gdb packet header */
	h->max_rw_packet = (((h->max_packet - 64) / 4) * 4) / 2;

	return ERROR_OK;

error_open:
	icdi_usb_close(h);

	return ERROR_FAIL;
}