USB Bulk transfer over Arduino Due Native USB port

Hi.
I am trying to setup a minimal sketch to setup an USB interface with two bulk endpoints (IN and OUT) with 512 Byte max packet size, and perform a read operation from the host (using the PyUSB libusb wrapper in linux)

I've looked at some custom USB implementation based on PluggableUSB class inheritance such as ArduinoMIDI.

I understand that the framework core files will automatically configure the Arduino as a CDC device that supports SerialUSB features, Which means that I will have to declare a USB interface number just after those exposed by the already present CDC interface.

Here is the full code.

#undef CDC_ENABLED // this is a test to try do disable inbuilt CDC (CDC.cpp) SerialUSB
// support


#include <Arduino.h>
#include <USBCore.h>
#include <USBCore.cpp>
#include <PluggableUSB.h>

#define STRID_LANGID 0
#define STRID_MANUFACTURER 1
#define STRID_PRODUCT 2
#define STRID_SERIAL 3

// Unique Vendor/Product IDs
//#define VENDOR_ID  0x2341   // Example: Arduino
//#define PRODUCT_ID 0x8008   // Example: custom device

// Endpoint parameters
#define BULK_IN_EP  1
#define BULK_OUT_EP 2
#define EP_SIZE     512      // Full-speed max bulk size



class MyUSBDevice : public PluggableUSBModule {
public:
    MyUSBDevice() : PluggableUSBModule(epsnum, ifsnum, epType) {
        //epType[0] = USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_IN(1);
        //epType[1] = USB_ENDPOINT_TYPE_BULK | USB_ENDPOINT_OUT(3);
        epType[0] = EP_TYPE_BULK_IN;
        epType[1] = EP_TYPE_BULK_OUT;
        

        PluggableUSB().plug(this);
    }

    int getInterface(uint8_t* interfaceCount) override {

        uint8_t interfaceDescriptor[] = {    
            9,                  // bLength
            USB_INTERFACE_DESCRIPTOR_TYPE, 
            2,    // bInterfaceNumber
            0,                  // bAlternateSetting
            2,                  // bNumEndpoints
            0xFF,               // bInterfaceClass (vendor-specific = 0xFF)
            0x00,               // bInterfaceSubClass
            0x00,               // bInterfaceProtocol
            2,                   // iInterface
            //FIRST ENDPOINT IN
            0x07, // bLength
            0x05, // bDescriptorType = ENDPOINT
            0x84, // bEndPointAddress = IN endpoint 1
            0x02, // bmAttributes = Bulk
            0x00, 0x02, // wMaxPacketSize = 512 Bytes
            0x00, // bInterval (ignored for Bulk)
            //SECOND ENDPOINT OUT
            0x07, // bLength
            0x05, // bDescriptorType = ENDPOINT
            0x03, // bEndPointAddress = OUT endpoint 1
            0x02, // bmAttributes = Bulk
            0x00, 0x02, // wMaxPacketSize = 512 Bytes
            0x00 // bInterval (ignored for Bulk)
        };
        *interfaceCount += 1;
        return USBD_SendControl(0,interfaceDescriptor, sizeof(interfaceDescriptor));
    }

  
    static void sendStringDescriptor(uint8_t index)
    {
      
      switch(index)
      {
        case STRID_LANGID:
        USB_SendStringDescriptor(USB_StringDescriptor0,sizeof(USB_StringDescriptor0));
        break;
        case STRID_MANUFACTURER:
        USB_SendStringDescriptor(USB_StringDescriptor1,sizeof(USB_StringDescriptor1));
        break;
        case STRID_PRODUCT:
        USB_SendStringDescriptor(USB_StringDescriptor2,sizeof(USB_StringDescriptor2));
        break;
        case STRID_SERIAL:
        USB_SendStringDescriptor(USB_StringDescriptor3,sizeof(USB_StringDescriptor3));
        break;
        default:
        USBD_SendControl(0,nullptr,0); 
      }
    }

    int getDescriptor(USBSetup& setup) override {
        // Optionally return string descriptors or report IDs
        //uint8_t descType = setup.wValueH >> 8;
        //uint8_t descIndex = setup.wValueH & 0xFF;
        
        //switch(descType)
        //{
        //  case USB_DEVICE_DESCRIPTOR_TYPE:
        //  return false;
        //  case USB_CONFIGURATION_DESCRIPTOR_TYPE:
        //  return false;
        //  case USB_STRING_DESCRIPTOR_TYPE:
        //  sendStringDescriptor(descIndex);
        //  return true;
        //  default:
        //  return false;
        //}

        return 0;
    }

