USB driver : setting 'high-speed' causes assert to fail for MSC subsys as NRF_USBD_COMMON_EPSIZE is fixed at 64!

Using NCS 2.9.0, Zephyr 3.7.99 on a custom nrf5340 board, I want to have multiple functions enabled on the USB interface : zephyr supplied MassStorage (msc), virtual UART (CDC-ACM), and my own custom CCID class for smartcard access.

I have managed to navigate the endpoint address maze (hint : the zephyr usb stack ALWAYS fixes up the endpoint addresses to avoid conflict between classes as per https://docs.zephyrproject.org/3.7.0/connectivity/usb/device/usb_device.html#implementing-a-non-standard-usb-class), and avoided running out of endpoints by configuring  num-in-endpoints/num-out-endpoints for the usbd device in the DTS (see below). And to get the usb_transfer() function not to run of 'slots' by setting CONFIG_USB_MAX_NUM_TRANSFERS=8 instead of 4 (would have been nice to put that info in the doc guys...)...

However, in the same device config I also set the USB speed to be 'high-speed':

zephyr_udc0: &usbd {
    compatible = "nordic,nrf-usbd";
    /* IN : 2 per uart =4 + 1 per MSC + 2 per CCID = 7 + spare = 8*/
    num-in-endpoints = <8>;
    /* OUT : 1 per uart = 2 + 1 per MSC + 1 per CCID = 4 + spare = 5 */
    num-out-endpoints = <5>;
    maximum-speed = "high-speed";
    status = "okay";
};

The aim is get the MSC and ACM operations to be faster (eg file copies, or doing DFU using mcuboot over usb serial) by having the USB MPS to be 512 bytes intead of default 64. The KConfig keys for these are not settable in prj.conf, but set depending on the USB bus speed in Kconfig.cdc/Kconfig.msc (conditioned by USB_DC_HAS_HS_SUPPORT)
So, I set  CONFIG_USB_DC_HAS_HS_SUPPORT=y  to enable this.
However, this then causes the usb setup to assert in
zephyr/drivers/usb/common/nrf_usbd_common/nrf_usbd_common.c :nrf_usbd_common_ep_max_packet_size_set()
as the MSC packet size of 512 is greater than the hardcoded value of NRF_USBD_COMMON_EPSIZE in the header file.
I don't see any mechanism to configure NRF_USBD_COMMON_EPSIZE based on the bus speed? How can I enable high-speed for the nrf USB driver and set CONFIG_USB_DC_HAS_HS_SUPPORT to use the MSC/CDC-ACM classes with the bigger buffers? 
Any ideas other than just hacking the nrf_usbd_common.h?
  • Hi BrianW,

    Hieu said:
    BrianW said:

    - why doesn't the DTS config fail when I set 'high-speed' as this is not supported on nrf5340?

    - why doesn't the Kconfig check fail for CONFIG_USB_DC_HAS_HS_SUPPORT=y (its usually not shy about complaining about config values it feels are in conflict)

    Both are very valid questions. Those facts bugged me too when I looked into the case yesterday.

    Let me try to ask our developers who work with Zephyr to see if they have any insight.

    I have some explanations from our developer. It turns out that the high-speed support in the legacy USB stack is... inadequate; and what we are seeing is a part of the several problems.

    That is why we invest effort into the USB Next stack to support USB High Speed with the newer devices instead.


    Regarding optimizing transfer speed, our developer recommends maximizing the CDC_ACM buffer size like you are already doing (CONFIG_USB_CDC_ACM_RINGBUF_SIZE); and use the UART Interrupt API instead of the Async API.

  • That is why we invest effort into the USB Next stack to support USB High Speed with the newer devices instead.

    Ok, understood. I don't really have a need for Hgh Speed currently as the data transfer speed issue is currently only related to DFU.

Related