Git Product home page Git Product logo

Comments (7)

profi200 avatar profi200 commented on June 18, 2024

Update:
I have modified the dev_hid_generic_inout example so it works exactly as i want.

2 things i noticed:

  • Endpoint buffer size seems to be restricted to 64 bytes which means lots of IRQs :/
  • TinyUSB doesn't recognize there is incoming data anymore if the PC side test code connects again causing it to not respond. The workaround is resetting the USB device. Unsure if this is expected behavior or a bug in TinyUSB/the underlying USB driver.

Here is the code:
tusb_config.h

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Ha Thach (tinyusb.org)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#ifndef _TUSB_CONFIG_H_
#define _TUSB_CONFIG_H_

#ifdef __cplusplus
extern "C" {
#endif

//--------------------------------------------------------------------
// COMMON CONFIGURATION
//--------------------------------------------------------------------

// defined by compiler flags for flexibility
#ifndef CFG_TUSB_MCU
#error CFG_TUSB_MCU must be defined
#endif

#if CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \
    CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56
#define CFG_TUSB_RHPORT0_MODE     (OPT_MODE_DEVICE | OPT_MODE_HIGH_SPEED)
#else
#define CFG_TUSB_RHPORT0_MODE     OPT_MODE_DEVICE
#endif

#ifndef CFG_TUSB_OS
#define CFG_TUSB_OS                 OPT_OS_PICO
#endif

// CFG_TUSB_DEBUG is defined by compiler in DEBUG build
// #define CFG_TUSB_DEBUG           0

/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
 * Tinyusb use follows macros to declare transferring memory so that they can be put
 * into those specific section.
 * e.g
 * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
 * - CFG_TUSB_MEM_ALIGN   : __attribute__ ((aligned(4)))
 */
#ifndef CFG_TUSB_MEM_SECTION
#define CFG_TUSB_MEM_SECTION
#endif

#ifndef CFG_TUSB_MEM_ALIGN
#define CFG_TUSB_MEM_ALIGN          __attribute__ ((aligned(4)))
#endif

//--------------------------------------------------------------------
// DEVICE CONFIGURATION
//--------------------------------------------------------------------

#ifndef CFG_TUD_ENDPOINT0_SIZE
#define CFG_TUD_ENDPOINT0_SIZE    64
#endif

//------------- CLASS -------------//
#define CFG_TUD_CDC             0
#define CFG_TUD_MSC             0
#define CFG_TUD_HID             0
#define CFG_TUD_MIDI            0
#define CFG_TUD_VENDOR          1

#define CFG_TUD_VENDOR_EPSIZE      64
#define CFG_TUD_VENDOR_RX_BUFSIZE  64
#define CFG_TUD_VENDOR_TX_BUFSIZE  64

#ifdef __cplusplus
}
#endif

#endif /* _TUSB_CONFIG_H_ */

usb_descriptors.c

/* 
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Ha Thach (tinyusb.org)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#include "tusb.h"

/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
 * Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
 *
 * Auto ProductID layout's Bitmap:
 *   [MSB]         HID | MSC | CDC          [LSB]
 */
#define _PID_MAP(itf, n)  ( (CFG_TUD_##itf) << (n) )
#define USB_PID           (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
                           _PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) )

//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
tusb_desc_device_t const desc_device =
        {
                .bLength            = sizeof(tusb_desc_device_t),
                .bDescriptorType    = TUSB_DESC_DEVICE,
                .bcdUSB             = 0x0200,
                .bDeviceClass       = 0x00,
                .bDeviceSubClass    = 0x00,
                .bDeviceProtocol    = 0x00,
                .bMaxPacketSize0    = CFG_TUD_ENDPOINT0_SIZE,

                .idVendor           = 0xCafe,
                .idProduct          = USB_PID,
                .bcdDevice          = 0x0100,

                .iManufacturer      = 0x01,
                .iProduct           = 0x02,
                .iSerialNumber      = 0x03,

                .bNumConfigurations = 0x01
        };

// Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor
uint8_t const *tud_descriptor_device_cb(void) {
    return (uint8_t const *) &desc_device;
}

