Update readme with instructions for darwin

This commit is contained in:
Kyle Lemons
2013-04-07 12:32:53 -07:00
parent 88b4ba82fe
commit 67ecea5706
6 changed files with 93 additions and 15 deletions

View File

@@ -17,6 +17,8 @@ Dependencies
------------
You must first install [libusb-1.0](http://libusb.org/wiki/libusb-1.0). This is pretty straightforward on linux and darwin. The cgo package should be able to find it if you install it in the default manner or use your distribution's package manager. How to tell cgo how to find one installed in a non-default place is beyond the scope of this README.
*Note*: If you are installing this on darwin, you will probably need to run `fixlibusb_darwin.sh /usr/local/lib/libusb-1.0/libusb.h` because of an LLVM incompatibility. It shouldn't break C programs, though I haven't tried it in anger.
Example: lsusb
--------------
The gousb project provides a simple but useful example: lsusb. This binary will list the USB devices connected to your system and various interesting tidbits about them, their configurations, endpoints, etc. To install it, run the following command:

View File

@@ -5,7 +5,7 @@ import "C"
import (
"fmt"
"log"
//"log" // TODO(kevlar): make a logger
"reflect"
"sync"
"time"
@@ -55,7 +55,7 @@ func (d *Device) Reset() error {
}
func (d *Device) Control(rType, request uint8, val, idx uint16, data []byte) (int, error) {
log.Printf("control xfer: %d:%d/%d:%d %x", idx, rType, request, val, string(data))
//log.Printf("control xfer: %d:%d/%d:%d %x", idx, rType, request, val, string(data))
dataSlice := (*reflect.SliceHeader)(unsafe.Pointer(&data))
n := C.libusb_control_transfer(
d.handle,

View File

@@ -42,3 +42,33 @@ var usbErrorString = map[usbError]string{
C.LIBUSB_ERROR_NOT_SUPPORTED: "not supported",
C.LIBUSB_ERROR_OTHER: "unknown error",
}
type TransferStatus uint8
const (
LIBUSB_TRANSFER_COMPLETED TransferStatus = C.LIBUSB_TRANSFER_COMPLETED
LIBUSB_TRANSFER_ERROR TransferStatus = C.LIBUSB_TRANSFER_ERROR
LIBUSB_TRANSFER_TIMED_OUT TransferStatus = C.LIBUSB_TRANSFER_TIMED_OUT
LIBUSB_TRANSFER_CANCELLED TransferStatus = C.LIBUSB_TRANSFER_CANCELLED
LIBUSB_TRANSFER_STALL TransferStatus = C.LIBUSB_TRANSFER_STALL
LIBUSB_TRANSFER_NO_DEVICE TransferStatus = C.LIBUSB_TRANSFER_NO_DEVICE
LIBUSB_TRANSFER_OVERFLOW TransferStatus = C.LIBUSB_TRANSFER_OVERFLOW
)
var transferStatusDescription = map[TransferStatus]string{
LIBUSB_TRANSFER_COMPLETED: "transfer completed without error",
LIBUSB_TRANSFER_ERROR: "transfer failed",
LIBUSB_TRANSFER_TIMED_OUT: "transfer timed out",
LIBUSB_TRANSFER_CANCELLED: "transfer was cancelled",
LIBUSB_TRANSFER_STALL: "halt condition detected (endpoint stalled) or control request not supported",
LIBUSB_TRANSFER_NO_DEVICE: "device was disconnected",
LIBUSB_TRANSFER_OVERFLOW: "device sent more data than requested",
}
func (ts TransferStatus) String() string {
return transferStatusDescription[ts]
}
func (ts TransferStatus) Error() string {
return "libusb: " + ts.String()
}

View File

@@ -5,8 +5,8 @@
void print_xfer(struct libusb_transfer *xfer);
void callback(struct libusb_transfer *xfer) {
printf("Callback!\n");
print_xfer(xfer);
//printf("Callback!\n");
//print_xfer(xfer);
iso_callback(xfer->user_data);
}
@@ -14,7 +14,7 @@ int submit(struct libusb_transfer *xfer) {
xfer->callback = &callback;
xfer->status = -1;
//print_xfer(xfer);
printf("Transfer submitted\n");
//printf("Transfer submitted\n");
/* fake
strcpy(xfer->buffer, "hello");
@@ -47,3 +47,32 @@ void print_xfer(struct libusb_transfer *xfer) {
xfer->iso_packet_desc[i].status);
}
}
int extract_data(struct libusb_transfer *xfer, void *raw, int max, unsigned char *status) {
int i;
int copied = 0;
unsigned char *in = xfer->buffer;
unsigned char *out = raw;
for (i = 0; i < xfer->num_iso_packets; i++) {
struct libusb_iso_packet_descriptor pkt = xfer->iso_packet_desc[i];
// Copy the data
int len = pkt.actual_length;
if (len > max) {
len = max;
}
memcpy(out, in, len);
copied += len;
// Increment offsets
in += pkt.length;
out += len;
// Extract first error
if (pkt.status == 0 || *status != 0) {
continue;
}
*status = pkt.status;
}
return copied;
}

View File

@@ -4,13 +4,14 @@ package usb
#include <libusb-1.0/libusb.h>
int submit(struct libusb_transfer *xfer);
void print_xfer(struct libusb_transfer *xfer);
int extract_data(struct libusb_transfer *xfer, void *data, int max, unsigned char *status);
*/
import "C"
import (
"fmt"
"log"
"reflect"
"time"
"unsafe"
)
@@ -46,15 +47,16 @@ func (end *endpoint) allocTransfer() *Transfer {
xfer.num_iso_packets = iso_packets
C.libusb_set_iso_packet_lengths(xfer, packet_size)
/*
pkts := *(*[]C.struct_libusb_packet_descriptor)(unsafe.Pointer(&reflect.SliceHeader{
Data: uintptr(unsafe.Pointer(&xfer.iso_packet_desc)),
Len: iso_packets,
Cap: iso_packets,
}))
*/
t := &Transfer{
xfer: xfer,
pkts: pkts,
done: done,
buf: buf,
}
@@ -65,13 +67,13 @@ func (end *endpoint) allocTransfer() *Transfer {
type Transfer struct {
xfer *C.struct_libusb_transfer
pkts []C.struct_libusb_packet_descriptor
pkts []*C.struct_libusb_packet_descriptor
done chan struct{}
buf []byte
}
func (t *Transfer) Submit(timeout time.Duration) error {
log.Printf("iso: submitting %#v", t.xfer)
//log.Printf("iso: submitting %#v", t.xfer)
t.xfer.timeout = C.uint(timeout / time.Millisecond)
if errno := C.submit(t.xfer); errno < 0 {
return usbError(errno)
@@ -85,12 +87,27 @@ func (t *Transfer) Wait(b []byte) (n int, err error) {
return 0, fmt.Errorf("wait timed out after 10s")
case <-t.done:
}
n = int(t.xfer.actual_length)
copy(b, ((*[1 << 16]byte)(unsafe.Pointer(t.xfer.buffer)))[:n])
// Non-iso transfers:
//n = int(t.xfer.actual_length)
//copy(b, ((*[1 << 16]byte)(unsafe.Pointer(t.xfer.buffer)))[:n])
//C.print_xfer(t.xfer)
/*
for i, pkt := range t.pkts {
log.Printf("PACKET[%4d] - %#v", i, pkt)
}*/
buf, offset := ((*[1 << 16]byte)(unsafe.Pointer(t.xfer.buffer))), 0
for i, pkt := range *t.pkts {
log.Printf("Type is %T", t.pkts)
n += copy(b[n:], buf[offset:][:pkt.actual_length])
offset += pkt.Length
if pkt.status != 0 && err == nil {
err = error(TransferStatus(pkt.status))
}
}
*/
var status uint8
n = int(C.extract_data(t.xfer, unsafe.Pointer(&b[0]), C.int(len(b)), (*C.uchar)(unsafe.Pointer(&status))))
if status != 0 {
err = TransferStatus(status)
}
return n, err
}

View File

@@ -39,7 +39,7 @@ func NewContext() *Context {
log.Printf("handle_events: error: %s", usbError(errno))
continue
}
log.Printf("handle_events returned")
//log.Printf("handle_events returned")
}
}()