diff --git a/arch/risc-v/src/mpfs/hardware/mpfs_usb.h b/arch/risc-v/src/mpfs/hardware/mpfs_usb.h index f6c6a5b664b..bdbda06d4bb 100644 --- a/arch/risc-v/src/mpfs/hardware/mpfs_usb.h +++ b/arch/risc-v/src/mpfs/hardware/mpfs_usb.h @@ -27,7 +27,7 @@ #define SOFT_RESET_REG_MASK 0x03u -#define MPFS_USB_NENDPOINTS 8 /* 4 IN and 4 OUT endpoints */ +#define MPFS_USB_NENDPOINTS 9 /* EP0 + 4x IN and 4x OUT EPs */ #define MPFS_USB_MAXPACKETSIZE(ep) 64 #define MPFS_USB_MAXPACKETSIZE_HS(ep) 512 #define MPFS_EP0_MAXPACKET 64 diff --git a/arch/risc-v/src/mpfs/mpfs_usb.c b/arch/risc-v/src/mpfs/mpfs_usb.c index e29b8b1043c..956dc634e64 100644 --- a/arch/risc-v/src/mpfs/mpfs_usb.c +++ b/arch/risc-v/src/mpfs/mpfs_usb.c @@ -138,10 +138,11 @@ #define mpfs_rqempty(q) ((q)->head == NULL) #define mpfs_rqpeek(q) ((q)->head) -#define MPFS_EPSET_ALL (0xff) /* All endpoints */ -#define MPFS_EPSET_NOTEP0 (0xfe) /* All endpoints except EP0 */ +#define MPFS_EPSET_ALL (0x1ff) /* All endpoints */ +#define MPFS_EPSET_NOTEP0 (0x1fe) /* All endpoints except EP0 */ #define MPFS_EP_BIT(ep) (1 << (ep)) #define MPFS_MAX_MULTIPACKET_SIZE (0x3fff) +#define MPFS_EPIN_START (MPFS_USB_NENDPOINTS / 2) /**************************************************************************** * Private Types @@ -652,9 +653,19 @@ static int mpfs_req_wrsetup(struct mpfs_usbdev_s *priv, uint8_t epno; int nbytes; int ret; + int idx; epno = USB_EPNO(privep->ep.eplog); + if (USB_ISEPIN(privep->ep.eplog)) + { + idx = epno + MPFS_EPIN_START; + } + else + { + idx = epno; + } + mpfs_putreg8(epno, MPFS_USB_INDEX); /* Get the number of bytes remaining to be sent. */ @@ -686,8 +697,8 @@ static int mpfs_req_wrsetup(struct mpfs_usbdev_s *priv, /* Setup TX transfer using ep configured maxpacket size */ - priv->eplist[epno].descb[1]->addr = (uintptr_t)buf; - packetsize = priv->eplist[epno].descb[1]->pktsize; + priv->eplist[idx].descb[1]->addr = (uintptr_t)buf; + packetsize = priv->eplist[idx].descb[1]->pktsize; /* Set automatic ZLP sending if requested on req */ @@ -696,7 +707,7 @@ static int mpfs_req_wrsetup(struct mpfs_usbdev_s *priv, /* Handle this properly when DMA supported */ } - priv->eplist[epno].descb[1]->pktsize = packetsize; + priv->eplist[idx].descb[1]->pktsize = packetsize; /* Indicate that we are in the sending state */ @@ -707,6 +718,7 @@ static int mpfs_req_wrsetup(struct mpfs_usbdev_s *priv, ret = mpfs_write_tx_fifo(buf, packetsize, epno); if (ret != OK) { + privep->epstate = USB_EPSTATE_IDLE; return ret; } @@ -731,6 +743,7 @@ static int mpfs_req_wrsetup(struct mpfs_usbdev_s *priv, ret = mpfs_write_tx_fifo(buf, nbytes, epno); if (ret != OK) { + privep->epstate = USB_EPSTATE_IDLE; return ret; } } @@ -906,6 +919,7 @@ static int mpfs_req_write(struct mpfs_usbdev_s *priv, ret = mpfs_req_wrsetup(priv, privep, privreq); if (ret != OK) { + mpfs_req_complete(privep, ret); return ret; } } @@ -1711,6 +1725,7 @@ static int mpfs_ep_submit(struct usbdev_ep_s *ep, struct usbdev_req_s *req) req->result = -EINPROGRESS; req->xfrd = 0; privreq->inflight = 0; + flags = enter_critical_section(); /* Handle IN (device-to-host) requests. NOTE: If the class device is @@ -1993,6 +2008,7 @@ static int mpfs_ep_stallresume(struct usbdev_ep_s *ep, bool resume) * Input Parameters: * priv - USB device abstraction * epset - Set of bits, one bit reflects one endpoint + * in - If the EP is direction IN * * Returned Value: * Endpoint structure or NULL in case of error @@ -2000,7 +2016,7 @@ static int mpfs_ep_stallresume(struct usbdev_ep_s *ep, bool resume) ****************************************************************************/ static inline struct mpfs_ep_s * -mpfs_ep_reserve(struct mpfs_usbdev_s *priv, uint8_t epset) +mpfs_ep_reserve(struct mpfs_usbdev_s *priv, uint16_t epset, bool in) { struct mpfs_ep_s *privep = NULL; irqstate_t flags; @@ -2008,15 +2024,34 @@ mpfs_ep_reserve(struct mpfs_usbdev_s *priv, uint8_t epset) flags = enter_critical_section(); epset &= priv->epavail; + if (epset != 0) { /* Select the lowest bit in the set of matching, available endpoints * (skipping EP0) */ - for (epndx = 1; epndx < MPFS_USB_NENDPOINTS; epndx++) + int max; + + if (in) { - uint8_t bit = MPFS_EP_BIT(epndx); + /* 5, 6, 7 and 8 */ + + max = MPFS_USB_NENDPOINTS; + } + else + { + /* 1, 2, 3 and 4 */ + + max = MPFS_EPIN_START + 1; + } + + for (epndx = 1 + (MPFS_USB_NENDPOINTS / 2) * in; + epndx < max; + epndx++) + { + uint16_t bit = MPFS_EP_BIT(epndx); + if ((epset & bit) != 0) { /* Mark the endpoint no longer available */ @@ -2033,6 +2068,8 @@ mpfs_ep_reserve(struct mpfs_usbdev_s *priv, uint8_t epset) } } + DEBUGASSERT(privep != NULL); + leave_critical_section(flags); return privep; } @@ -2088,9 +2125,14 @@ static struct usbdev_ep_s *mpfs_allocep(struct usbdev_s *dev, uint8_t epno, epset = MPFS_EP_BIT(epno); } + if (in) + { + epset <<= MPFS_EPIN_START; + } + /* Check if the selected endpoint number is available */ - privep = mpfs_ep_reserve(priv, epset); + privep = mpfs_ep_reserve(priv, epset, in); if (privep == NULL) { return NULL; @@ -2509,6 +2551,7 @@ static void mpfs_ep0_setup(struct mpfs_usbdev_s *priv) uint8_t epno; int nbytes = 0; /* Assume zero-length packet */ int ret; + int idx; /* Terminate any pending requests */ @@ -2570,6 +2613,15 @@ static void mpfs_ep0_setup(struct mpfs_usbdev_s *priv) case USB_REQ_RECIPIENT_ENDPOINT: { epno = USB_EPNO(index.b[LSB]); + if (USB_ISEPIN(index.b[LSB])) + { + idx = epno + MPFS_EPIN_START; + } + else + { + idx = epno; + } + usbtrace(TRACE_INTDECODE(MPFS_TRACEINTID_GETSTATUS), epno); if (epno >= MPFS_USB_NENDPOINTS) { @@ -2579,7 +2631,7 @@ static void mpfs_ep0_setup(struct mpfs_usbdev_s *priv) } else { - privep = &priv->eplist[epno]; + privep = &priv->eplist[idx]; response.w = 0; /* Not stalled */ nbytes = 2; /* Response size: 2 bytes */ @@ -2665,7 +2717,16 @@ static void mpfs_ep0_setup(struct mpfs_usbdev_s *priv) if (epno < MPFS_USB_NENDPOINTS && index.b[MSB] == 0 && value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) { - privep = &priv->eplist[epno]; + if (USB_ISEPIN(index.b[LSB])) + { + idx = epno + MPFS_EPIN_START; + } + else + { + idx = epno; + } + + privep = &priv->eplist[idx]; privep->halted = false; ret = mpfs_ep_resume(privep); @@ -2719,7 +2780,16 @@ static void mpfs_ep0_setup(struct mpfs_usbdev_s *priv) if (epno < MPFS_USB_NENDPOINTS && index.b[MSB] == 0 && value.w == USB_FEATURE_ENDPOINTHALT && len.w == 0) { - privep = &priv->eplist[epno]; + if (USB_ISEPIN(index.b[LSB])) + { + idx = epno + MPFS_EPIN_START; + } + else + { + idx = epno; + } + + privep = &priv->eplist[idx]; privep->halted = true; ret = mpfs_ep_stall(privep); @@ -3035,7 +3105,10 @@ static void mpfs_ep_rx_interrupt(struct mpfs_usbdev_s *priv, int epno) static void mpfs_ep_tx_interrupt(struct mpfs_usbdev_s *priv, int epno) { struct mpfs_ep_s *privep; - privep = &priv->eplist[epno]; + + privep = &priv->eplist[epno + MPFS_EPIN_START]; + + DEBUGASSERT((epno + MPFS_EPIN_START) < MPFS_USB_NENDPOINTS); mpfs_putreg8(epno, MPFS_USB_INDEX); @@ -3080,14 +3153,13 @@ static void mpfs_ep_tx_interrupt(struct mpfs_usbdev_s *priv, int epno) * * Input Parameters: * priv - USB device abstraction - * epno - The endpoint number * * Returned Value: * None * ****************************************************************************/ -static void mpfs_ctrl_ep_interrupt(struct mpfs_usbdev_s *priv, int epno) +static void mpfs_ctrl_ep_interrupt(struct mpfs_usbdev_s *priv) { struct mpfs_ep_s *privep; uint16_t count0; @@ -3096,9 +3168,9 @@ static void mpfs_ctrl_ep_interrupt(struct mpfs_usbdev_s *priv, int epno) /* Get the endpoint structure */ - privep = &priv->eplist[epno]; + privep = &priv->eplist[EP0]; - mpfs_putreg8(epno, MPFS_USB_INDEX); + mpfs_putreg8(EP0, MPFS_USB_INDEX); /* Make sure we're in device mode */ @@ -3198,8 +3270,6 @@ static void mpfs_ctrl_ep_interrupt(struct mpfs_usbdev_s *priv, int epno) { uint16_t rlen; - DEBUGASSERT(epno == EP0); - /* Yes.. back to the IDLE state */ privep->epstate = USB_EPSTATE_IDLE; @@ -3311,7 +3381,7 @@ static int mpfs_usb_interrupt(int irq, void *context, void *arg) if ((pending_tx_ep & 0x01) != 0) { - mpfs_ctrl_ep_interrupt(priv, 0); + mpfs_ctrl_ep_interrupt(priv); } if (pending_tx_ep != 0) @@ -3667,7 +3737,14 @@ static void mpfs_sw_setup(struct mpfs_usbdev_s *priv) priv->eplist[epno].ep.ops = &g_epops; priv->eplist[epno].dev = priv; - priv->eplist[epno].ep.eplog = epno; + if (epno < (MPFS_EPIN_START + 1)) + { + priv->eplist[epno].ep.eplog = epno; + } + else + { + priv->eplist[epno].ep.eplog = epno - MPFS_EPIN_START; + } /* We will use a maxpacket size for supported for each endpoint */ diff --git a/boards/risc-v/mpfs/common/src/mpfs_composite.c b/boards/risc-v/mpfs/common/src/mpfs_composite.c index c7dfe447f1d..f280ab32ba2 100644 --- a/boards/risc-v/mpfs/common/src/mpfs_composite.c +++ b/boards/risc-v/mpfs/common/src/mpfs_composite.c @@ -252,8 +252,8 @@ void *board_composite_connect(int port, int configid) /* Endpoints */ dev[0].devinfo.epno[CDCACM_EP_BULKIN_IDX] = 3; - dev[0].devinfo.epno[CDCACM_EP_BULKOUT_IDX] = 4; - dev[0].devinfo.epno[CDCACM_EP_INTIN_IDX] = 5; + dev[0].devinfo.epno[CDCACM_EP_BULKOUT_IDX] = 3; + dev[0].devinfo.epno[CDCACM_EP_INTIN_IDX] = 4; /* Count up the base numbers */