    bool setup(USBSetup& setup) override {
        return false;
    }


    // Send data to host
    int sendData(const uint8_t* data, int len) {

        return USBD_Send(0x84, data, len);
    		        
    }


    // Send data to host
    int receiveData(const uint8_t* data) {
		uint32_t c;
		if (!USBD_Available(0x03)) {
			udd_ack_fifocon(0x03);
			return 0;
		}
		c = USBD_Recv(0x03);
        return c;
    }

private:
    uint32_t epType[2];
    uint8_t epsnum = 2;
    uint8_t ifsnum = 2;

    static constexpr uint8_t USB_StringDescriptor0[4] = {4,3,0x09,0x04};
    static constexpr uint8_t USB_StringDescriptor1[7] = {'C','O','M','P','A','N','Y'};
    static constexpr uint8_t USB_StringDescriptor2[6] = {'D','E','V','I','C','E'};
    static constexpr uint8_t USB_StringDescriptor3[6] = {'1','2','3','4','5','6'};
  

};

// Instantiate device
MyUSBDevice myUSB;

void setup() {
    //SerialUSB.end();
    USBD_InitControl(0);
    //SerialUSB.begin(9600); // optional debug over USB CDC
    //while (!SerialUSB) ; // wait for host
    //SerialUSB.println("Custom USB device starting...");
    pinMode(LED_BUILTIN, OUTPUT);
    digitalWrite(LED_BUILTIN, HIGH);
    delay(3000); // 10 Hz
    
        
}

void loop() {
    // Example: send 64 bytes periodically
    char buffer[EP_SIZE];
    for (int i = 0; i < EP_SIZE; i++) buffer[i] = 'z';
    digitalWrite(LED_BUILTIN, LOW);
    delay(1000); // 10 Hz
    int r = myUSB.sendData((uint8_t*)buffer, EP_SIZE);
    //int c = myUSB.receiveData((uint8_t*)buffer);

    
    digitalWrite(LED_BUILTIN, HIGH);
    delay(1000); // 10 Hz
  
}

It seems that a custom implementation of PluggableUSB GetInterface callback is critical as it exposes the USB interface descriptor to the host during USB connection/enumeration.
Without that dmesg complains. With it, interface is properly exposed and the host sees it.

As for GetDescriptor(USBSetup &setup) and Setup(USBSetup &setup), they seem to be optional for using standard bulk endpoints. USBMidi does not use them.

Obviously SendData() and ReceiveData() are required to send Bulk data, and they wrap
USBD_Send() and USBD_Recv() respectively.

The sketch blocks on USBD_Send(0x84, data, len);
Which is expected as it waits for an URB "IN" message to send the data.

Now this is the code that performs the read on the host :

import usb.core
import usb.util

# Find your device (replace with your VID and PID)
dev = usb.core.find(idVendor=0x2341, idProduct=0x003e)  
#dev = usb.core.find(idVendor=0x03eb, idProduct=0x6124)  
if dev is None:
    raise ValueError("Device not found")

# Detach kernel driver if necessary
if dev.is_kernel_driver_active(1):
    dev.detach_kernel_driver(1)

if dev.is_kernel_driver_active(2):
    dev.detach_kernel_driver(2)
# Set configuration
dev.set_configuration()

# Get endpoint (assuming bulk IN is endpoint 0x81)
cfg = dev.get_active_configuration()
#print(cfg)

intf = cfg[(2,0)]
print(intf)

ep = usb.util.find_descriptor(
    intf,
    custom_match=lambda e: 
        usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN
)
epout = usb.util.find_descriptor(
    intf,
    custom_match=lambda e: 
        usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_OUT
)


print(epout.bEndpointAddress)
print(epout.wMaxPacketSize)
print(ep.bEndpointAddress)
print(ep.wMaxPacketSize)

# Poll loop
while True:
    print("loop")
    try:
        data = dev.read(ep.bEndpointAddress, 1, timeout=1000)
        print("DATA=\n")
        print(data)
    except usb.core.USBError as e:
        if e.errno == 110:  # timeout
            continue
        else:
            raise