//--------------------------------------------------------------------+
// Configuration Descriptor
//--------------------------------------------------------------------+

enum {
    ITF_NUM_VENDOR,
    ITF_NUM_TOTAL
};

#define  CONFIG_TOTAL_LEN  (TUD_CONFIG_DESC_LEN + TUD_VENDOR_DESC_LEN)

#define EPNUM_IN   0x02
#define EPNUM_OUT  0x01

uint8_t const desc_configuration[] =
        {
                // Config number, interface count, string index, total length, attribute, power in mA
                TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),

                // Interface number, string index, EP Out & IN address, EP size
                TUD_VENDOR_DESCRIPTOR(ITF_NUM_VENDOR, 0, EPNUM_OUT, 0x80 | EPNUM_IN, CFG_TUD_VENDOR_EPSIZE)
        };

// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const *tud_descriptor_configuration_cb(uint8_t index) {
    (void) index; // for multiple configurations
    return desc_configuration;
}

//--------------------------------------------------------------------+
// String Descriptors
//--------------------------------------------------------------------+

// array of pointer to string descriptors
char const *string_desc_arr[] =
        {
                (const char[]) {0x09, 0x04}, // 0: is supported language is English (0x0409)
                "TinyUSB",                     // 1: Manufacturer
                "TinyUSB Device",              // 2: Product
                "123456",                      // 3: Serials, should use chip ID
        };

static uint16_t _desc_str[32];

// Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
uint16_t const *tud_descriptor_string_cb(uint8_t index, uint16_t langid) {
    (void) langid;

    uint8_t chr_count;

    if (index == 0) {
        memcpy(&_desc_str[1], string_desc_arr[0], 2);
        chr_count = 1;
    } else {
        // Convert ASCII string into UTF-16

        if (!(index < sizeof(string_desc_arr) / sizeof(string_desc_arr[0]))) return NULL;

        const char *str = string_desc_arr[index];

        // Cap at max char
        chr_count = strlen(str);
        if (chr_count > 31) chr_count = 31;

        for (uint8_t i = 0; i < chr_count; i++) {
            _desc_str[1 + i] = str[i];
        }
    }

    // first byte is length (including header), second byte is string type
    _desc_str[0] = (TUSB_DESC_STRING << 8) | (2 * chr_count + 2);

    return _desc_str;
}

vendor_generic_inout.c

/* 
 * The MIT License (MIT)
 *
 * Copyright (c) 2019 Ha Thach (tinyusb.org)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "bsp/board.h"
#include "tusb.h"

//--------------------------------------------------------------------+
// MACRO CONSTANT TYPEDEF PROTYPES
//--------------------------------------------------------------------+

/* Blink pattern
 * - 250 ms  : device not mounted
 * - 1000 ms : device mounted
 * - 2500 ms : device is suspended
 */
enum {
    BLINK_NOT_MOUNTED = 250,
    BLINK_MOUNTED = 1000,
    BLINK_SUSPENDED = 2500,
};

static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;

void led_blinking_task(void);

/*------------- MAIN -------------*/
int main(void) {
    board_init();

    tusb_init();

    while (1) {
        tud_task(); // tinyusb device task
        led_blinking_task();
    }

    return 0;
}

//--------------------------------------------------------------------+
// Device callbacks
//--------------------------------------------------------------------+

// Invoked when device is mounted
void tud_mount_cb(void) {
    blink_interval_ms = BLINK_MOUNTED;
}

// Invoked when device is unmounted
void tud_umount_cb(void) {
    blink_interval_ms = BLINK_NOT_MOUNTED;
}

// Invoked when usb bus is suspended
// remote_wakeup_en : if host allow us  to perform remote wakeup
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
void tud_suspend_cb(bool remote_wakeup_en) {
    (void) remote_wakeup_en;
    blink_interval_ms = BLINK_SUSPENDED;
}

// Invoked when usb bus is resumed
void tud_resume_cb(void) {
    blink_interval_ms = BLINK_MOUNTED;
}

//--------------------------------------------------------------------+
// USB VENDOR
//--------------------------------------------------------------------+

