I am trying to communicate with an ICOM R8600 radio receiver via USB, more specifically with its I/Q USB output port (vendor ID 0x0c26, product ID 0x0022). This port is documented quite well in an ICOM manual:
https://www.icomjapan.com/support/manual/1769/
Attached to my Linux computer, lsusb -v -d 0c26:0022
results in the following output:
Bus 003 Device 002: ID 0c26:0022 Prolific Technology Inc.
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 2.00
bDeviceClass 255 Vendor Specific Class
bDeviceSubClass 255 Vendor Specific Subclass
bDeviceProtocol 255 Vendor Specific Protocol
bMaxPacketSize0 64
idVendor 0x0c26 Prolific Technology Inc.
idProduct 0x0022
bcdDevice 0.00
iManufacturer 0
iProduct 0
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 0x00ab
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 1
bNumEndpoints 6
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x88 EP 8 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 2
bNumEndpoints 6
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x88 EP 8 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 3
bNumEndpoints 6
bInterfaceClass 255 Vendor Specific Class
bInterfaceSubClass 255 Vendor Specific Subclass
bInterfaceProtocol 255 Vendor Specific Protocol
iInterface 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x04 EP 4 OUT
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x86 EP 6 IN
bmAttributes 1
Transfer Type Isochronous
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 1
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x88 EP 8 IN
bmAttributes 2
Transfer Type Bulk
Synch Type None
Usage Type Data
wMaxPacketSize 0x0200 1x 512 bytes
bInterval 0
Device Qualifier (for other device speed):
bLength 10
bDescriptorType 6
bcdUSB 2.00
bDeviceClass 255 Vendor Specific Class
bDeviceSubClass 255 Vendor Specific Subclass
bDeviceProtocol 255 Vendor Specific Protocol
bMaxPacketSize0 64
bNumConfigurations 1
Device Status: 0x0000
(Bus Powered)
I tried to access this device using libusb on Linux, however, the bulk transfer to issue a control command (to endpoint 02 with ICOM's CI-V syntax) always times out.
This is a minimal example I used for testing:
#include <cstdlib>
#include <cstdio>
#include <unistd.h>
#include <libusb.h>
static const uint16_t s_vendor_id = 0x0c26;
static const uint16_t s_product_id = 0x0022;
int main(int argc, char* argv[])
{
int rv = 0;
// Initialize libusb and open device
if (libusb_init(nullptr) != 0)
{
fprintf(stderr, "Error initilizing libUSB\n");
return EXIT_FAILURE;
}
//libusb_set_debug(nullptr, LIBUSB_LOG_LEVEL_DEBUG);
libusb_device_handle *handle = libusb_open_device_with_vid_pid (nullptr, s_vendor_id, s_product_id);
if (!handle)
{
printf("Unable to open USB device with vendor id %04X and product id %04X\n", s_vendor_id, s_product_id);
return EXIT_FAILURE;
}
printf("ICOM R8600 opened successfully!\n");
// Claim interface 0 and use alternative setting #1
const int interface_number = 0;
if (libusb_kernel_driver_active(handle, interface_number) > 0)
{
// Detach kernel driver if ncccessary
rv = libusb_detach_kernel_driver(handle, interface_number);
printf("Kernel driver was active, libusb_detach_kernel_driver returned %d (%s)\n", rv, libusb_strerror(rv));
}
rv = libusb_claim_interface(handle, 0);
printf("libusb_claim_interface returned %d (%s)\n", rv, libusb_strerror(rv));
rv = libusb_set_interface_alt_setting(handle, 0, 1);
printf("libusb_set_interface_alt_setting returned %d (%s)\n", rv, libusb_strerror(rv));
printf("Interface 0 and alt setting 1 selected!\n");
// Send a control command to address 0x02 (EP 02 OUT)
unsigned char request[8] = {0xFE, 0xFE, 0x96, 0xE0, 0x1A, 0x13, 0x00, 0xFD}; // Read the I/Q mode status
unsigned char endpoint = 0x02;
rv = libusb_clear_halt(handle, endpoint);// Clear any halt/stall for this endpoint
printf("libusb_clear_halt returned %d (%s)\n", rv, libusb_strerror(rv));
int bytes = 0;
rv = libusb_bulk_transfer(handle, endpoint, request, 8, &bytes, 10000);
if (rv == 0)
printf("libusb_bulk_transfer succeeded with %d bytes transferred...\n", bytes);
else
printf("libusb_bulk_transfer failed with code %d (%s)\n", rv, libusb_strerror(rv));
// Clean up
libusb_release_interface(handle, interface_number);
libusb_close(handle);
return EXIT_SUCCESS;
}
The output of this application is as follows:
> ./usb_mwe
Device opened successfully!
libusb_claim_interface returned 0 (Success)
libusb_set_interface_alt_setting returned 0 (Success)
Interface 0 and alt setting 1 selected!
libusb_clear_halt returned 0 (Success)
libusb_bulk_transfer failed with code -7 (Operation timed out)
Does anybody know what I am doing wrong here, or what I am missing?
Thank you very much for any help, this is highly appreciated!