This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

USB CDC ACM with AUDIO class on Windows

I have successfully been using USB CDC ACM class alongside USB Audio with only a MIC feature available on Mac OS. However, on Windows, only USB CDC ACM enumerates in Device Manager. The Audio class enumerates with a failure "Device USB\VID****** had a problem starting". Any ideas what could be causing this discrepancy?

  • Hello, 

    Apologies for the late reply. I'm out on travel but will look into your case when I return to the office.

    Kind regards,
    Øyvind

  • Hi,

    I had the same problem and had posted a support ticket on this but with no reply so far.

    I just found the solution for my case so I thought to share.

    We need to include an "INTERFACE_ASSOCIATION DESCRIPTOR" (IAD) just before the "INTERFACE DESCRIPTOR" for the AudioClass Control Interface.

    On Windows, it works WITHOUT the IAD when there are NO CDC-ACM descriptors. However, once CDC-ACM descriptors are added, the AudioClass descriptors will NOT be parsed correctly during USB device enumeration. Adding the IAD solves this problem.

    Since you did not have the issues on Mac but then had it on Windows, perhaps it is a Windows problem.

  • Thank you for sharing. Could you help provide more details on where exactly to inject IAD descriptor in the USB Audio class? What goes into the descriptor and can I inject it using any of existing SDK API macros?

  • Hi,

    I tried to use their SDK but it is too convoluted for my liking. Tracing was particularly difficult with many levels of indirection and even some code were in .h files rather than in .c files. So I spent many days and nights ended up writing a bare metal version with only the minimal files from their SDK such as the startup code and bitfields etc only. What shocked me was when I got the same issues using my BareMetal version. That’s when I realized it was not their library issue.

    i will share my exact descriptors shortly and maybe help relook into their SDK to see where you would need to tweet to get it to work. Hopefully Nordic will incorporate as well into their updates.

  • Hi,

    I have prepared the file attached extracted based on what I used in my own bare metal source. Please see the static declarations for the descriptors at the end of the file. The extra IAD to be inserted is at line 214,215:

    test.h

    For the SDK (nRF5_SDK_16.0.0_98a08e2), I have not tested it but the place to modify is likely in "app_usbd_audio.c", in the function audio_feed_descriptors() at line 675. 

    Hope it helps.

    static bool audio_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
    app_usbd_class_inst_t const * p_inst,
    uint8_t * p_buff,
    size_t max_size)
    {
    static uint8_t ifaces = 0;
    ifaces = app_usbd_class_iface_count_get(p_inst);
    ASSERT(ifaces == 2);
    app_usbd_audio_t const * p_audio = audio_get(p_inst);

    APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);

    /* INSERT CODE HERE FOR THE IAD */

    /* CONTROL INTERFACE DESCRIPTOR */
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface

    static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
    p_cur_iface = app_usbd_class_iface_get(p_inst, 0);

    APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
    APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS); // bInterfaceClass = Audio
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL); // bInterfaceSubclass (Audio Control)
    APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED); // bInterfaceProtocol
    APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface

Related