// Send back any data we receive from the host.
void tud_vendor_rx_cb(uint8_t itf)
{
    (void)itf;

    uint8_t lb_buf[64];
    const uint32_t read = tud_vendor_read(lb_buf, 64);
    tud_vendor_write(lb_buf, read);
}

//--------------------------------------------------------------------+
// BLINKING TASK
//--------------------------------------------------------------------+
void led_blinking_task(void) {
    static uint32_t start_ms = 0;
    static bool led_state = false;

    // Blink every interval ms
    if (board_millis() - start_ms < blink_interval_ms) return; // not enough time
    start_ms += blink_interval_ms;

    board_led_write(led_state);
    led_state = 1 - led_state; // toggle
}

My test code. Should also work with a modified version of the Python script from the lowlevel example:

#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <getopt.h>
#include <libusb.h>


#define VENDOR_ID         (0xCAFE)
#define PRODUCT_ID        (0x4010)

#define USB_ENDPOINT_OUT  (0x01)
#define USB_ENDPOINT_IN   (0x82)
#define USB_TIMEOUT       (5000)



libusb_device_handle* findSetupDevice(uint16_t idVendor, uint16_t idProduct)
{
	libusb_device **list;
	ssize_t num = libusb_get_device_list(NULL, &list);
	if(num < 0)
	{
		fprintf(stderr, "Failed to get device list.\n");
		return NULL;
	}

	libusb_device_handle *devH = NULL;
	for(uint32_t i = 0; i < num; i++)
	{
		struct libusb_device_descriptor desc;
		if(libusb_get_device_descriptor(list[i], &desc) < 0)
		{
			fprintf(stderr, "Failed to get device descriptor.\n");
			libusb_free_device_list(list, 1);
			return devH;
		}

		if(desc.idVendor == idVendor && desc.idProduct == idProduct)
		{
			if(libusb_open(list[i], &devH)) fprintf(stderr, "Failed to open device.\n");
			else
			{
				if(libusb_set_configuration(devH, 1))
				{
					fprintf(stderr, "Failed to set configuration\n");
					libusb_close(devH);
					devH = NULL;
				}
			}
			break;
		}
	}

	libusb_free_device_list(list, 1);

	return devH;
}

static bool sendReceiveHello(libusb_device_handle *devH)
{
	uint8_t sendbuf[64] = "Hello USB!"; // 11 bytes with terminator.
	uint8_t recvbuf[64] = {0};

	int transferred;
	if(libusb_bulk_transfer(devH, USB_ENDPOINT_OUT, sendbuf, 11, &transferred, USB_TIMEOUT) ||
	   transferred != 11)
	{
		fprintf(stderr, "Failed to send data.\n");
		return false;
	}

	if(libusb_bulk_transfer(devH, USB_ENDPOINT_IN, recvbuf, 11, &transferred, USB_TIMEOUT) ||
	   transferred != 11)
	{
		fprintf(stderr, "Failed to receive data.\n");
		return false;
	}

	printf("Received: \"%s\"\n", (char*)recvbuf);

	return true;
}

// gcc -std=c17 -O2 -fstrict-aliasing -ffunction-sections -Wall -I/usr/include/libusb-1.0 -L/usr/lib -Wl,--gc-sections pico_usb_test.c -o pico_usb_test -lusb-1.0
int main(int argc, char *const argv[])
{
	if(libusb_init(NULL))
	{
		fprintf(stderr, "libusb init failed.\n");
		return 1;
	}
	libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_INFO);

	libusb_device_handle *devH = findSetupDevice(VENDOR_ID, PRODUCT_ID);
	if(!devH)
	{
		fprintf(stderr, "pico not found.\n");
		libusb_exit(NULL);
		return 2;
	}

	// TODO: Can we reconnect without reset?
	if(libusb_reset_device(devH))
	{
		fprintf(stderr, "Failed to reset device.\n");
		libusb_close(devH);
		libusb_exit(NULL);
		return 3;
	}

	if(libusb_claim_interface(devH, 0))
	{
		fprintf(stderr, "Failed to claim interface 0.\n");
		libusb_close(devH);
		libusb_exit(NULL);
		return 4;
	}

	sendReceiveHello(devH);

	libusb_release_interface(devH, 0);
	libusb_close(devH);
	libusb_exit(NULL);

	return 0;
}

