示例#1
0
int slogic_open(struct slogic_ctx *handle, int logic_index){
int err,i;	
size_t cnt;
libusb_device **list;
libusb_device *found = NULL;
struct libusb_device_descriptor descriptor;	
	
	cnt = libusb_get_device_list(handle->usb_context, &list);
	i = 0;
	if (cnt < 0) {
		log_printf( DEBUG,  "Failed to get a list of devices\n");
		return 0;
	}
	
	for (i = 0; i < cnt; i++) {
		libusb_device *device = list[i];
		err = libusb_get_device_descriptor(device, &descriptor);
		if (err) {
			log_printf( DEBUG,  "libusb_get_device_descriptor: %s\n", usbutil_error_to_string(err));
			libusb_free_device_list(list, 1);
			return 0;
		}
		if ((descriptor.idVendor == USB_VENDOR_ID) && (descriptor.idProduct == USB_PRODUCT_ID)) {
			found = device;
			usbutil_dump_device_descriptor(&descriptor);
			break;
		}
	}
	
	if (!found) {
		log_printf( DEBUG,  "Device not found\n");
		libusb_free_device_list(list, 1);
		return 0;
	}
	
	if ((err = libusb_open(found, &handle->device_handle))) {
		log_printf( DEBUG,  "Failed OPEN the device: %s\n", usbutil_error_to_string(err));
		libusb_free_device_list(list, 1);
		return 0;
	}
	log_printf( DEBUG,  "libusb_open: %s\n", usbutil_error_to_string(err));	
	
	if ((err = claim_device(handle->device_handle, 0)) != 0) {
		log_printf( DEBUG, "Failed to claim the usb interface: %s\n", usbutil_error_to_string(err));
		libusb_free_device_list(list, 1);
		return 0;
	}	
	
	
	if (!handle->device_handle) {
		log_printf( ERR, "Failed to open the device\n");
		libusb_free_device_list(list, 1);
		return -1;
	}
	libusb_free_device_list(list, 1);
	handle->dev = libusb_get_device(handle->device_handle);
	handle->transfers = calloc(1,sizeof(struct logic_transfers) * handle->n_transfer_buffers);

	return 0;
}
示例#2
0
/*
 * This method looks if the kernel already has a driver attached to the device. if so I will take over the device.
 */
static enum libusb_error claim_device(libusb_device_handle * dev, int interface)
{
	enum libusb_error err;
	if (libusb_kernel_driver_active(dev, interface)) {
		fprintf(stderr, "A kernel has claimed the interface, detaching it...\n");
		if ((err = libusb_detach_kernel_driver(dev, interface)) != 0) {
			fprintf(stderr, "Failed to Disconnected the OS driver: %s\n", usbutil_error_to_string(err));
			return err;
		}
	}

	if ((err = libusb_set_configuration(dev, 1))) {
		fprintf(stderr, "libusb_set_configuration: %s\n", usbutil_error_to_string(err));
		return err;
	}
	fprintf(stderr, "libusb_set_configuration: %s\n", usbutil_error_to_string(err));

	/* claim interface */
	if ((err = libusb_claim_interface(dev, interface))) {
		fprintf(stderr, "Claim interface error: %s\n", usbutil_error_to_string(err));
		return err;
	}
	fprintf(stderr, "libusb_claim_interface: %s\n", usbutil_error_to_string(err));

	if ((err = libusb_set_interface_alt_setting(dev, interface, 0))) {
		fprintf(stderr, "libusb_set_interface_alt_setting: %s\n", usbutil_error_to_string(err));
		return err;
	}
	fprintf(stderr, "libusb_set_interface_alt_setting: %s\n", usbutil_error_to_string(err));

