USBD endpoint transfer completion event.

In my NRF52840 based device using NRF5 SDK 17.1.0, I notice that sometimes this loop in the nrfx usbd driver code of the SDK doesn't finish:

[modules/nrfx/drivers/src/nrfx_usbd.c: 1444]

/* There is a lot of USBD registers that cannot be accessed during EasyDMA transfer.
 * This is quick fix to maintain stability of the stack.
 * It cost some performance but makes stack stable. */
while (!nrf_usbd_event_check(nrfx_usbd_ep_to_endevent(ep)) &&
       !nrf_usbd_event_check(NRF_USBD_EVENT_USBRESET))
{
    /* Empty */
}

It seems the transfer-end EasyDMA hardware-event isn't generated reliably in all situations. This happens mostly with small transfers on interrupt-in-endpoints and only with some usb hosts (notably raspberry pi). This is a big problem, because this function is called from interrupt context (and therefore should actually not do such busy waiting).

Is this a known issue and is there a workaround? I tried to enter the loop conditionally only when transfer size is bigger than 4 or 8 bytes, which seems to fix this, but that causes other problems.  I tried to pad the 2-byte transfer to 8 bytes, but that doesn't change anything. I think it could work to skip the loop for interrupt endpoints, but this routine handles interrupt and bulk endpoints the same; there is no USBD register that keeps track of bulk vs. interrupt endpoints.

I know that NRF5 sdk is out of support, but my project was built with it and it isn't easy to move to NRF-Connect SDK.

Parents
  • This is for an outgoing notification to the host, so it should be ENDEPIN. The endpoint address is 0x83 and the ep_to_endevent(ep) results in 0x114.

    Since this is involving interrupts, it's hard to see if anything else reset the end event before the handler code has the chance to look at it, but since this is code run in interrupt context, I guess the likelihood is very minimal.

    I will try to find an example that is suitable to demonstrate this issue. Maybe you have a suggestion which one?

    I don't have a working NC SDK at my disposal now. But it looks like that code didn't change much between nRF5 SDK and NRF Connect.

Reply
  • This is for an outgoing notification to the host, so it should be ENDEPIN. The endpoint address is 0x83 and the ep_to_endevent(ep) results in 0x114.

    Since this is involving interrupts, it's hard to see if anything else reset the end event before the handler code has the chance to look at it, but since this is code run in interrupt context, I guess the likelihood is very minimal.

    I will try to find an example that is suitable to demonstrate this issue. Maybe you have a suggestion which one?

    I don't have a working NC SDK at my disposal now. But it looks like that code didn't change much between nRF5 SDK and NRF Connect.

Children
No Data
Related