from pico-examples.

lurch avatar lurch commented on June 18, 2024

ping @liamfraser

from pico-examples.

liamfraser avatar liamfraser commented on June 18, 2024

64 byte is the max packet size of a USB 1.1 device. That's just how the protocol works. https://github.com/raspberrypi/picoprobe is an example of a vendor device.

from pico-examples.

liamfraser avatar liamfraser commented on June 18, 2024

I don't have to reset the device before I can talk to it in picoprobe but I am getting the data differently:

    if ( tud_vendor_available() ) {
        uint count = tud_vendor_read(&probe.rx_buf[probe.rx_len], 64);

It depends when tinyusb decides to call the callback. It might only do it when you get a full 64 bytes?

from pico-examples.

profi200 avatar profi200 commented on June 18, 2024

Yeah, almost expected that to be a USB 1.1 limitation. That's a shame because as mentioned that will cause lots of IRQs for larger transfers.

The problem with having to reset the device i dunno. The PC side test code is actually a stripped down version of code i have written for something else long ago and it didn't need a reset either (but the device acted buggy in other ways like timing out on first try). It doesn't have issues with arbitrary sized bulk transfers if the test code opens the device for the first time. Can send anything up to 64 bytes and multiple bulk transfers as well.

libusb output without reset first try:

[blub@blub-PC vendor_generic_inout]$ sudo ./pico_usb_test
[sudo] Passwort für blub: 
[timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
[ 0.003590] [000297a0] libusb: debug [libusb_get_device_list]  
[ 0.003608] [000297a0] libusb: debug [discovered_devs_append] need to increase capacity
[ 0.003614] [000297a0] libusb: debug [libusb_get_device_descriptor]  
[ 0.003621] [000297a0] libusb: debug [libusb_get_device_descriptor]  
[ 0.003625] [000297a0] libusb: debug [libusb_get_device_descriptor]  
[ 0.003627] [000297a0] libusb: debug [libusb_get_device_descriptor]  
[ 0.003629] [000297a0] libusb: debug [libusb_get_device_descriptor]  
[ 0.003631] [000297a0] libusb: debug [libusb_get_device_descriptor]  
[ 0.003634] [000297a0] libusb: debug [libusb_get_device_descriptor]  
[ 0.003638] [000297a0] libusb: debug [libusb_open] open 2.7
[ 0.112770] [000297a0] libusb: debug [usbi_add_event_source] add fd 7 events 4
[ 0.112825] [000297a0] libusb: debug [libusb_set_configuration] configuration 1
[ 0.115049] [000297a0] libusb: debug [libusb_claim_interface] interface 0
[ 0.115139] [000297a0] libusb: debug [libusb_alloc_transfer] transfer 0x555e464e0f78
[ 0.115155] [000297a0] libusb: debug [libusb_submit_transfer] transfer 0x555e464e0f78
[ 0.115166] [000297a0] libusb: debug [add_to_flying_list] arm timer for timeout in 5000ms (first in line)
[ 0.115184] [000297a0] libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 11
[ 0.115218] [000297a0] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.115230] [000297a0] libusb: debug [handle_events] event sources modified, reallocating event data
[ 0.115244] [000297a0] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ 0.115265] [000297a0] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 0.115279] [000297a0] libusb: debug [reap_for_handle] urb type=3 status=0 transferred=11
[ 0.115291] [000297a0] libusb: debug [handle_bulk_completion] handling completion status 0 of bulk urb 1/1
[ 0.115299] [000297a0] libusb: debug [handle_bulk_completion] all URBs in transfer reaped --> complete!
[ 0.115307] [000297a0] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer
[ 0.115323] [000297a0] libusb: debug [usbi_handle_transfer_completion] transfer 0x555e464e0f78 has callback 0x7f85889837d0
[ 0.115335] [000297a0] libusb: debug [sync_transfer_cb] actual_length=11
[ 0.115350] [000297a0] libusb: debug [libusb_free_transfer] transfer 0x555e464e0f78
[ 0.115363] [000297a0] libusb: debug [libusb_alloc_transfer] transfer 0x555e464dabb8
[ 0.115371] [000297a0] libusb: debug [libusb_submit_transfer] transfer 0x555e464dabb8
[ 0.115380] [000297a0] libusb: debug [add_to_flying_list] arm timer for timeout in 5000ms (first in line)
[ 0.115396] [000297a0] libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 11
[ 0.115417] [000297a0] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.115428] [000297a0] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ 0.115465] [000297a0] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 0.115481] [000297a0] libusb: debug [reap_for_handle] urb type=3 status=0 transferred=11
[ 0.115492] [000297a0] libusb: debug [handle_bulk_completion] handling completion status 0 of bulk urb 1/1
[ 0.115504] [000297a0] libusb: debug [handle_bulk_completion] all URBs in transfer reaped --> complete!
[ 0.115515] [000297a0] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer
[ 0.115529] [000297a0] libusb: debug [usbi_handle_transfer_completion] transfer 0x555e464dabb8 has callback 0x7f85889837d0
[ 0.115541] [000297a0] libusb: debug [sync_transfer_cb] actual_length=11
[ 0.115556] [000297a0] libusb: debug [libusb_free_transfer] transfer 0x555e464dabb8
Received: "Hello USB!"
[ 0.115598] [000297a0] libusb: debug [libusb_release_interface] interface 0
[ 0.115637] [000297a0] libusb: debug [libusb_close]  
[ 0.115651] [000297a0] libusb: debug [usbi_remove_event_source] remove fd 7
[ 0.115677] [000297a0] libusb: debug [libusb_exit]  
[ 0.115689] [000297a0] libusb: debug [libusb_exit] destroying default context
[ 0.115700] [000297a0] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.115711] [000297a0] libusb: debug [handle_events] event sources modified, reallocating event data
[ 0.115727] [000297a0] libusb: debug [usbi_wait_for_events] poll() 2 fds with timeout in 0ms
[ 0.115785] [000297a0] libusb: debug [usbi_wait_for_events] poll() returned 0
[ 0.115801] [000297a0] libusb: debug [libusb_unref_device] destroy device 3.2
[ 0.115816] [000297a0] libusb: debug [libusb_unref_device] destroy device 3.1
[ 0.115830] [000297a0] libusb: debug [libusb_unref_device] destroy device 1.2
[ 0.115846] [000297a0] libusb: debug [libusb_unref_device] destroy device 1.1
[ 0.115860] [000297a0] libusb: debug [libusb_unref_device] destroy device 4.1
[ 0.115874] [000297a0] libusb: debug [libusb_unref_device] destroy device 2.3
[ 0.115889] [000297a0] libusb: debug [libusb_unref_device] destroy device 2.7
[ 0.115902] [000297a0] libusb: debug [libusb_unref_device] destroy device 2.2
[ 0.115917] [000297a0] libusb: debug [libusb_unref_device] destroy device 2.5
[ 0.115930] [000297a0] libusb: debug [libusb_unref_device] destroy device 2.6
[ 0.115944] [000297a0] libusb: debug [libusb_unref_device] destroy device 2.1
[ 0.115958] [000297a0] libusb: debug [usbi_remove_event_source] remove fd 6
[ 0.115986] [000297a0] libusb: debug [usbi_remove_event_source] remove fd 5
[ 0.116038] [000297a1] libusb: debug [linux_udev_event_thread_main] udev event thread exiting