This is the result of the command LIBUSB_DEBUG=4 python3 testusb.py
The test involves a read operation of 1 byte length, but it behaves the same if the length is USB maxpacketsize = 512

timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
[ 0.000031] [0000b109] libusb: debug [libusb_init] created default context
[ 0.000045] [0000b109] libusb: debug [libusb_init] libusb v1.0.24.11584
[ 0.000057] [0000b109] libusb: debug [get_kernel_version] reported kernel version is 5.10.0-32-rt-amd64
[ 0.000084] [0000b109] libusb: debug [op_init] found usbfs at /dev/bus/usb
[ 0.000093] [0000b109] libusb: debug [op_init] max iso packet length is (likely) 98304 bytes
[ 0.000114] [0000b109] libusb: debug [op_init] sysfs is available
[ 0.000573] [0000b10b] libusb: debug [linux_udev_event_thread_main] udev event thread entering
[ 0.004691] [0000b109] libusb: debug [linux_get_device_address] getting address for device: usb1 detached: 0
[ 0.004705] [0000b109] libusb: debug [linux_get_device_address] scan usb1
[ 0.004758] [0000b109] libusb: debug [linux_get_device_address] bus=1 dev=1
[ 0.004767] [0000b109] libusb: debug [linux_enumerate_device] busnum 1 devaddr 1 session_id 257
[ 0.004777] [0000b109] libusb: debug [linux_enumerate_device] allocating new device for 1/1 (session 257)
[ 0.004939] [0000b109] libusb: debug [linux_get_device_address] getting address for device: 1-1 detached: 0
[ 0.004953] [0000b109] libusb: debug [linux_get_device_address] scan 1-1
[ 0.005002] [0000b109] libusb: debug [linux_get_device_address] bus=1 dev=2
[ 0.005011] [0000b109] libusb: debug [linux_enumerate_device] busnum 1 devaddr 2 session_id 258
[ 0.005021] [0000b109] libusb: debug [linux_enumerate_device] allocating new device for 1/2 (session 258)
[ 0.005068] [0000b109] libusb: debug [linux_get_parent_info] dev 0x55b7f11895b0 (1-1) has parent 0x55b7f11894c0 (usb1) port 1
[ 0.005177] [0000b109] libusb: debug [linux_get_device_address] getting address for device: 1-1.1 detached: 0
[ 0.005187] [0000b109] libusb: debug [linux_get_device_address] scan 1-1.1
[ 0.005228] [0000b109] libusb: debug [linux_get_device_address] bus=1 dev=3
[ 0.005235] [0000b109] libusb: debug [linux_enumerate_device] busnum 1 devaddr 3 session_id 259
[ 0.005245] [0000b109] libusb: debug [linux_enumerate_device] allocating new device for 1/3 (session 259)
[ 0.005299] [0000b109] libusb: debug [linux_get_parent_info] dev 0x55b7f1189810 (1-1.1) has parent 0x55b7f11895b0 (1-1) port 1
[ 0.005404] [0000b109] libusb: debug [linux_get_device_address] getting address for device: usb2 detached: 0
[ 0.005415] [0000b109] libusb: debug [linux_get_device_address] scan usb2
[ 0.005462] [0000b109] libusb: debug [linux_get_device_address] bus=2 dev=1
[ 0.005470] [0000b109] libusb: debug [linux_enumerate_device] busnum 2 devaddr 1 session_id 513
[ 0.005477] [0000b109] libusb: debug [linux_enumerate_device] allocating new device for 2/1 (session 513)
[ 0.005616] [0000b109] libusb: debug [linux_get_device_address] getting address for device: 2-1 detached: 0
[ 0.005627] [0000b109] libusb: debug [linux_get_device_address] scan 2-1
[ 0.005674] [0000b109] libusb: debug [linux_get_device_address] bus=2 dev=2
[ 0.005682] [0000b109] libusb: debug [linux_enumerate_device] busnum 2 devaddr 2 session_id 514
[ 0.005688] [0000b109] libusb: debug [linux_enumerate_device] allocating new device for 2/2 (session 514)
[ 0.005736] [0000b109] libusb: debug [linux_get_parent_info] dev 0x55b7f1189e60 (2-1) has parent 0x55b7f1189f60 (usb2) port 1
[ 0.005887] [0000b109] libusb: debug [linux_get_device_address] getting address for device: 2-1.1 detached: 0
[ 0.005899] [0000b109] libusb: debug [linux_get_device_address] scan 2-1.1
[ 0.005949] [0000b109] libusb: debug [linux_get_device_address] bus=2 dev=24
[ 0.005958] [0000b109] libusb: debug [linux_enumerate_device] busnum 2 devaddr 24 session_id 536
[ 0.005970] [0000b109] libusb: debug [linux_enumerate_device] allocating new device for 2/24 (session 536)
[ 0.006017] [0000b109] libusb: debug [linux_get_parent_info] dev 0x55b7f116f6d0 (2-1.1) has parent 0x55b7f1189e60 (2-1) port 1
[ 0.006134] [0000b109] libusb: debug [linux_get_device_address] getting address for device: 2-1.2 detached: 0
[ 0.006144] [0000b109] libusb: debug [linux_get_device_address] scan 2-1.2
[ 0.006194] [0000b109] libusb: debug [linux_get_device_address] bus=2 dev=38
[ 0.006202] [0000b109] libusb: debug [linux_enumerate_device] busnum 2 devaddr 38 session_id 550
[ 0.006212] [0000b109] libusb: debug [linux_enumerate_device] allocating new device for 2/38 (session 550)
[ 0.006260] [0000b109] libusb: debug [linux_get_parent_info] dev 0x55b7f116faf0 (2-1.2) has parent 0x55b7f1189e60 (2-1) port 2
[ 0.006353] [0000b109] libusb: debug [usbi_add_event_source] add fd 5 events 1
[ 0.006369] [0000b109] libusb: debug [usbi_io_init] using timer for timeouts
[ 0.006378] [0000b109] libusb: debug [usbi_add_event_source] add fd 6 events 1
[ 0.006492] [0000b109] libusb: debug [libusb_get_device_list]  
[ 0.006613] [0000b109] libusb: debug [libusb_get_device_descriptor]  
[ 0.006881] [0000b109] libusb: debug [libusb_open] open 2.38
[ 0.006921] [0000b109] libusb: debug [usbi_add_event_source] add fd 7 events 4
[ 0.006953] [0000b109] libusb: debug [libusb_kernel_driver_active] interface 1
[ 0.006990] [0000b109] libusb: debug [libusb_detach_kernel_driver] interface 1
[ 0.007225] [0000b109] libusb: debug [libusb_kernel_driver_active] interface 2
[ 0.007277] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.007291] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.007406] [0000b109] libusb: debug [libusb_set_configuration] configuration 1
[ 0.007610] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.007630] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.007751] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.007767] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.008119] [0000b109] libusb: debug [libusb_alloc_transfer] transfer 0x55b7f1132388
[ 0.008135] [0000b109] libusb: debug [libusb_submit_transfer] transfer 0x55b7f1132388
[ 0.008144] [0000b109] libusb: debug [add_to_flying_list] arm timer for timeout in 1000ms (first in line)
[ 0.008177] [0000b109] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.008189] [0000b109] libusb: debug [handle_events] event sources modified, reallocating event data
[ 0.008201] [0000b109] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ 0.008299] [0000b109] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 0.008319] [0000b109] libusb: debug [reap_for_handle] urb type=2 status=0 transferred=4
[ 0.008328] [0000b109] libusb: debug [handle_control_completion] handling completion status 0
[ 0.008337] [0000b109] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer
[ 0.008351] [0000b109] libusb: debug [usbi_handle_transfer_completion] transfer 0x55b7f1132388 has callback 0x7fe6365dedc0
[ 0.008360] [0000b109] libusb: debug [sync_transfer_cb] actual_length=4
[ 0.008371] [0000b109] libusb: debug [libusb_free_transfer] transfer 0x55b7f1132388
[ 0.008473] [0000b109] libusb: debug [libusb_alloc_transfer] transfer 0x55b7f1187a38
[ 0.008488] [0000b109] libusb: debug [libusb_submit_transfer] transfer 0x55b7f1187a38
[ 0.008497] [0000b109] libusb: debug [add_to_flying_list] arm timer for timeout in 1000ms (first in line)
[ 0.008518] [0000b109] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.008528] [0000b109] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ 0.008671] [0000b109] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 0.008689] [0000b109] libusb: debug [reap_for_handle] urb type=2 status=0 transferred=24
[ 0.008697] [0000b109] libusb: debug [handle_control_completion] handling completion status 0
[ 0.008706] [0000b109] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer
[ 0.008717] [0000b109] libusb: debug [usbi_handle_transfer_completion] transfer 0x55b7f1187a38 has callback 0x7fe6365dedc0
[ 0.008725] [0000b109] libusb: debug [sync_transfer_cb] actual_length=24
[ 0.008735] [0000b109] libusb: debug [libusb_free_transfer] transfer 0x55b7f1187a38
[ 0.009733] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.009796] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.009966] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.009980] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
    INTERFACE 2: Vendor Specific ===========================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x2
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x2
     bInterfaceClass    :   0xff Vendor Specific
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x2 Arduino Due
      ENDPOINT 0x84: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x84 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :  0x200 (512 bytes)
       bInterval        :    0x0
      ENDPOINT 0x3: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x3 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :  0x200 (512 bytes)
       bInterval        :    0x0
