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

USB throughput for nRF52840

I have developed USB firmware for the 840 based on the USBD example so that we can use WINUSB (WCID) for the host.  The design is for USB 2.0 full speed with EPIN1 for device to host transfers and EPOUT1 for host to device transfers The firmware passes test for 60, 64 and 192 byte tests when they are manually triggered from a Windows test tool we wrote.  I just moved onto loop testing to validate throughput and the device seems unable to work at speed with more than 64 bytes in a transfer (tested at 1 , 10 and 100 MS rates).  I've examined the descriptor file (usbd_desc.c) and the USB code (usbd.c) but can't find an issue.  I am suspicious of how I handle receive packet for NRF_DR_USBD_EPOUT2 in the event handler but it does work with the manually triggered testing.  attached is a zip of my project (I am using the template example as a base).g4_boost_snapshot_041320_0912AM_start of day.zip

Parents
  • Hi,

      

    henryh said:
    I am using v16

    That is good.

    Do you have performance issues with sizes ending up in a short packet or ZLP?

    By looking at usbd.c::usbd_send_data_to_host(), it seems that ZLP isn't handled.

    Try implementing something like this when sending:

        else
        {
          // Send data
          usb_tx_xfer.p_data.tx = buff;
          usb_tx_xfer.size = size;
    
          tx_flag = true;
          /* Check if ZLP flag should be set */
          if ((size > NRF_DRV_USBD_EPSIZE) && (size % NRF_DRV_USBD_EPSIZE == 0)) 
          {
            usb_tx_xfer.flags |= NRFX_USBD_TRANSFER_ZLP_FLAG;
          } else {
            /* ZLP not needed, in case your structure is using global memory and not stacked, we clear the .flags */
            usb_tx_xfer.flags = 0;
          }
          ret_val=nrf_drv_usbd_ep_transfer(NRF_DRV_USBD_EPIN1,&usb_tx_xfer);
        
          ret_val=NRF_SUCCESS;
        }

     

    Kind regards,

    Håkon

Reply
  • Hi,

      

    henryh said:
    I am using v16

    That is good.

    Do you have performance issues with sizes ending up in a short packet or ZLP?

    By looking at usbd.c::usbd_send_data_to_host(), it seems that ZLP isn't handled.

    Try implementing something like this when sending:

        else
        {
          // Send data
          usb_tx_xfer.p_data.tx = buff;
          usb_tx_xfer.size = size;
    
          tx_flag = true;
          /* Check if ZLP flag should be set */
          if ((size > NRF_DRV_USBD_EPSIZE) && (size % NRF_DRV_USBD_EPSIZE == 0)) 
          {
            usb_tx_xfer.flags |= NRFX_USBD_TRANSFER_ZLP_FLAG;
          } else {
            /* ZLP not needed, in case your structure is using global memory and not stacked, we clear the .flags */
            usb_tx_xfer.flags = 0;
          }
          ret_val=nrf_drv_usbd_ep_transfer(NRF_DRV_USBD_EPIN1,&usb_tx_xfer);
        
          ret_val=NRF_SUCCESS;
        }

     

    Kind regards,

    Håkon

Children
No Data
Related