0

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!

BigMick
  • 595
  • 1
  • 4
  • 7
  • The manual says you need an extra 0xFF padding character at the end. – EmilioPeJu Apr 18 '23 at 12:44
  • Yes, thanks for the hint. However, the 0xFF is only needed for messages with odd length, not for the 8 Bytes I am transmitting. Nevertheless, I gave the additional 0xFF at the end a try, no changes unfortunately. :-/ – BigMick Apr 18 '23 at 13:17
  • Try to capture USB traffic, e.g. with usbmon backend for wireshark. You'll see at least is bulk transferred to USB controller or not. – dimich Apr 19 '23 at 19:12

0 Answers0