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
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
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
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.