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

USB port disconnect requires power cycle before new connection

I developed a custom RF mesh to USB serial bridge. Right after boot, I receive all serial messages, but once the host closes the serial port and open it again, nothing comes out.

This is the application I'm using where I call a `usb_print()` function

https://github.com/nRFMesh/nRF52_Mesh/blob/8d2858650310cad7e3f256ee2ad59abb7fa580d4/applications/08_usb_dongle/main.c#L129

I've looked through the forum but could not find issues to map on my case. I would really appreciate to get a review of my event handling functions and hint on what could go wrong, as it's hard to investigate without a lead or a similar reference example.

For functions to look at, I provide both a link to the code line in github, so that it's possible to see the full program and a copy here for quick viewing.

As you can see in my makefile, I'm using 'nRF5_SDK_for_Thread_and_Zigbee_2.0.0_29775ac_min' and a patched 'nRF5_SDK_15.0.0_prf' for rf files which are not in the scope of this issue, the scope of this issue is USB only.

My `cdc_acm_user_ev_handler()` code

https://github.com/nRFMesh/nRF52_Mesh/blob/8d2858650310cad7e3f256ee2ad59abb7fa580d4/drivers/usb_print.c#L115

static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
                                    app_usbd_cdc_acm_user_event_t event)
{
    app_usbd_cdc_acm_t const * p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);

    switch (event)
    {
        case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
        {
            //This starts listening and notify an event immediatly when 'any' size of data is available
            app_usbd_cdc_acm_read_any(p_cdc_acm,m_rx_buffer,rx_buffer_size);
            g_is_port_open = true;
            break;
        }
        case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
            g_is_port_open = false;
            break;
        case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
            g_is_write_buffer_ready = true;
            usb_tx_from_buffer();
            break;
        case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
        {
            size_t size;
            ret_code_t ret;
            do
            {
                size = app_usbd_cdc_acm_rx_size(p_cdc_acm);     //get the number of bytes waiting in the buffer provided in the previous read call
                stream_to_message(m_rx_buffer,size);            //provide the data to the next layer
                ret = app_usbd_cdc_acm_read_any(p_cdc_acm,m_rx_buffer,rx_buffer_size);  //initiate the next listening
            } while (ret == NRF_SUCCESS);   //if ret is success, then another cycle of checking read data size using it and initiate listening
            break;
        }
        default:
            break;
    }
}

My `usbd_user_ev_handler()`  code

https://github.com/nRFMesh/nRF52_Mesh/blob/8d2858650310cad7e3f256ee2ad59abb7fa580d4/drivers/usb_print.c#L153

static void usbd_user_ev_handler(app_usbd_event_type_t event)
{
    switch (event)
    {
        case APP_USBD_EVT_DRV_SUSPEND:
            ////bsp_board_led_off(LED_USB_RESUME);
            break;
        case APP_USBD_EVT_DRV_RESUME:
            ////bsp_board_led_on(LED_USB_RESUME);
            break;
        case APP_USBD_EVT_STARTED:

            break;
        case APP_USBD_EVT_STOPPED:
            // -- app_usbd_disable(); -- commented as this would kill the device when the host disconnects the first connection
            ////bsp_board_leds_off();
            break;
        case APP_USBD_EVT_POWER_DETECTED:
            NRF_LOG_INFO("USB power detected");

            if (!nrf_drv_usbd_is_enabled())
            {
                app_usbd_enable();
            }
            break;
        case APP_USBD_EVT_POWER_REMOVED:
            NRF_LOG_INFO("USB power removed");
            app_usbd_stop();
            break;
        case APP_USBD_EVT_POWER_READY:
            NRF_LOG_INFO("USB ready");
            app_usbd_start();
            break;
        default:
            break;
    }
}

If the review does not reveal anything suspicious from first sight then a deeper question would be on how can I handle the 'APP_USBD_EVT_STOPPED' ? event ? disabling the device is obviously wrong as it won't be allow any further connection from the host.

Thanks in advance for any hint or feedback.

Parents Reply Children
Related