Second try:

[blub@blub-PC vendor_generic_inout]$ sudo ./pico_usb_test
[timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
[ 0.003601] [000297a9] libusb: debug [libusb_get_device_list]  
[ 0.003612] [000297a9] libusb: debug [discovered_devs_append] need to increase capacity
[ 0.003616] [000297a9] libusb: debug [libusb_get_device_descriptor]  
[ 0.003619] [000297a9] libusb: debug [libusb_get_device_descriptor]  
[ 0.003621] [000297a9] libusb: debug [libusb_get_device_descriptor]  
[ 0.003624] [000297a9] libusb: debug [libusb_get_device_descriptor]  
[ 0.003626] [000297a9] libusb: debug [libusb_get_device_descriptor]  
[ 0.003628] [000297a9] libusb: debug [libusb_get_device_descriptor]  
[ 0.003630] [000297a9] libusb: debug [libusb_get_device_descriptor]  
[ 0.003633] [000297a9] libusb: debug [libusb_open] open 2.7
[ 0.111359] [000297a9] libusb: debug [usbi_add_event_source] add fd 7 events 4
[ 0.111422] [000297a9] libusb: debug [libusb_set_configuration] configuration 1
[ 0.113653] [000297a9] libusb: debug [libusb_claim_interface] interface 0
[ 0.113752] [000297a9] libusb: debug [libusb_alloc_transfer] transfer 0x561958850f78
[ 0.113771] [000297a9] libusb: debug [libusb_submit_transfer] transfer 0x561958850f78
[ 0.113781] [000297a9] libusb: debug [add_to_flying_list] arm timer for timeout in 5000ms (first in line)
[ 0.113800] [000297a9] libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 11
[ 0.113835] [000297a9] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.113848] [000297a9] libusb: debug [handle_events] event sources modified, reallocating event data
[ 0.113863] [000297a9] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ 0.113885] [000297a9] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 0.113898] [000297a9] libusb: debug [reap_for_handle] urb type=3 status=0 transferred=11
[ 0.113913] [000297a9] libusb: debug [handle_bulk_completion] handling completion status 0 of bulk urb 1/1
[ 0.113925] [000297a9] libusb: debug [handle_bulk_completion] all URBs in transfer reaped --> complete!
[ 0.113938] [000297a9] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer
[ 0.113954] [000297a9] libusb: debug [usbi_handle_transfer_completion] transfer 0x561958850f78 has callback 0x7fa252d6e7d0
[ 0.113966] [000297a9] libusb: debug [sync_transfer_cb] actual_length=11
[ 0.113980] [000297a9] libusb: debug [libusb_free_transfer] transfer 0x561958850f78
[ 0.113995] [000297a9] libusb: debug [libusb_alloc_transfer] transfer 0x56195884abb8
[ 0.114007] [000297a9] libusb: debug [libusb_submit_transfer] transfer 0x56195884abb8
[ 0.114020] [000297a9] libusb: debug [add_to_flying_list] arm timer for timeout in 5000ms (first in line)
[ 0.114036] [000297a9] libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 11
[ 0.114060] [000297a9] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.114072] [000297a9] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ 5.114165] [000297a9] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 5.114210] [000297a9] libusb: debug [libusb_cancel_transfer] transfer 0x56195884abb8
[ 5.114336] [000297a9] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer
[ 5.114369] [000297a9] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 5.114390] [000297a9] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ 5.114413] [000297a9] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 5.114447] [000297a9] libusb: debug [reap_for_handle] urb type=3 status=-2 transferred=0
[ 5.114465] [000297a9] libusb: debug [handle_bulk_completion] handling completion status -2 of bulk urb 1/1
[ 5.114478] [000297a9] libusb: debug [handle_bulk_completion] abnormal reap: urb status -2
[ 5.114487] [000297a9] libusb: debug [handle_bulk_completion] abnormal reap: last URB handled, reporting
[ 5.114504] [000297a9] libusb: debug [usbi_handle_transfer_cancellation] detected timeout cancellation
[ 5.114520] [000297a9] libusb: debug [arm_timer_for_next_timeout] no timeouts, disarming timer
[ 5.114536] [000297a9] libusb: debug [usbi_handle_transfer_completion] transfer 0x56195884abb8 has callback 0x7fa252d6e7d0
[ 5.114555] [000297a9] libusb: debug [sync_transfer_cb] actual_length=0
[ 5.114577] [000297a9] libusb: debug [libusb_free_transfer] transfer 0x56195884abb8
Failed to receive data.
[ 5.114619] [000297a9] libusb: debug [libusb_release_interface] interface 0
[ 5.114677] [000297a9] libusb: debug [libusb_close]  
[ 5.114703] [000297a9] libusb: debug [usbi_remove_event_source] remove fd 7
[ 5.114741] [000297a9] libusb: debug [libusb_exit]  
[ 5.114757] [000297a9] libusb: debug [libusb_exit] destroying default context
[ 5.114776] [000297a9] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 5.114793] [000297a9] libusb: debug [handle_events] event sources modified, reallocating event data
[ 5.114817] [000297a9] libusb: debug [usbi_wait_for_events] poll() 2 fds with timeout in 0ms
[ 5.114839] [000297a9] libusb: debug [usbi_wait_for_events] poll() returned 0
[ 5.114856] [000297a9] libusb: debug [libusb_unref_device] destroy device 3.2
[ 5.114875] [000297a9] libusb: debug [libusb_unref_device] destroy device 3.1
[ 5.114894] [000297a9] libusb: debug [libusb_unref_device] destroy device 1.2
[ 5.114912] [000297a9] libusb: debug [libusb_unref_device] destroy device 1.1
[ 5.114931] [000297a9] libusb: debug [libusb_unref_device] destroy device 4.1
[ 5.114948] [000297a9] libusb: debug [libusb_unref_device] destroy device 2.3
[ 5.114967] [000297a9] libusb: debug [libusb_unref_device] destroy device 2.7
[ 5.114984] [000297a9] libusb: debug [libusb_unref_device] destroy device 2.2
[ 5.115003] [000297a9] libusb: debug [libusb_unref_device] destroy device 2.5
[ 5.115021] [000297a9] libusb: debug [libusb_unref_device] destroy device 2.6
[ 5.115039] [000297a9] libusb: debug [libusb_unref_device] destroy device 2.1
[ 5.115056] [000297a9] libusb: debug [usbi_remove_event_source] remove fd 6
[ 5.115088] [000297a9] libusb: debug [usbi_remove_event_source] remove fd 5
[ 5.115154] [000297aa] libusb: debug [linux_udev_event_thread_main] udev event thread exiting