[ 0.010197] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.010209] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.010319] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.010332] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.010414] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.010426] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
3
512
132
512
loop
[ 0.010603] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.010619] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.010730] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.010740] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.010854] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.010864] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.010983] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.010993] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.011066] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.011077] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.011182] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.011192] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.011299] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.011309] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.011446] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.011458] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.011534] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.011545] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.011652] [0000b109] libusb: debug [libusb_get_config_descriptor] index 0
[ 0.011663] [0000b109] libusb: debug [parse_configuration] skipping descriptor 0xb
[ 0.011801] [0000b109] libusb: debug [libusb_claim_interface] interface 2
[ 0.011930] [0000b109] libusb: debug [libusb_alloc_transfer] transfer 0x55b7f116f298
[ 0.011941] [0000b109] libusb: debug [libusb_submit_transfer] transfer 0x55b7f116f298
[ 0.011947] [0000b109] libusb: debug [add_to_flying_list] arm timer for timeout in 1000ms (first in line)
[ 0.011958] [0000b109] libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 1
[ 0.011986] [0000b109] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.011993] [0000b109] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ 0.016064] [0000b109] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 0.016103] [0000b109] libusb: debug [reap_for_handle] urb type=3 status=-71 transferred=0
[ 0.016111] [0000b109] libusb: debug [handle_bulk_completion] handling completion status -71 of bulk urb 1/1
[ 0.016117] [0000b109] libusb: debug [handle_bulk_completion] low-level bus error -71
[ 0.016125] [0000b109] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer
[ 0.016134] [0000b109] libusb: debug [usbi_handle_transfer_completion] transfer 0x55b7f116f298 has callback 0x7fe6365dedc0
[ 0.016140] [0000b109] libusb: debug [sync_transfer_cb] actual_length=0
[ 0.016150] [0000b109] libusb: debug [libusb_free_transfer] transfer 0x55b7f116f298
Traceback (most recent call last):
  File "/home/rod/Documents/PlatformIO/Projects/ad7606_arduino/src/testusb.py", line 49, in <module>
    data = dev.read(ep.bEndpointAddress, 1, timeout=1000)
  File "/root/anaconda3/lib/python3.9/site-packages/usb/core.py", line 1043, in read
    ret = fn(
  File "/root/anaconda3/lib/python3.9/site-packages/usb/backend/libusb1.py", line 850, in bulk_read
    return self.__read(self.lib.libusb_bulk_transfer,
  File "/root/anaconda3/lib/python3.9/site-packages/usb/backend/libusb1.py", line 958, in __read
    _check(retval)
  File "/root/anaconda3/lib/python3.9/site-packages/usb/backend/libusb1.py", line 604, in _check
    raise USBError(_strerror(ret), ret, _libusb_errno[ret])
usb.core.USBError: [Errno 5] Input/Output Error
[ 0.019599] [0000b109] libusb: debug [libusb_release_interface] interface 2
[ 0.019701] [0000b109] libusb: debug [libusb_close]  
[ 0.019724] [0000b109] libusb: debug [usbi_remove_event_source] remove fd 7
[ 0.019805] [0000b109] libusb: debug [libusb_exit]  
[ 0.019815] [0000b109] libusb: debug [libusb_exit] destroying default context
[ 0.019835] [0000b109] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.019849] [0000b109] libusb: debug [handle_events] event sources modified, reallocating event data
[ 0.019868] [0000b109] libusb: debug [usbi_wait_for_events] poll() 2 fds with timeout in 0ms
[ 0.019886] [0000b109] libusb: debug [usbi_wait_for_events] poll() returned 0
[ 0.019899] [0000b109] libusb: debug [libusb_unref_device] destroy device 2.38
[ 0.019915] [0000b109] libusb: debug [libusb_unref_device] destroy device 2.24
[ 0.019936] [0000b109] libusb: debug [libusb_unref_device] destroy device 2.2
[ 0.019948] [0000b109] libusb: debug [libusb_unref_device] destroy device 2.1
[ 0.019963] [0000b109] libusb: debug [libusb_unref_device] destroy device 1.3
[ 0.019979] [0000b109] libusb: debug [libusb_unref_device] destroy device 1.2
[ 0.019988] [0000b109] libusb: debug [libusb_unref_device] destroy device 1.1
[ 0.019997] [0000b109] libusb: debug [usbi_remove_event_source] remove fd 6
[ 0.020015] [0000b109] libusb: debug [usbi_remove_event_source] remove fd 5
[ 0.020043] [0000b10b] libusb: debug [linux_udev_event_thread_main] udev event thread exiting

The error is a USB protocol error -71. These are the error relevant lines.

0.017488] [0000b13e] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ 0.021526] [0000b13e] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 0.021558] [0000b13e] libusb: debug [reap_for_handle] urb type=3 status=-71 transferred=0
[ 0.021571] [0000b13e] libusb: debug [handle_bulk_completion] handling completion status -71 of bulk urb 1/1
[ 0.021583] [0000b13e] libusb: debug [handle_bulk_completion] low-level bus error -71

