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