Is there a place to make suggestions for new releases of nRF5 SDK's or even contribute?
I've been using the current USBD CDC ACM library and needed to modify the app_usbd_cdc_acm.h and app_usbd_cdc_acm.c files to add support for SET_LINE_CODING class requests to create events in the cdc_acm_user_ev_handler. From the event I can extract the data rate, stop bits, parity and data bits requested from the host exactly when it occurs and update a UART module or make a copy of the data that can be processed in main later (in main is a must for my application); instead of polling the m_app_cdc_acm instance (m_app_cdc_acm.specific.p_data->ctx.line_coding) for changes in main, which would be unsafe. It appears the data is only stored in the m_app_cdc_acm instance to respond to GET_LINE_CODING requests.
The SET_LINE_CODING request's data is needed for USB to UART bridges and should be easily accessible in a finished CDC ACM library, are there any updates on the horizon?
Would be nice to get CONTROL_LINE_STATE class requests to generate user events also, or even the individual events for changes to DTR and RTS (I realise APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN is DTR).
I can't see any of these features, let me know if they already exist and I'm blind or there is a better way to go about this?
Cheers, John.
Example of changes to setup_req_class_out in app_usbd_cdc_acm.c:
static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst, app_usbd_setup_evt_t const * p_setup_ev) { app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst); app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm); switch (p_setup_ev->setup.bmRequest) { case APP_USBD_CDC_REQ_SET_LINE_CODING: { if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t)) { return NRF_ERROR_NOT_SUPPORTED; } // Modification ret_code_t ret = cdc_acm_req_out_datastage(p_inst, p_setup_ev); const app_usbd_cdc_acm_user_event_t ev = APP_USBD_CDC_ACM_USER_EVT_SET_LINE_CODING; user_event_handler(p_inst, ev); return ret; // Uncomment below for original //return cdc_acm_req_out_datastage(p_inst, p_setup_ev); // END } case APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE: { if (p_setup_ev->setup.wLength.w != 0) { return NRF_ERROR_NOT_SUPPORTED; } NRF_LOG_INFO("REQ_SET_CONTROL_LINE_STATE: 0x%x", p_setup_ev->setup.wValue.w); bool old_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ? true : false; p_cdc_acm_ctx->line_state = p_setup_ev->setup.wValue.w; bool new_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ? true : false; if (old_dtr == new_dtr) { return NRF_SUCCESS; } const app_usbd_cdc_acm_user_event_t ev = new_dtr ? APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN : APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE; user_event_handler(p_inst, ev); if (!new_dtr) { /*Abort DATA endpoints on port close */ nrf_drv_usbd_ep_t ep; ep = data_ep_in_addr_get(p_inst); nrf_drv_usbd_ep_abort(ep); ep = data_ep_out_addr_get(p_inst); nrf_drv_usbd_ep_abort(ep); // Set rx transfers configuration to default state. p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL; p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL; p_cdc_acm_ctx->bytes_left = 0; p_cdc_acm_ctx->bytes_read = 0; p_cdc_acm_ctx->last_read = 0; p_cdc_acm_ctx->cur_read = 0; p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf; } return NRF_SUCCESS; } default: break; } return NRF_ERROR_NOT_SUPPORTED; }
Example of changes to app_usbd_cdc_acm_user_event_t in app_usbd_cdc_acm.h:
typedef enum app_usbd_cdc_acm_user_event_e { APP_USBD_CDC_ACM_USER_EVT_RX_DONE, /**< User event RX_DONE. */ APP_USBD_CDC_ACM_USER_EVT_TX_DONE, /**< User event TX_DONE. */ APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN, /**< User event PORT_OPEN. */ APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE, /**< User event PORT_CLOSE. */ // Modification APP_USBD_CDC_ACM_USER_EVT_SET_LINE_CODING // END } app_usbd_cdc_acm_user_event_t;