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
No Data
Related