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;