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.