from pico-examples.

kilograham avatar kilograham commented on June 18, 2024

please re-open this as a PR if you want it included

from pico-examples.

JesperNaarttijarvi avatar JesperNaarttijarvi commented on June 18, 2024

EDIT:
I changed the data to send in bytes of 64 instead, and now it works.

Sorry for the very late response, but did you get it to work?

I wanted to achieve the same test result, and got stuck. Sending data works, but not receiving it.

Tried with your code, but also gets stuck on "Failed to receive data."

My logs are very similar to yours:
HOST

sudo ./cm4_usb_host 1

Starting USB scan thread...
2024-06-05 10:43:00 Found a Pico USB device
2024-06-05 10:43:00 Setting up communications
2024-06-05 10:43:00 Sending counter 200 to device
Sent 1 bytes
2024-06-05 10:43:00 Waiting for response from device...
Error receiving data from device: LIBUSB_ERROR_TIMEOUT
2024-06-05 10:43:01 Sending counter 201 to device
Sent 1 bytes
2024-06-05 10:43:01 Waiting for response from device...
Error receiving data from device: LIBUSB_ERROR_TIMEOUT
2024-06-05 10:43:03 Sending counter 202 to device
Sent 1 bytes
2024-06-05 10:43:03 Waiting for response from device...
Error receiving data from device: LIBUSB_ERROR_TIMEOUT
2024-06-05 10:43:04 Sending counter 203 to device
Sent 1 bytes
2024-06-05 10:43:04 Waiting for response from device...
Error receiving data from device: LIBUSB_ERROR_TIMEOUT

DEVICE (RP2040 OVER UART CONSOLE):

Sending counter 201 to host, 1 bytes written
USBD Xfer Complete on EP 01 with 1 bytes
  VENDOR xfer callback
  Queue EP 01 with 64 bytes ...
Received counter 201 from host
Sending counter 202 to host, 1 bytes written
USBD Xfer Complete on EP 01 with 1 bytes
  VENDOR xfer callback
  Queue EP 01 with 64 bytes ...
Received counter 202 from host
Sending counter 203 to host, 1 bytes written
USBD Xfer Complete on EP 01 with 1 bytes
  VENDOR xfer callback
  Queue EP 01 with 64 bytes ...
Received counter 203 from host
Sending counter 204 to host, 1 bytes written

from pico-examples.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.