	return LIBUSB_SUCCESS;
}
示例#3
0
int slogic_readbyte(struct slogic_handle *handle, unsigned char *out)
{
	int ret;
	unsigned char command = 0x05;
	int transferred;

	ret = libusb_bulk_transfer(handle->device_handle, COMMAND_OUT_ENDPOINT, &command, 1, &transferred, 100);
	if (ret) {
		log_printf(&logger, ERR, "libusb_bulk_transfer (out): %s\n", usbutil_error_to_string(ret));
		return ret;
	}

	ret = libusb_bulk_transfer(handle->device_handle, COMMAND_IN_ENDPOINT, out, 1, &transferred, 100);
	if (ret) {
		log_printf(&logger, ERR, "libusb_bulk_transfer (in): %s\n", usbutil_error_to_string(ret));
		return ret;
	}
	return 0;
}
示例#4
0
int slogic_pump_data(struct slogic_ctx *handle, unsigned int transfer_id){
int retval;
	
	
	if((retval = libusb_submit_transfer(handle->transfers[transfer_id].transfer))){
		handle->transfers[transfer_id].state = 1;
		log_printf( ERR, "libusb_submit_transfer: %s\n", usbutil_error_to_string(retval));
		handle->recording_state = UNKNOWN;
		return 1;
	}
	return 0;
}
示例#5
0
int slogic_execute_recording(struct slogic_ctx *handle){
int transfer_id,retval,ret;
struct timeval timeout;	


	handle->recording_state = WARMING_UP;
	
	for (transfer_id = 0; transfer_id < handle->n_transfer_buffers; transfer_id++) {
		slogic_prime_data(handle, transfer_id);
	}
		
	handle->recording_state = RUNNING;


	for (transfer_id = 0; transfer_id < handle->n_transfer_buffers; transfer_id++) {
		if(!transfer_id){
			slogic_set_capture_async(handle);
		}
		slogic_pump_data(handle, transfer_id);
		handle->transfer_count++;
	}


	while (handle->recording_state == RUNNING) {		
		timeout.tv_sec = 1;
		if((ret = libusb_handle_events_timeout(handle->usb_context, &timeout))){
			log_printf( ERR, "libusb_handle_events: %s\n", usbutil_error_to_string(ret));
			break;
		}
	}

	//spindown!





	if (handle->recording_state == COMPLETED_SUCCESSFULLY) {
		log_printf(INFO, "Capture Success!\n");
	}else{	
		log_printf( ERR, "Capture Fail! recording_state=%d\n", handle->recording_state);
		retval = 1;
	}


	return retval;
}
示例#6
0
int slogic_set_capture(struct slogic_ctx *handle){
struct libusb_transfer *transfer;
struct slogic_command command;	
int ret,transferred;
	
	transfer = libusb_alloc_transfer(0);

	if (transfer == NULL) {
		log_printf( ERR, "libusb_alloc_transfer failed\n");
		handle->recording_state = UNKNOWN;
		ret = 1;
		return ret;
	}

	command.command = SALEAE_LOGIC_COMMAND_SET_SAMPLE_DELAY;
	command.sample_delay = handle->sample_rate->sample_delay;	

	if((ret = libusb_bulk_transfer(handle->device_handle, SALEAE_COMMAND_OUT_ENDPOINT, (unsigned char *)&command, sizeof(command), &transferred, handle->transfer_timeout))){
		log_printf( ERR, "libusb_bulk_transfer (in): %s\n", usbutil_error_to_string(ret));
		return ret;
	}
	return 0;	
	
}
示例#7
0
int slogic_execute_recording(struct slogic_handle *handle, struct slogic_recording *recording)
{
	/* TODO: validate recording */
	int retval =0;

	struct libusb_transfer *transfer;
	unsigned char *buffer;
	int counter;
	int ret;

	struct slogic_internal_recording *internal_recording = allocate_internal_recording(handle, recording);

	/*
	 * TODO: We probably want to tune the transfer buffer size to a sane
	 * default based on the sampling rate. If transfer_buffer_size is
	 * samples per second / 10 we can expect 10 transfers per second which
	 * should be sufficient for a user application to be responsive while
	 * not having too many transfers per second.
	 *  - Trygve
	 */

	log_printf(&logger, DEBUG, "Starting recording...\n");
	log_printf(&logger, DEBUG, "Transfer buffers:     %d\n", internal_recording->n_transfer_buffers);
	log_printf(&logger, DEBUG, "Transfer buffer size: %zu\n", handle->transfer_buffer_size);
	log_printf(&logger, DEBUG, "Transfer timeout:     %u\n", handle->transfer_timeout);

	/* Pre-allocate transfers */
	for (counter = 0; counter < internal_recording->n_transfer_buffers; counter++) {
		buffer = malloc(handle->transfer_buffer_size);
		assert(buffer);

		transfer = libusb_alloc_transfer(0);
		if (transfer == NULL) {
			log_printf(&logger, ERR, "libusb_alloc_transfer failed\n");
			recording->recording_state = UNKNOWN;
			retval = 1;
			return retval;
		}
		libusb_fill_bulk_transfer(transfer, handle->device_handle,
					  STREAMING_DATA_IN_ENDPOINT, buffer,
					  handle->transfer_buffer_size,
					  slogic_read_samples_callback,
					  &internal_recording->transfers[counter], handle->transfer_timeout);
		internal_recording->transfers[counter].internal_recording = internal_recording;
		internal_recording->transfers[counter].transfer = transfer;
	}

	recording->recording_state = WARMING_UP;
	internal_recording->done = false;

	/* Submit all transfers */
	for (counter = 0; counter < internal_recording->n_transfer_buffers; counter++) {
		internal_recording->transfers[counter].seq = tcounter++;
		ret = libusb_submit_transfer(internal_recording->transfers[counter].transfer);
		if (ret) {
			log_printf(&logger, ERR, "libusb_submit_transfer: %s\n", usbutil_error_to_string(ret));
			recording->recording_state = UNKNOWN;
			retval =1;
			return retval;
		}
	}

	log_printf(&logger, DEBUG, "sample_delay=%d\n", recording->sample_rate->sample_delay);

	struct timeval start;
	assert(gettimeofday(&start, NULL) == 0);

	struct timeval timeout = { 1, 0 };
	while (!internal_recording->done) {
		ret = libusb_handle_events_timeout(handle->context, &timeout);
		if (ret) {
			log_printf(&logger, ERR, "libusb_handle_events: %s\n", usbutil_error_to_string(ret));
			break;
		}
	}

	struct timeval end;
	assert(gettimeofday(&end, NULL) == 0);

	for (counter = 0; counter < internal_recording->n_transfer_buffers; counter++) {
		libusb_cancel_transfer(internal_recording->transfers[counter].transfer);
		libusb_free_transfer(internal_recording->transfers[counter].transfer);
		internal_recording->transfers[counter].transfer = NULL;
	}

	if (internal_recording->recording->recording_state != COMPLETED_SUCCESSFULLY) {
		log_printf(&logger, ERR, "FAIL! recording_state=%d\n", internal_recording->recording->recording_state);
		retval =1;
	} else {
		log_printf(&logger, DEBUG, "SUCCESS!\n");
	}

	log_printf(&logger, DEBUG, "Total number of samples read: %i\n", internal_recording->sample_count);
	log_printf(&logger, DEBUG, "Total number of transfers: %i\n", internal_recording->transfer_counter);

	int sec = end.tv_sec - start.tv_sec;
	int usec = (end.tv_usec - start.tv_usec) / 1000;
	if (usec < 0) {
		sec--;
		usec = 1 - usec;
	}
	log_printf(&logger, DEBUG, "Time elapsed: %d.%03ds\n", sec, usec);

	free_internal_recording(internal_recording);
	return retval;
}
示例#8
0
/*
 * Is some kind of synchronization required here? libusb is not supposed to
 * create its own threads, but I've seen mentions of an event thread in debug
 * output - Trygve
 */
