Hello,
we are using nrf5 SDK version is 17.0.2 and nrf52840.
Our product uses nrf52840 and its USB capabilities being configured as a composite device (HID keyboard + CDC ACM). The CDC ACM is used for a custom text protocol data transmission between the device and the PC. It's correctly working on Linux (Ubuntu) and Windows 10, but not on Mac OS X Catalina (10.15.6). We are not sure it's related only to Mac OS. The problem is that during data transmission the TX line hangs forever in NRF_ERROR_BUSY, which happens accidentally and the device can't recover that error unless "COM port" being reopened on the host machine. Meanwhile, RX continues working correctly. The general approach for sending data is the following (pseudo-code):
// Handling cdc acm events: ... case APP_USBD_CDC_ACM_USER_EVT_RX_DONE: NRF_LOG_INFO("APP_USBD_CDC_ACM_USER_EVT_RX_DONE"); process_incoming_data(); break; case APP_USBD_CDC_ACM_USER_EVT_TX_DONE: NRF_LOG_INFO("APP_USBD_CDC_ACM_USER_EVT_TX_DONE"); tx_done = true; tx_buffer_fill_size = 0; break; ... // main(): ... for (;;) { if (tx_done && tx_buffer_fill_size != 0) { ret_code_t ret = app_usbd_cdc_acm_write(&m_app_cdc_acm, tx_buffer, tx_buffer_fill_size); if (ret == NRF_ERROR_BUSY) { NRF_LOG_ERROR("Resource is busy"); } else if (ret == NRF_SUCCESS) { NRF_LOG_INFO("cdc_acm_write start"); } else { NRF_LOG_ERROR("cdc_acm_write error"); } } nrf_pwr_mgmt_run(); } ...
Typical logs could be the following:
APP_USBD_CDC_ACM_USER_EVT_RX_DONE cdc_acm_write start APP_USBD_CDC_ACM_USER_EVT_TX_DONE APP_USBD_CDC_ACM_USER_EVT_RX_DONE cdc_acm_write start APP_USBD_CDC_ACM_USER_EVT_TX_DONE APP_USBD_CDC_ACM_USER_EVT_RX_DONE cdc_acm_write start APP_USBD_CDC_ACM_USER_EVT_TX_DONE APP_USBD_CDC_ACM_USER_EVT_RX_DONE cdc_acm_write start APP_USBD_CDC_ACM_USER_EVT_RX_DONE Resource is busy APP_USBD_CDC_ACM_USER_EVT_RX_DONE Resource is busy and so on...
The problem is that the device couldn't recover from this state unless the port is being re-opened. On the host system, incoming data becomes lost at the same time when
app_usbd_cdc_acm_write stops producing APP_USBD_CDC_ACM_USER_EVT_TX_DONE events. We also tried to send "zero-length" packets right after sending packet with data, but it doesn't help.
Some important constants in sdk_config.h:
NRF_LOG_DEFERRED 1
APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED 1
APP_USBD_CDC_ACM_ZLP_ON_EPSIZE_WRITE 1
1) Is it possible to recover from the such situation?
2) Shouldn't nrf SDK produce error in a callback in the such situation?
3) Is it possible to debug this problem on a lower level and find an exact reason of the fault? CDC ACM logging doesn't provide enough of useful information.
4) Any other suggestion why it might happend and how to fix this?