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.