void slogic_read_samples_callback(struct libusb_transfer *transfer)
{
	struct slogic_transfer *slogic_transfer = transfer->user_data;
	struct slogic_internal_recording *internal_recording = slogic_transfer->internal_recording;
	struct slogic_recording *recording = internal_recording->recording;
	assert(slogic_transfer);

	if (internal_recording->done) {
		/*
		 * This will happen if there was more incoming transfers when the
		 * callback wanted to stop recording. The outer method will handle
		 * the cleanup so just return here.
		 */
		return;
	}

	slogic_transfer->internal_recording->transfer_counter++;

	/*
	 * Handle the success as a special case, the failure logic is basically: abort.
	 * Note that this does not indicate that the entire amount of requested data was transferred.
	 */
	if (transfer->status == LIBUSB_TRANSFER_COMPLETED || recording->recording_state == RUNNING) {
		internal_recording->sample_count += transfer->actual_length;

		bool more =
		    recording->on_data_callback(transfer->buffer, transfer->actual_length, recording->user_data);

		if (!more) {
			internal_recording->recording->recording_state = COMPLETED_SUCCESSFULLY;
			internal_recording->done = true;
			log_printf(&logger, DEBUG, "Callback signalled completion\n");
			return;
		}

		int old_seq = slogic_transfer->seq;
		slogic_transfer->seq = tcounter++;
		int ret = libusb_submit_transfer(slogic_transfer->transfer);
		if (ret) {
			log_printf(&logger, ERR, "libusb_submit_transfer: %s\n", usbutil_error_to_string(ret));
			internal_recording->recording->recording_state = UNKNOWN;
			internal_recording->done = true;
			return;
		}

		log_printf(&logger, DEBUG, "Rescheduled transfer %d as %d\n", old_seq, slogic_transfer->seq);
		return;
	}
	
	if (internal_recording->transfer_counter == 200) {
			struct libusb_transfer *transfer;
			unsigned char command[] = { 0x01, recording->sample_rate->sample_delay };
			transfer = libusb_alloc_transfer(0 /* we use bulk */ );
			assert(transfer);
			libusb_fill_bulk_transfer(transfer,
						  internal_recording->shandle->device_handle, 0x01,
						  command, 2, slogic_read_samples_callback_start_log, recording, 40);
			libusb_submit_transfer(transfer);
	}
	if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) {
		if (recording->recording_state == RUNNING){
			slogic_transfer->internal_recording->timeout_counter++;
		}
		if (internal_recording->timeout_counter < 1000){
			slogic_transfer->seq = tcounter++;
			int ret = libusb_submit_transfer(slogic_transfer->transfer);
			if (ret) {
				log_printf(&logger, ERR, "libusb_submit_transfer: %s\n", usbutil_error_to_string(ret));
				internal_recording->recording->recording_state = UNKNOWN;
				internal_recording->done = true;
			}
			return;
		}
	}

	internal_recording->done = true;

	log_printf(&logger, ERR, "Transfer failed: %s\n", usbutil_transfer_status_to_string(transfer->status));

	switch (transfer->status) {
	default:
		/* Make the compiler shut up */
	case LIBUSB_TRANSFER_COMPLETED:
		/*
		 * This shouldn't happen in slogic.
		 * From libusb docs:
		 * For bulk/interrupt endpoints: halt condition detected (endpoint stalled).
		 * For control endpoints: control request not supported.
		 */
	case LIBUSB_TRANSFER_STALL:
		/* We don't cancel transfers without setting should_run = 0 so this should not happen */
	case LIBUSB_TRANSFER_CANCELLED:
	case LIBUSB_TRANSFER_ERROR:
		recording->recording_state = UNKNOWN;
		break;
	case LIBUSB_TRANSFER_TIMED_OUT:
		recording->recording_state = TIMEOUT;
		break;
	case LIBUSB_TRANSFER_NO_DEVICE:
		recording->recording_state = DEVICE_GONE;
		break;
	case LIBUSB_TRANSFER_OVERFLOW:
		recording->recording_state = OVERFLOW;
		break;
	}
}
示例#9
0
/*
 * Iterates over the usb devices on the usb busses and returns a handle to the
 * first device found that matches the predefined vendor and product id
 */
