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

Switching off USB in a clean way

To the kind attention of Nordic support team,

I'm experiencing some problems switching off in a clean way the usbd library/usb driver/USB peripheral. I do need a clean switch off of everything comes after an app_usbd_init call in order to get everything like it was at the beginning and eventually redo a call to app_usbd_init again. I'm currently studying your usbd_hid_composite application as it comes from nRF5_SDK_15.2.0_9412b96. 

What is the recommended order should I call

nrf_drv_usbd_stop()
nrf_drv_power_usbevt_uninit()
nrf_drv_usbd_disable()
nrf_drv_usbd_uninit()
or should it suffice app_usbd_uninit(),

before going with another call to app_usbd_init()?

Could you please point me up to an example, if any, that has been made in order to accomplish this task? Otherwise it will take a while by debugging the state of the library.

Thanks for your kind attention

  • Hello,

    I'm experiencing some problems switching off in a clean way the usbd library/usb driver/USB peripheral

    Can you please elaborate?  What kind of problems are you experiencing?

    Have a look at the USBD Driver documentation it states: 

    In most cases, enabling and starting of the USBD driver will be processed in response to USB power events (see nrf_drv_power_usbevt_init). Using the POWER driver - legacy layer driver, USB can be initialized in the following way:

    static void power_usb_event_handler(nrf_drv_power_usb_evt_t event)
    {
        switch(event)
        {
        case NRF_DRV_POWER_USB_EVT_DETECTED:
            if(!nrf_drv_usbd_is_enabled())
            {
                nrf_drv_usbd_enable();
            }
            break;
        case NRF_DRV_POWER_USB_EVT_REMOVED:
            if(nrf_drv_usbd_is_started())
            {
                nrf_drv_usbd_stop();
            }
            if(nrf_drv_usbd_is_enabled())
            {
                nrf_drv_usbd_disable();
            }
            break;
        case NRF_DRV_POWER_USB_EVT_READY:
            if(!nrf_drv_usbd_is_started())
            {
                nrf_drv_usbd_start(true);
            }
            break;
        default:
            ASSERT(false);
        }
    }

    Example code that provides USB HID functionality using only the USBD driver can be found here: USB Device Example (examples\peripheral\usbd).

    Kind regards,
    Øyvind

  • Hi, I'd like to simply clean every usb initialization as it is done in the usbd_hid_composite sdk example.

    For example, if I try and call an app_usbd_uninit() at the end of your program, then I try to restart everything again as it is calling an app_usbd_init, I get an NRF_ERROR_INVALID_STATE inside the nrf_drv_usbd_init. 

  • When using the software I mentioned (usbd_hid_composite ) these are the routines called in order to have the usb up and running:

    1. app_usbd_init

    2. app_usbd_hid_kbd_class_inst_get

    3. app_usbd_class_append

    4. app_usbd_power_events_enable

    I have to do something like this:

    1. app_usbd_init

    2. app_usbd_hid_kbd_class_inst_get

    3. app_usbd_class_append

    4. app_usbd_power_events_enable

    // ... stop and restart everything again

    1. app_usbd_init

    2. app_usbd_hid_kbd_class_inst_get

    3. app_usbd_class_append

    4. app_usbd_power_events_enable

    My question is: what do you recommend in order to be able to do like that? What  the // ... should be?

    1. app_usbd_init

    2. app_usbd_hid_kbd_class_inst_get

    3. app_usbd_class_append

    4. app_usbd_power_events_enable

    nrf_drv_usbd_stop(); ?
    nrf_drv_power_usbevt_uninit(); ?

    nrf_drv_usbd_disable(); ?

    nrf_drv_usbd_uninit(); ?

    1. app_usbd_init

    2. app_usbd_hid_kbd_class_inst_get

    3. app_usbd_class_append

    4. app_usbd_power_events_enable

    Hope that my question is clear. Best regards 

  • It seems I got what I wanted, right now. My goal was to use the mentioned wanderful usbd_hid_composite as it is. Then, in some cases, I would like to force like a USB reset, and a new enumeration process. Also, the device should be able to re-present itself to the host device using a dynamically changed descriptor (accordingly to the application requirements).

    After the normal flow to have usb up and running:

    1. app_usbd_init

    2. app_usbd_hid_kbd_class_inst_get

    3. app_usbd_class_append

    4. app_usbd_power_events_enable

    I would need to stop the usb, dynamically change some of the usb descriptors and restart usb again.

    I'm just trying to do something like this:

    1. app_usbd_init

    2. app_usbd_hid_kbd_class_inst_get

    3. app_usbd_class_append

    4. app_usbd_power_events_enable

    nrf_drv_usbd_stop()

    nrf_drv_usbd_disable()

    change m_app_hid_kbd 

    app_usbd_class_remove to remove old istance

    app_usbd_hid_kbd_class_inst_get(&m_app_hid_kbd) // the updated instace

    app_usbd_class_append

    app_usbd_enable

    app_usbd_start

    Those things are working, as I see using an USB analyzer. Hope it is the standard procedure, that leaves that USB stack and peripheral in a consistent safe state. Could you convalidate this procedure?

    Thanks for your kind attention

Related