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

SPI/USB will drop large multiple of packets in a row. Can't keep up with 1 Mbps on nrf52840 dk?

Hi,

I'm using an nrf52840 dk to query another device over spi and then pipe the response back USB to a host PC. Ideally, we're piping data at 1 Mbps (which should be very much doable for USB) and for a little bit, it will work perfectly. Then randomly we'll miss 4 kB worth of packets. After plotting the data stream it's become apparent that it's quite bad. We consistently lose at least a 3rd of our packets. Furthermore, the lost data is lost in chunks. Here's an example of a 'noisy' sine wave that we sent through the serial link.

I don't believe it's an issue with the spi because I've tied an oscope to the spi pins and observed perfect spi packets being transmitted at a rate of 1 Mbps (but I could only observe maybe 20 packets at a time and didn't decode them so ...). Given that we're missing consecutive packets, and it seems to happen more or less regularly, I think this might have to do with a USB overhead issue.  

Is there something I'm missing about USB? Is there an ideal packet size that I should send over the USB at a given moment? I've played with the following settings but they've seem to make no difference:

  • APP_USBD_CONFIG_SOF_HANDLING_MODE (tried both normal and compress queue)
  • APP_USBD_CONFIG_EVENT_QUEUE_SIZE (Tried setting this to the max, 64, in case I was trying to send packets too frequently and they needed a larger queue)

I'm pretty new with USB communication so any help would be amazing! 

EDIT: I've started saving the data to a buffer on the dev kit and reading it all out at once (ideally this decouples the SPI and USB). While I'm missing significantly fewer packets, I am still missing a few. Now I'm getting 75%-85% of all my packets. So I guess this means there is some function that's interrupting the SPI's interrupt, possibly? I've tried bumping the SPI interrupts priority but it doesn't seem to have changed anything. I'm completely out of ideas so any pointers would be a huge help.

Thanks,

Ryan

  • Hi,

     

    ryerye120 said:
    Do you think these missed packets are related to how often I run _queue_process()?

    It could be, but without seeing the whole picture, I would only be guessing.

      

    ryerye120 said:
    Also what did you mean by "retry function". I interpreted as checking the usb_write() return code. So now, my code will try to such that whenever a USB transfer returns something NOT(NRF_SUCCESS) then I run _queue_process() instead and then wait till the next iteration of my main loop before trying another USB transfer.

    Since you're using the queue, events and handling related to usbd is performed in iterations, as per how often the _queue_process() function is called. If there's something blocking the function from executing (like a delay in your main loop or similar), handling of the USBD traffic would also be delayed.

    Could you share more of your code so I can have a look, or even better; be able to reproduce the problem?

     

    Do you have a log file or similar which has timestamped data on the host side, to see which transfers are missing? Is the data missing, as in you see "skipped packets", or is the data delayed?

     

    Kind regards,

    Håkon

Related