Optimize HID code.

This commit is contained in:
Serge Vakulenko 2018-09-17 20:04:17 -07:00
parent f4bb02eea2
commit 2658ffff80
2 changed files with 31 additions and 23 deletions

View File

@ -44,6 +44,7 @@ static const unsigned char CMD_CWB1[] = "CWB\4\0\1\0\0";
static libusb_context *ctx = NULL; // libusb context static libusb_context *ctx = NULL; // libusb context
static libusb_device_handle *dev; // libusb device static libusb_device_handle *dev; // libusb device
static struct libusb_transfer *transfer; // async transfer descriptor
static unsigned char receive_buf[42]; // receive buffer static unsigned char receive_buf[42]; // receive buffer
static volatile int nbytes_received = 0; // receive result static volatile int nbytes_received = 0; // receive result
static unsigned offset = 0; // CWD offset static unsigned offset = 0; // CWD offset
@ -55,13 +56,13 @@ static unsigned offset = 0; // CWD offset
// Callback function for asynchronous receive. // Callback function for asynchronous receive.
// Needs to fill the receive_buf and set nbytes_received. // Needs to fill the receive_buf and set nbytes_received.
// //
static void read_callback(struct libusb_transfer *transfer) static void read_callback(struct libusb_transfer *t)
{ {
switch (transfer->status) { switch (t->status) {
case LIBUSB_TRANSFER_COMPLETED: case LIBUSB_TRANSFER_COMPLETED:
//fprintf(stderr, "%s: Transfer complete, %d bytes\n", __func__, transfer->actual_length); //fprintf(stderr, "%s: Transfer complete, %d bytes\n", __func__, t->actual_length);
memcpy(receive_buf, transfer->buffer, transfer->actual_length); memcpy(receive_buf, t->buffer, t->actual_length);
nbytes_received = transfer->actual_length; nbytes_received = t->actual_length;
break; break;
case LIBUSB_TRANSFER_CANCELLED: case LIBUSB_TRANSFER_CANCELLED:
@ -80,7 +81,7 @@ static void read_callback(struct libusb_transfer *transfer)
break; break;
default: default:
//fprintf(stderr, "%s: Unknown transfer code: %d\n", __func__, transfer->status); //fprintf(stderr, "%s: Unknown transfer code: %d\n", __func__, t->status);
nbytes_received = LIBUSB_ERROR_IO; nbytes_received = LIBUSB_ERROR_IO;
} }
} }
@ -94,12 +95,15 @@ static void read_callback(struct libusb_transfer *transfer)
// //
static int write_read(const unsigned char *data, unsigned length, unsigned char *reply, unsigned rlength) static int write_read(const unsigned char *data, unsigned length, unsigned char *reply, unsigned rlength)
{ {
struct libusb_transfer *transfer = libusb_alloc_transfer(0); if (! transfer) {
// Allocate transfer descriptor on first invocation.
transfer = libusb_alloc_transfer(0);
libusb_fill_interrupt_transfer(transfer, dev,
LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
reply, rlength, read_callback, 0, TIMEOUT_MSEC);
}
again: again:
nbytes_received = 0; nbytes_received = 0;
libusb_fill_interrupt_transfer(transfer, dev,
LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
reply, rlength, read_callback, 0, TIMEOUT_MSEC);
libusb_submit_transfer(transfer); libusb_submit_transfer(transfer);
int result = libusb_control_transfer(dev, int result = libusb_control_transfer(dev,
@ -111,7 +115,6 @@ again:
fprintf(stderr, "Error %d transmitting data via control transfer: %s\n", fprintf(stderr, "Error %d transmitting data via control transfer: %s\n",
result, libusb_strerror(result)); result, libusb_strerror(result));
libusb_cancel_transfer(transfer); libusb_cancel_transfer(transfer);
libusb_free_transfer(transfer);
return -1; return -1;
} }
@ -125,17 +128,17 @@ again:
result != LIBUSB_ERROR_INTERRUPTED) { result != LIBUSB_ERROR_INTERRUPTED) {
fprintf(stderr, "Error %d receiving data via interrupt transfer: %s\n", fprintf(stderr, "Error %d receiving data via interrupt transfer: %s\n",
result, libusb_strerror(result)); result, libusb_strerror(result));
libusb_free_transfer(transfer);
return result; return result;
} }
} }
} }
if (nbytes_received == LIBUSB_ERROR_TIMEOUT) { if (nbytes_received == LIBUSB_ERROR_TIMEOUT) {
//fprintf(stderr, "Timed out!\n"); if (trace_flag > 0) {
fprintf(stderr, "No response from HID device!\n");
}
goto again; goto again;
} }
libusb_free_transfer(transfer);
return nbytes_received; return nbytes_received;
} }
@ -272,6 +275,10 @@ void hid_close()
if (!ctx) if (!ctx)
return; return;
if (transfer) {
libusb_free_transfer(transfer);
transfer = 0;
}
libusb_release_interface(dev, HID_INTERFACE); libusb_release_interface(dev, HID_INTERFACE);
libusb_close(dev); libusb_close(dev);
libusb_exit(ctx); libusb_exit(ctx);

View File

@ -78,7 +78,7 @@ void hid_send_recv(const unsigned char *data, unsigned nbytes, unsigned char *rd
} }
nbytes_received = 0; nbytes_received = 0;
memset(receive_buf, 0, sizeof(receive_buf)); memset(receive_buf, 0, sizeof(receive_buf));
again:
// Write to HID device. // Write to HID device.
IOReturn result = IOHIDDeviceSetReport(dev, kIOHIDReportTypeOutput, 0, buf, sizeof(buf)); IOReturn result = IOHIDDeviceSetReport(dev, kIOHIDReportTypeOutput, 0, buf, sizeof(buf));
if (result != kIOReturnSuccess) { if (result != kIOReturnSuccess) {
@ -87,15 +87,16 @@ void hid_send_recv(const unsigned char *data, unsigned nbytes, unsigned char *rd
} }
// Run main application loop until reply received. // Run main application loop until reply received.
for (k=0; ; k++) { CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, 0);
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, 0); for (k = 0; nbytes_received <= 0; k++) {
if (nbytes_received > 0)
break;
if (k >= 5) {
fprintf(stderr, "HID device stopped responding!\n");
exit(-1);
}
usleep(10000); usleep(10000);
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, 0);
if (k >= 10) {
if (trace_flag > 0) {
fprintf(stderr, "No response from HID device!\n");
}
goto again;
}
} }
if (nbytes_received != sizeof(receive_buf)) { if (nbytes_received != sizeof(receive_buf)) {