And this is the Interface as seen in PyUSB :

    INTERFACE 2: Vendor Specific ===========================
     bLength            :    0x9 (9 bytes)
     bDescriptorType    :    0x4 Interface
     bInterfaceNumber   :    0x2
     bAlternateSetting  :    0x0
     bNumEndpoints      :    0x2
     bInterfaceClass    :   0xff Vendor Specific
     bInterfaceSubClass :    0x0
     bInterfaceProtocol :    0x0
     iInterface         :    0x2 Arduino Due
      ENDPOINT 0x84: Bulk IN ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :   0x84 IN
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :  0x200 (512 bytes)
       bInterval        :    0x0
      ENDPOINT 0x3: Bulk OUT ===============================
       bLength          :    0x7 (7 bytes)
       bDescriptorType  :    0x5 Endpoint
       bEndpointAddress :    0x3 OUT
       bmAttributes     :    0x2 Bulk
       wMaxPacketSize   :  0x200 (512 bytes)
       bInterval        :    0x0

And system wide in /sys/kernel/debug/usb/devices

T:  Bus=02 Lev=02 Prnt=02 Port=01 Cnt=02 Dev#= 38 Spd=480  MxCh= 0
D:  Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs=  1
P:  Vendor=2341 ProdID=003e Rev= 1.00
S:  Manufacturer=Arduino
S:  Product=Arduino Due
S:  SerialNumber=C
C:* #Ifs= 3 Cfg#= 1 Atr=c0 MxPwr=500mA
A:  FirstIf#= 0 IfCount= 2 Cls=02(comm.) Sub=02 Prot=01
I:* If#= 0 Alt= 0 #EPs= 1 Cls=02(comm.) Sub=02 Prot=00 Driver=(none)
E:  Ad=81(I) Atr=03(Int.) MxPS=  16 Ivl=4096ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=(none)
E:  Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=00 Prot=00 Driver=(none)
E:  Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms
E:  Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms

Any ideas on how to make the transfer work ? I mostly think that the error is on the Arduino Due firmware code side, as when i try to read using the interface 1 (CDC SerialUsb) there is no -71 error, albeit it returns an empty data array, but no low level protocol error.
Besides all this, i found that the Native USB resource literature is scarce and that Native USB is severely under documented, besides the PluggableUSB tutorial.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.