app_usbd_cdc_acm_read_any never worked for me on RX

On the NRF52840 dongle am building a protocol on USB CDC ACM.

Using app_usbd_cdc_acm_read to read one byte at a time works perfectly.

However, I can seem to make app_usbd_cdc_acm_read_any work.

Pseudo-code for app_usbd_cdc_acm_read:

static uint8_t one_byte;

static void on_byte_read() {
    // TODO: Process that one_byte
}

static void usb_serial_process_read() {
    for (;;) {
        ret_code_t ret = app_usbd_cdc_acm_read(&m_app_cdc_acm_data,
                                                   &one_byte,
                                                   1);
        if (ret == NRF_SUCCESS) {
            on_byte_read();
        } else if (ret == NRF_ERROR_IO_PENDING) {
            break;
        } else {
            // TODO: Handle USB rx error
            break;
        }
    }
}

static void cdc_acm_data_ev_handler(app_usbd_class_inst_t const * p_inst,
                                    app_usbd_cdc_acm_user_event_t event) {
    switch (event)
    {
        case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
        {
            usb_serial_process_read();
            break;
        }
        case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
            // TODO
            break;
        case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
        {
            on_byte_read();     // one_byte is already read
            usb_serial_process_read();
        }
            break;
        case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
            // TODO: handle TX
            break;
        default:
            break;
    }
}

However, using app_usbd_cdc_acm_read_any always failed to receive.

#define BUF_LEN 16
uint8_t buffer[BUF_LEN];

static void on_incoming(size_t len) {
    // TODO: Process buffer and len
}

static void usb_serial_process_read(size_t total) {
    for (;;) {
        ret_code_t ret = app_usbd_cdc_acm_read_any(&m_app_cdc_acm_data,
                                                   buffer,
                                                   BUF_LEN);
        if (ret == NRF_SUCCESS) {
            size_t size = app_usbd_cdc_acm_rx_size(&m_app_cdc_acm_data);
            on_incoming(size);
        } else if (ret == NRF_ERROR_IO_PENDING) {
            break;
        } else {
            // TODO: Error handling
            break;
        }
    }
}

static void cdc_acm_data_ev_handler(app_usbd_class_inst_t const * p_inst,
                                    app_usbd_cdc_acm_user_event_t event) {
    switch (event)
    {
        case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
        {
            usb_serial_process_read();
            break;
        }
        case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
            break;
        case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
        {
            size_t size = app_usbd_cdc_acm_rx_size(&m_app_cdc_acm_data);
            on_incoming(size);
            usb_serial_process_read();
        }
            break;
        case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
            // TODO: Handle TX
            break;
        default:
            break;
    }
}

What am I missing?

Related