raiden00pl commented on code in PR #9508:
URL: https://github.com/apache/nuttx/pull/9508#discussion_r1225250145
##########
arch/arm/src/nrf52/nrf52_usbd.c:
##########
@@ -1943,70 +1990,135 @@ static void nrf52_endepoutinterrupt(struct
nrf52_usbdev_s *priv)
static int nrf52_usbinterrupt(int irq, void *context, void *arg)
{
- struct nrf52_usbdev_s *priv = &g_usbdev;
+ struct nrf52_usbdev_s *priv = &g_usbdev;
+ struct nrf52_ep_s *privep = NULL;
+ uint32_t irqnow = 0;
+ uint32_t offset = 0;
+ int i = 0;
usbtrace(TRACE_INTENTRY(NRF52_TRACEINTID_USB), 0);
+ /* Handle all events */
+
+ for (i = 0; i < USBD_INT_ALL_NUM; i++)
+ {
+ /* Get EVENT offset */
+
+ offset = NRF52_USBD_EVENTS_USBRESET + 0x04 * i;
+
+ /* Get EVENT state */
+
+ irqnow |= nrf52_getreg(offset) << i;
+
+ /* Clear EVENT */
+
+ nrf52_putreg(0, offset);
+ }
+
/* USB reset interrupt */
- if (nrf52_getreg(NRF52_USBD_EVENTS_USBRESET))
+ if (irqnow & USBD_INT_USBRESET)
{
usbtrace(TRACE_INTDECODE(NRF52_TRACEINTID_DEVRESET), 0);
nrf52_usbreset(priv);
- nrf52_putreg(0, NRF52_USBD_EVENTS_USBRESET);
goto intout;
}
#ifdef CONFIG_USBDEV_SOFINTERRUPT
/* Handle SOF */
- if (nrf52_getreg(NRF52_USBD_EVENTS_SOF))
+ if (irqnow & USBD_INT_SOF)
{
usbtrace(TRACE_INTDECODE(NRF52_TRACEINTID_SOF), 0);
- nrf52_putreg(0, NRF52_USBD_EVENTS_SOF);
}
#endif
/* Handle USBEVENT */
- if (nrf52_getreg(NRF52_USBD_EVENTS_USBEVENT))
+ if (irqnow & USBD_INT_USBEVENT)
{
usbtrace(TRACE_INTDECODE(NRF52_TRACEINTID_USBEVENT), 0);
nrf52_eventinterrupt(priv);
- nrf52_putreg(0, NRF52_USBD_EVENTS_USBEVENT);
+ }
+
+ /* DMA transfer complete */
+
+ if (irqnow & NRF52_USBD_DMAIRQ)
+ {
+ nrf52_startdma_ack(priv);
}
/* Handle EP0SETUP */
- if (nrf52_getreg(NRF52_USBD_EVENTS_EP0SETUP))
+ if (irqnow & USBD_INT_EP0SETUP)
{
usbtrace(TRACE_INTDECODE(NRF52_TRACEINTID_EP0SETUP), 0);
nrf52_ep0setupinterrupt(priv);
- nrf52_putreg(0, NRF52_USBD_EVENTS_EP0SETUP);
}
/* Handle EP0DATADONE */
- if (nrf52_getreg(NRF52_USBD_EVENTS_EP0DATADONE))
+ if (irqnow & USBD_INT_EP0DATADONE)
{
usbtrace(TRACE_INTDECODE(NRF52_TRACEINTID_EP0DATADONE), 0);
nrf52_ep0datainterrupt(priv);
- nrf52_putreg(0, NRF52_USBD_EVENTS_EP0DATADONE);
}
+ /* Handle ENDEPOUT */
+
+ nrf52_endepoutinterrupt(priv, irqnow);
+
+ /* Handle ENDEPIN */
+
+ nrf52_endepininterrupt(priv, irqnow);
+
/* Handle EPDATA */
- if (nrf52_getreg(NRF52_USBD_EVENTS_EPDATA))
+ if (irqnow & USBD_INT_EPDATA)
{
usbtrace(TRACE_INTDECODE(NRF52_TRACEINTID_EPDATA), 0);
nrf52_epdatainterrupt(priv);
- nrf52_putreg(0, NRF52_USBD_EVENTS_EPDATA);
}
- /* Handle all END events */
+ /* Try to handle waiting OUT DMA requests */
- nrf52_endepininterrupt(priv);
- nrf52_endepoutinterrupt(priv);
+ if (priv->dmanow == false)
+ {
+ if (priv->dmaepoutwait)
+ {
+ for (i = 0; i < NRF52_NENDPOINTS; i++)
+ {
+ if (priv->dmaepoutwait & (1 << i))
+ {
+ priv->dmaepoutwait &= ~(1 << i);
+
+ privep = &priv->epout[i];
+ nrf52_epout_handle(priv, privep);
+ break;
+ }
+ }
+ }
+ }
+
+ /* Try to handle waiting IN DMA requests */
+
+ if (priv->dmanow == false)
Review Comment:
It can't be. EPOUT must be handled first and if there is a pending EPOUT
then the DMA will be taken (`priv->dmanow` set to `true` by
`nrf52_epout_handle()`) and the pending EPIN must be skipped in this interrupt
cycle.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]