Skip to content

correct bulk size for highspeed endpoint in dynamic_configuration and usbtmc exmaples#1516

Merged
hathach merged 1 commit intomasterfrom
fix-example-with-highspeed
Jun 17, 2022
Merged

correct bulk size for highspeed endpoint in dynamic_configuration and usbtmc exmaples#1516
hathach merged 1 commit intomasterfrom
fix-example-with-highspeed

Conversation

@hathach
Copy link
Copy Markdown
Owner

@hathach hathach commented Jun 17, 2022

Describe the PR
fix #1457, close #1459
bulk endpoint size must be 512 for highspeed and 64 for FS, dynamic_configuration and usbtmc examples hard coded to 64 and cause an assert in the stack

[ 4949.159993] usb 3-1: USB disconnect, device number 51
[ 4949.484276] usb 3-1: new high-speed USB device number 52 using xhci_hcd
[ 4949.633227] usb 3-1: config 1 interface 0 altsetting 0 bulk endpoint 0x1 has invalid maxpacket 64
[ 4949.633230] usb 3-1: config 1 interface 0 altsetting 0 bulk endpoint 0x81 has invalid maxpacket 64

@pigrew
Copy link
Copy Markdown
Collaborator

pigrew commented Jun 17, 2022

@hathach, perhaps you can explain this to me?

Will this cause any issues when a high-speed device is talking to a full-speed host (or using a full-speed hub)?

Since it would be a full-speed connection, the packets shouldn't be more than 64 bytes, but the descriptor will statically report a maxPacketLen of 512?

(I'm not so familiar with high-speed USB, so please pardon my ignorance)

(It looks like the correct answer is to have two sets of descriptors, and update the example application code to choose the appropriate one. If so, I can write up a patch?)

@hathach
Copy link
Copy Markdown
Owner Author

hathach commented Jun 18, 2022

For complete compatible with FS hub/host, highspeed-capable device must prepare 2 configuration descriptors: fs and hs and return correct one according to the actual link speed. When HS-capable device working in FS link, it may need to answer to the get_other_speed_configuration() from host. I did implement all of this for cdc_msc example sometime ago

uint8_t const desc_fs_configuration[] =
{
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
};
#if TUD_OPT_HIGH_SPEED
// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
// high speed configuration
uint8_t const desc_hs_configuration[] =
{
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
// Interface number, string index, EP Out & EP In address, EP size
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512),
};
// other speed configuration
uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
tusb_desc_device_qualifier_t const desc_device_qualifier =
{
.bLength = sizeof(tusb_desc_device_qualifier_t),
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
.bcdUSB = USB_BCD,
.bDeviceClass = TUSB_CLASS_MISC,
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
.bDeviceProtocol = MISC_PROTOCOL_IAD,
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
.bNumConfigurations = 0x01,
.bReserved = 0x00
};
// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete.
// device_qualifier descriptor describes information about a high-speed capable device that would
// change if the device were operating at the other speed. If not highspeed capable stall this request.
uint8_t const* tud_descriptor_device_qualifier_cb(void)
{
return (uint8_t const*) &desc_device_qualifier;
}
// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa
uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index)
{
(void) index; // for multiple configurations
// if link speed is high return fullspeed config, and vice versa
// Note: the descriptor type is OHER_SPEED_CONFIG instead of CONFIG
memcpy(desc_other_speed_config,
(tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration,
CONFIG_TOTAL_LEN);
desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG;
return desc_other_speed_config;
}
#endif // highspeed
// 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
#if TUD_OPT_HIGH_SPEED
// Although we are highspeed, host may be fullspeed.
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
#else
return desc_fs_configuration;
#endif
}

Note: The driver reserve max 512 bytes for buffering, but should only use the actual packet size from actual descriptor if needed. For cdc driver it simply schedule the max possible (512) since typically, cdc transfer end with short packet and have an stream buffered.

@hathach
Copy link
Copy Markdown
Owner Author

hathach commented Jun 18, 2022

PS: I will update the usbtmc example later to also support this scenario :)

@pigrew
Copy link
Copy Markdown
Collaborator

pigrew commented Jun 18, 2022

PS: I will update the usbtmc example later to also support this scenario :)

Thanks! I didn't want to create more work for you (but on the other hand, I don't have any HS devices to test...)

I unfortunately used USBTMCD_MAX_PACKET_SIZE a bunch of times in the driver, too. These have to be changed to be based on the value in the endpoint descriptor table....

@hathach
Copy link
Copy Markdown
Owner Author

hathach commented Jun 20, 2022

No problems at all, you added usbtmc driver before I have sorted this hs/fs thing out. I will double check the example and driver when having time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

some examples don't work for imxrt: cdc_msc_freertos, dynamic_configuration, hid_composite_freertos, usbtmc

2 participants