mdebug

cortex m series debugger
git clone http://frotz.net/git/mdebug.git
Log | Files | Refs | README | LICENSE

usb.c (2926B)


      1 /* usb.c
      2  *
      3  * Copyright 2014 Brian Swetland <swetland@frotz.net>
      4  * 
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 #include <stdlib.h>
     19 #include <stdio.h>
     20 
     21 #include <libusb-1.0/libusb.h>
     22 
     23 #include "usb.h"
     24 
     25 struct usb_handle {
     26 	libusb_device_handle *dev;
     27 	unsigned ei;
     28 	unsigned eo;
     29 };
     30 
     31 static libusb_context *usb_ctx = NULL;
     32 
     33 usb_handle *usb_open(unsigned vid, unsigned pid, unsigned ifc) {
     34 	usb_handle *usb;
     35 	int r;
     36 
     37 	if (usb_ctx == NULL) {
     38 		if (libusb_init(&usb_ctx) < 0) {
     39 			usb_ctx = NULL;
     40 			return NULL;
     41 		}
     42 	}
     43 
     44 	usb = malloc(sizeof(usb_handle));
     45 	if (usb == 0) {
     46 		return NULL;
     47 	}
     48 
     49 	/* TODO: extract from descriptors */
     50 	switch (ifc) {
     51 	case 0:
     52 		usb->ei = 0x81;
     53 		usb->eo = 0x01;
     54 		break;
     55 	case 1:
     56 		usb->ei = 0x82;
     57 		usb->eo = 0x02;
     58 		break;
     59 	default:
     60 		goto fail;
     61 	}
     62 
     63 	usb->dev = libusb_open_device_with_vid_pid(usb_ctx, vid, pid);
     64 	if (usb->dev == NULL) {
     65 		goto fail;
     66 	}
     67 	// This causes problems on re-attach.  Maybe need for OSX?
     68 	// On Linux it's completely happy without us explicitly setting a configuration.
     69 	//r = libusb_set_configuration(usb->dev, 1);
     70 	r = libusb_claim_interface(usb->dev, ifc);
     71 	if (r < 0) {
     72 		fprintf(stderr, "failed to claim interface #%d\n", ifc);
     73 		goto close_fail;
     74 	}
     75 
     76 #ifdef __APPLE__
     77 	// make sure everyone's data toggles agree
     78 	// makes things worse on Linux, but happy on OSX
     79 	libusb_clear_halt(usb->dev, usb->ei);
     80 	libusb_clear_halt(usb->dev, usb->eo);
     81 #endif
     82 
     83 	return usb;
     84 
     85 close_fail:
     86 	libusb_close(usb->dev);
     87 fail:
     88 	free(usb);
     89 	return NULL;
     90 }
     91 
     92 void usb_close(usb_handle *usb) {
     93 	libusb_close(usb->dev);
     94 	free(usb);
     95 }
     96 
     97 int usb_ctrl(usb_handle *usb, void *data,
     98 	uint8_t typ, uint8_t req, uint16_t val, uint16_t idx, uint16_t len) {
     99 	int r = libusb_control_transfer(usb->dev, typ, req, val, idx, data, len, 5000);
    100 	if (r < 0) {
    101 		return -1;
    102 	} else {
    103 		return r;
    104 	}
    105 }
    106 
    107 int usb_read(usb_handle *usb, void *data, int len) {
    108 	int xfer = len;
    109 	int r = libusb_bulk_transfer(usb->dev, usb->ei, data, len, &xfer, 5000);
    110 	if (r < 0) {
    111 		return -1;
    112 	}
    113 	return xfer;
    114 }
    115 
    116 int usb_read_forever(usb_handle *usb, void *data, int len) {
    117 	int xfer = len;
    118 	int r = libusb_bulk_transfer(usb->dev, usb->ei, data, len, &xfer, 0);
    119 	if (r < 0) {
    120 		return -1;
    121 	}
    122 	return xfer;
    123 }
    124 
    125 int usb_write(usb_handle *usb, const void *data, int len) {
    126 	int xfer = len;
    127 	int r = libusb_bulk_transfer(usb->dev, usb->eo, (void*) data, len, &xfer, 5000);
    128 	if (r < 0) {
    129 		return -1;
    130 	}
    131 	return xfer;
    132 }
    133