This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Custom USB Device Endpoint doesn't Read After first Transaction

Hello I'm making a custom usb device class with 1 IN & OUT Bulk endpoints running on a nrf52840 with 340. The device reads the data correctly that are being sent by the host - from an OUT event- but it doesn't seem to respond on later transfers.

There is no crash - Code is still running I can send IN requests with no problem and the main loop seems to be executing just fine.

This is the read code that gets called from the event handler on an APP_USBD_EVT_DRV_EPTRANSFER event.

static ret_code_t antusb_endpoint_ev(app_usbd_class_inst_t const *  p_inst,
                                      app_usbd_complex_evt_t const * p_event)
{
    ret_code_t ret;
    app_usbd_antusb_t const * p_antusb= antusb_get(p_inst);
    app_usbd_antusb_ctx_t *   p_antusb_ctx = antusb_ctx_get(p_antusb);


    if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
    {
        /* not very relevent :P */
    }

    if (NRF_USBD_EPOUT_CHECK(p_event->drv_evt.data.eptransfer.ep))
    {
        NRF_LOG_INFO("OUT Transfer %i Status: %i", p_event->drv_evt.data.eptransfer.ep, p_event->drv_evt.data.eptransfer.status);

        switch (p_event->drv_evt.data.eptransfer.status)
        {
            case NRF_USBD_EP_OK:
                //ret = antusb_rx_block_finished(p_inst);
                NRF_LOG_INFO("EPOUT_DATA: %02x done", p_event->drv_evt.data.eptransfer.ep);
                user_event_handler(p_inst, APP_USBD_ANTUSB_USER_EVT_RX_DONE);
                return ret;

            case NRF_USBD_EP_WAITING:
            {
                  p_antusb_ctx->rx_buf_size = nrf_usbd_epout_size_get(p_event->drv_evt.data.eptransfer.ep);

                  /* Recieve data */
                  NRF_DRV_USBD_TRANSFER_OUT(
                      transfer, p_antusb_ctx->rx_buf, p_antusb_ctx->rx_buf_size
                  );
                  CRITICAL_REGION_ENTER();
                  ret = nrf_drv_usbd_ep_transfer(p_event->drv_evt.data.eptransfer.ep, &transfer);
                  if (ret == NRF_SUCCESS)
                  {
                        /* ... */
                  }
                  CRITICAL_REGION_EXIT();
                  return ret;
            }
            case NRF_USBD_EP_ABORTED:
                return NRF_SUCCESS;
            default:
                return NRF_ERROR_INTERNAL;
        }
    }

    return NRF_ERROR_NOT_SUPPORTED;
}

Parents Reply Children
  • Yes I call app_usbd_antusb_read but It's much more simpler than the CDC ACM one's. 

    ret_code_t app_usbd_antusb_read(app_usbd_antusb_t const *     p_antusb,
                                      ANT_MESSAGE * const         p_antmsg)
    {
        ASSERT(p_antusb != NULL);
        ASSERT(p_antmsg != NULL);
    
        ret_code_t ret = NRF_SUCCESS;
    
        app_usbd_antusb_ctx_t * p_antusb_ctx = antusb_ctx_get(p_antusb);
        const uint8_t* rx_buf = p_antusb_ctx->rx_buf;
        const uint8_t rx_size =  p_antusb_ctx->rx_buf_size;
    
        NRF_LOG_INFO("Reading Buffer: (%i)", rx_size);
        NRF_LOG_HEXDUMP_INFO(p_antusb_ctx->rx_buf, rx_size);
    
        if (rx_buf[0] != MESG_TX_SYNC)
        {
            NRF_LOG_ERROR("Rx buffer doesn't start with sync");
            return NRF_ERROR_INTERNAL;
        }
        
        const unsigned total_mesglen = rx_buf[1] + MESG_SYNC_SIZE + MESG_SIZE_SIZE + MESG_ID_SIZE;
        const uint8_t checksum = rx_buf[total_mesglen];
        
    
        memcpy(p_antmsg->aucMessage, rx_buf + 1,  total_mesglen - 1);
    
        return NRF_SUCCESS;
    }

  • Try calling app_usbd_ep_handled_transfer() at the end of your app_usbd_antusb_read() function.

Related