Does usb device support arbitrary (no/generic class) usb device?

moefear85
Posts: 44
Joined: Sun Sep 05, 2021 4:55 pm

Does usb device support arbitrary (no/generic class) usb device?

Postby moefear85 » Thu Aug 22, 2024 4:13 pm

I'm trying to create a simple "hello world" usb device, that doesn't follow any prespecified class type (not HID/MSC/etc), because I don't want any preexisting generic driver from my PC to pick it up. I'm trying to code a custom driver that kicks in based solely on VID:PID, which I have chosen arbitrarily. The problem is that upon plugging into the PC, I get the following error:

Code: Select all

E (133) tusb_tsk: tusb_run_task(49): TinyUSB main task already started
E (133) TinyUSB: tinyusb_driver_install(63): Run TinyUSB task failed
ESP_ERROR_CHECK failed: esp_err_t 0x103 (ESP_ERR_INVALID_STATE) at 0x40085dc9
0x40085dc9: app_main at /home/mofear/Projects/C++/kernel_modules/test_i2c_adapter/usb_test/main/main.c:69 (discriminator 1)

file: "./main/main.c" line 69
func: app_main
expression: tinyusb_driver_install(&tusb_cfg)

abort() was called at PC 0x4002adff on core 0
0x4002adff: _esp_error_check_failed at /media/STORAGE/source/esp-idf_release-v5.3_20.08.24/components/esp_system/esp_err.c:49



Backtrace: 0x400254ff:0x3ffca6d0 0x4002ae19:0x3ffca700 0x40032c6d:0x3ffca730 0x4002adff:0x3ffca7b0 0x40085dc9:0x3ffca7f0 0x4009c834:0x3ffca830 0x4002e35a:0x3ffca860
0x400254ff: panic_abort at /media/STORAGE/source/esp-idf_release-v5.3_20.08.24/components/esp_system/panic.c:463
0x4002ae19: esp_system_abort at /media/STORAGE/source/esp-idf_release-v5.3_20.08.24/components/esp_system/port/esp_system_chip.c:92
0x40032c6d: abort at /media/STORAGE/source/esp-idf_release-v5.3_20.08.24/components/newlib/abort.c:38
0x4002adff: _esp_error_check_failed at /media/STORAGE/source/esp-idf_release-v5.3_20.08.24/components/esp_system/esp_err.c:49
0x40085dc9: app_main at /home/mofear/Projects/C++/kernel_modules/test_i2c_adapter/usb_test/main/main.c:69 (discriminator 1)
0x4009c834: main_task at /media/STORAGE/source/esp-idf_release-v5.3_20.08.24/components/freertos/app_startup.c:208
0x4002e35a: vPortTaskWrapper at /media/STORAGE/source/esp-idf_release-v5.3_20.08.24/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:134





ELF file SHA256: 4495daafb

CPU halted.
The documentation on the esp32s2, does not provide any information on how to create a usb device that does not follow a standard class. Is this intentional? Are the only options to use one of the preexisting classes in sdkconfig (MSC/CDC/HID/BTH/MIDI/DFU/UVC/ECM/NCM/RNDIS)?

I'm setting up the descriptors as follows:

Code: Select all

#include <stdint.h>
#include "esp_log.h"
#include "tinyusb.h"

#define UCHAR unsigned char

static const char *TAG = "example";

tusb_desc_configuration_t desc_conf={
    .bLength=sizeof(tusb_desc_configuration_t),
    .bDescriptorType=0x2,
    .wTotalLength=sizeof(tusb_desc_configuration_t)+sizeof(tusb_desc_interface_t)+sizeof(tusb_desc_endpoint_t),
    .bNumInterfaces=1,
    .bConfigurationValue=1, // should be 1 according to usb spec
    .iConfiguration=0,
    .bmAttributes=0x80,
    .bMaxPower=50,
};

tusb_desc_interface_t desc_interf={
    .bLength=sizeof(tusb_desc_interface_t),
    .bDescriptorType=0x4,
    .bInterfaceNumber=0,
    .bAlternateSetting=0, // first setting is also technically alternate setting, and indices start from 0
    .bNumEndpoints=1,
    .bInterfaceClass=0xff,
    .bInterfaceSubClass=0x01,
    .bInterfaceProtocol=0x01,
    .iInterface=0,
};

tusb_desc_endpoint_t desc_endp={
    .bLength=sizeof(tusb_desc_endpoint_t),
    .bDescriptorType=5,
    .bEndpointAddress=0x00,
    .bInterval=0,
    .bmAttributes.xfer=2,
    .bmAttributes.sync=0,
    .bmAttributes.usage=0,
    .wMaxPacketSize=64,
};

char* total_desc;

void app_main(void)
{
    ESP_LOGI(TAG, "USB initialization");

    total_desc=malloc(desc_conf.wTotalLength);

    memcpy(&total_desc, &desc_conf, sizeof(desc_conf));
    memcpy(&total_desc+sizeof(desc_conf), &desc_interf,sizeof(desc_interf));
    memcpy(&total_desc+sizeof(desc_conf)+sizeof(desc_interf), &desc_endp, sizeof(desc_endp));

    tinyusb_config_t tusb_cfg={
        .configuration_descriptor=(UCHAR*) buffer,
    };

    ESP_ERROR_CHECK( tinyusb_driver_install(&tusb_cfg) );
}
Is this allowed? Is there a proper way to set/choose my own configuration/interface/endpoint descriptors? The documentation seems to imply that we are only given the option to specify a custom configuration descriptor for fringe cases, but that it must still conform to one of the preexisting provided classes in sdkconfig, such that it isn't possible to additionally specify arbitrary interface/endpoint descriptors?

Who is online

Users browsing this forum: No registered users and 99 guests