libusb_device_handle *open_device(libusb_context * ctx, int vendor_id, int product_id)
{
	// discover devices
	libusb_device **list;
	libusb_device *found = NULL;
	libusb_device_handle *device_handle = NULL;
	struct libusb_device_descriptor descriptor;

	size_t cnt = libusb_get_device_list(ctx, &list);
	size_t i = 0;
	int err = 0;
	if (cnt < 0) {
		fprintf(stderr, "Failed to get a list of devices\n");
		return NULL;
	}

	for (i = 0; i < cnt; i++) {
		libusb_device *device = list[i];
		err = libusb_get_device_descriptor(device, &descriptor);
		if (err) {
			fprintf(stderr, "libusb_get_device_descriptor: %s\n", usbutil_error_to_string(err));
			libusb_free_device_list(list, 1);
			return NULL;
		}
		if ((descriptor.idVendor == vendor_id) && (descriptor.idProduct == product_id)) {
			found = device;
			usbutil_dump_device_descriptor(stderr, &descriptor);
			break;
		}
	}

	if (!found) {
		fprintf(stderr, "Device not found\n");
		libusb_free_device_list(list, 1);
		return NULL;
	}

	if ((err = libusb_open(found, &device_handle))) {
		fprintf(stderr, "Failed OPEN the device: %s\n", usbutil_error_to_string(err));
		libusb_free_device_list(list, 1);
		return NULL;
	}
	fprintf(stderr, "libusb_open: %s\n", usbutil_error_to_string(err));

	libusb_free_device_list(list, 1);

	if ((err = claim_device(device_handle, 0)) != 0) {
		fprintf(stderr, "Failed to claim the usb interface: %s\n", usbutil_error_to_string(err));
		return NULL;
	}

	struct libusb_config_descriptor *config_descriptor;
	err = libusb_get_active_config_descriptor(found, &config_descriptor);
	if (err) {
		fprintf(stderr, "libusb_get_active_config_descriptor: %s\n", usbutil_error_to_string(err));
		return NULL;
	}
	fprintf(stderr, "Active configuration:%d\n", config_descriptor->bConfigurationValue);
	libusb_free_config_descriptor(config_descriptor);

	fprintf(stderr, "Available configurations (%d):\n", descriptor.bNumConfigurations);
	for (i = 0; i < descriptor.bNumConfigurations; i++) {
		err = libusb_get_config_descriptor(found, i, &config_descriptor);
		if (err) {
			fprintf(stderr, "libusb_get_config_descriptor: %s\n", usbutil_error_to_string(err));
			return NULL;
		}

		usbutil_dump_config_descriptor(stderr, config_descriptor);
		libusb_free_config_descriptor(config_descriptor);
	}

	return device_handle;
}