mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 15:22:18 +08:00
Fixes for the STM32 OTG FS device driver
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4583 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -153,7 +153,7 @@
|
|||||||
#define STM32_OTGFS_DIEPCTL2_OFFSET 0x0940 /* Device control IN endpoint 3 control register */
|
#define STM32_OTGFS_DIEPCTL2_OFFSET 0x0940 /* Device control IN endpoint 3 control register */
|
||||||
#define STM32_OTGFS_DIEPCTL3_OFFSET 0x0960 /* Device control IN endpoint 4 control register */
|
#define STM32_OTGFS_DIEPCTL3_OFFSET 0x0960 /* Device control IN endpoint 4 control register */
|
||||||
|
|
||||||
#define STM32_OTGFS_DIEPINT_OFFSET(n) 0x0908 /* Device endpoint-n interrupt register */
|
#define STM32_OTGFS_DIEPINT_OFFSET(n) (0x0908 + ((n) << 5))
|
||||||
#define STM32_OTGFS_DIEPINT0_OFFSET 0x0908 /* Device endpoint-0 interrupt register */
|
#define STM32_OTGFS_DIEPINT0_OFFSET 0x0908 /* Device endpoint-0 interrupt register */
|
||||||
#define STM32_OTGFS_DIEPINT1_OFFSET 0x0928 /* Device endpoint-1 interrupt register */
|
#define STM32_OTGFS_DIEPINT1_OFFSET 0x0928 /* Device endpoint-1 interrupt register */
|
||||||
#define STM32_OTGFS_DIEPINT2_OFFSET 0x0948 /* Device endpoint-2 interrupt register */
|
#define STM32_OTGFS_DIEPINT2_OFFSET 0x0948 /* Device endpoint-2 interrupt register */
|
||||||
@@ -171,7 +171,7 @@
|
|||||||
#define STM32_OTGFS_DTXFSTS2_OFFSET 0x0958 /* Device OUT endpoint-2 transfer size register */
|
#define STM32_OTGFS_DTXFSTS2_OFFSET 0x0958 /* Device OUT endpoint-2 transfer size register */
|
||||||
#define STM32_OTGFS_DTXFSTS3_OFFSET 0x0978 /* Device OUT endpoint-3 transfer size register */
|
#define STM32_OTGFS_DTXFSTS3_OFFSET 0x0978 /* Device OUT endpoint-3 transfer size register */
|
||||||
|
|
||||||
#define STM32_OTGFS_DOEP_OFFSET(n) 0x0b00 + ((n) << 5))
|
#define STM32_OTGFS_DOEP_OFFSET(n) (0x0b00 + ((n) << 5))
|
||||||
#define STM32_OTGFS_DOEPCTL_EPOFFSET 0x0000 /* Device control OUT endpoint 0 control register */
|
#define STM32_OTGFS_DOEPCTL_EPOFFSET 0x0000 /* Device control OUT endpoint 0 control register */
|
||||||
#define STM32_OTGFS_DOEPINT_EPOFFSET 0x0008 /* Device endpoint-x interrupt register */
|
#define STM32_OTGFS_DOEPINT_EPOFFSET 0x0008 /* Device endpoint-x interrupt register */
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,7 @@
|
|||||||
/* Trace interrupt codes */
|
/* Trace interrupt codes */
|
||||||
|
|
||||||
#define STM32_TRACEINTID_USB 1 /* USB Interrupt entry/exit */
|
#define STM32_TRACEINTID_USB 1 /* USB Interrupt entry/exit */
|
||||||
|
#define STM32_TRACEINTID_INTPENDING 2 /* On each pass through the loop */
|
||||||
|
|
||||||
#define STM32_TRACEINTID_EPOUT (10 + 0) /* First level interrupt decode */
|
#define STM32_TRACEINTID_EPOUT (10 + 0) /* First level interrupt decode */
|
||||||
#define STM32_TRACEINTID_EPIN (10 + 1)
|
#define STM32_TRACEINTID_EPIN (10 + 1)
|
||||||
@@ -792,7 +793,9 @@ static void stm32_ep0in_activate(void)
|
|||||||
|
|
||||||
/* Clear global IN NAK */
|
/* Clear global IN NAK */
|
||||||
|
|
||||||
stm32_putreg(OTGFS_DCTL_CGINAK, STM32_OTGFS_DCTL);
|
regval = stm32_getreg(STM32_OTGFS_DIEPCTL0);
|
||||||
|
regval |= OTGFS_DCTL_CGINAK;
|
||||||
|
stm32_putreg(regval, STM32_OTGFS_DCTL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
@@ -807,8 +810,8 @@ static void stm32_ep0out_ctrlsetup(FAR struct stm32_usbdev_s *priv)
|
|||||||
{
|
{
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
|
||||||
regval = (USB_SIZEOF_CTRLREQ * 3 << OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT) ||
|
regval = (USB_SIZEOF_CTRLREQ * 3 << OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT) |
|
||||||
(OTGFS_DOEPTSIZ0_PKTCNT) ||
|
(OTGFS_DOEPTSIZ0_PKTCNT) |
|
||||||
(3 << OTGFS_DOEPTSIZ0_STUPCNT_SHIFT);
|
(3 << OTGFS_DOEPTSIZ0_STUPCNT_SHIFT);
|
||||||
stm32_putreg(regval, STM32_OTGFS_DOEPTSIZ0);
|
stm32_putreg(regval, STM32_OTGFS_DOEPTSIZ0);
|
||||||
}
|
}
|
||||||
@@ -886,7 +889,6 @@ static void stm32_epin_transfer(FAR struct stm32_ep_s *privep,
|
|||||||
/* Yes.. leave the transfer size at zero and set the packet count to 1 */
|
/* Yes.. leave the transfer size at zero and set the packet count to 1 */
|
||||||
|
|
||||||
pktcnt = 1;
|
pktcnt = 1;
|
||||||
regval |= (1 << OTGFS_DIEPTSIZ_PKTCNT_SHIFT);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -903,7 +905,7 @@ static void stm32_epin_transfer(FAR struct stm32_ep_s *privep,
|
|||||||
/* Set the XFRSIZ and PKTCNT */
|
/* Set the XFRSIZ and PKTCNT */
|
||||||
|
|
||||||
regval |= (pktcnt << OTGFS_DIEPTSIZ_PKTCNT_SHIFT);
|
regval |= (pktcnt << OTGFS_DIEPTSIZ_PKTCNT_SHIFT);
|
||||||
regval |= ((uint32_t)nbytes << OTGFS_DIEPTSIZ_PKTCNT_SHIFT);
|
regval |= ((uint32_t)nbytes << OTGFS_DIEPTSIZ_XFRSIZ_SHIFT);
|
||||||
|
|
||||||
/* If this is an isconchronous endpoint, then set the multi-count field to
|
/* If this is an isconchronous endpoint, then set the multi-count field to
|
||||||
* the PKTCNT as well.
|
* the PKTCNT as well.
|
||||||
@@ -946,7 +948,7 @@ static void stm32_epin_transfer(FAR struct stm32_ep_s *privep,
|
|||||||
/* EP enable, IN data in FIFO */
|
/* EP enable, IN data in FIFO */
|
||||||
|
|
||||||
regval &= ~OTGFS_DIEPCTL_EPDIS;
|
regval &= ~OTGFS_DIEPCTL_EPDIS;
|
||||||
regval |= (OTGFS_DIEPCTL_SNAK | OTGFS_DIEPCTL_EPENA);
|
regval |= (OTGFS_DIEPCTL_CNAK | OTGFS_DIEPCTL_EPENA);
|
||||||
stm32_putreg(regval, STM32_OTGFS_DIEPCTL(privep->epphy));
|
stm32_putreg(regval, STM32_OTGFS_DIEPCTL(privep->epphy));
|
||||||
|
|
||||||
/* Transfer the data to the TxFIFO. At this point, the caller has already
|
/* Transfer the data to the TxFIFO. At this point, the caller has already
|
||||||
@@ -1003,9 +1005,10 @@ static void stm32_epin_request(FAR struct stm32_usbdev_s *priv,
|
|||||||
/* The endpoint is no longer active */
|
/* The endpoint is no longer active */
|
||||||
|
|
||||||
privep->active = false;
|
privep->active = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ullvdbg("EP%d req=%p: len=%d xfrd=%d nullpkt=%d\n",
|
ullvdbg("EP%d req=%p: len=%d xfrd=%d zlp=%d\n",
|
||||||
privep->epphy, privreq, privreq->req.len,
|
privep->epphy, privreq, privreq->req.len,
|
||||||
privreq->req.xfrd, privep->zlp);
|
privreq->req.xfrd, privep->zlp);
|
||||||
|
|
||||||
@@ -2098,9 +2101,7 @@ static inline void stm32_ep0out_setup(struct stm32_usbdev_s *priv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate any pending requests - since all DTDs will have been retired
|
/* Terminate any pending requests */
|
||||||
* because of the setup packet.
|
|
||||||
*/
|
|
||||||
|
|
||||||
stm32_req_cancel(&priv->epout[EP0], -EPROTO);
|
stm32_req_cancel(&priv->epout[EP0], -EPROTO);
|
||||||
stm32_req_cancel(&priv->epin[EP0], -EPROTO);
|
stm32_req_cancel(&priv->epin[EP0], -EPROTO);
|
||||||
@@ -2646,7 +2647,7 @@ static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv)
|
|||||||
/* Global OUT NAK. This indicate that the global OUT NAK bit has taken
|
/* Global OUT NAK. This indicate that the global OUT NAK bit has taken
|
||||||
* effect.
|
* effect.
|
||||||
*
|
*
|
||||||
* PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don’t Care, DPID = Don’t
|
* PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = Don't
|
||||||
* Care.
|
* Care.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -2679,7 +2680,7 @@ static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv)
|
|||||||
* on the specified OUT endpoint.
|
* on the specified OUT endpoint.
|
||||||
*
|
*
|
||||||
* PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on
|
* PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on
|
||||||
* which the data transfer is complete, DPID = Don’t Care.
|
* which the data transfer is complete, DPID = Don't Care.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OTGFS_GRXSTSD_PKTSTS_OUTDONE:
|
case OTGFS_GRXSTSD_PKTSTS_OUTDONE:
|
||||||
@@ -2695,7 +2696,7 @@ static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv)
|
|||||||
* interrupt).
|
* interrupt).
|
||||||
*
|
*
|
||||||
* PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num,
|
* PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num,
|
||||||
* DPID = Don’t Care.
|
* DPID = Don't Care.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
case OTGFS_GRXSTSD_PKTSTS_SETUPDONE:
|
case OTGFS_GRXSTSD_PKTSTS_SETUPDONE:
|
||||||
@@ -2981,6 +2982,8 @@ static int stm32_usbinterrupt(int irq, FAR void *context)
|
|||||||
FAR struct stm32_usbdev_s *priv = &g_otgfsdev;
|
FAR struct stm32_usbdev_s *priv = &g_otgfsdev;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
|
||||||
|
usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_USB), 0);
|
||||||
|
|
||||||
/* Assure that we are in device mode */
|
/* Assure that we are in device mode */
|
||||||
|
|
||||||
DEBUGASSERT((stm32_getreg(STM32_OTGFS_GINTSTS) & OTGFS_GINTSTS_CMOD) == OTGFS_GINTSTS_DEVMODE);
|
DEBUGASSERT((stm32_getreg(STM32_OTGFS_GINTSTS) & OTGFS_GINTSTS_CMOD) == OTGFS_GINTSTS_DEVMODE);
|
||||||
@@ -3005,7 +3008,7 @@ static int stm32_usbinterrupt(int irq, FAR void *context)
|
|||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_USB), (uint16_t)regval);
|
usbtrace(TRACE_INTDECODE(STM32_TRACEINTID_INTPENDING), (uint16_t)regval);
|
||||||
|
|
||||||
/* OUT endpoint interrupt. The core sets this bit to indicate that an
|
/* OUT endpoint interrupt. The core sets this bit to indicate that an
|
||||||
* interrupt is pending on one of the OUT endpoints of the core.
|
* interrupt is pending on one of the OUT endpoints of the core.
|
||||||
@@ -3539,7 +3542,7 @@ static void stm32_epin_disable(FAR struct stm32_ep_s *privep)
|
|||||||
* to poll this bit below).
|
* to poll this bit below).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
stm32_putreg(OTGFS_DIEPINT_INEPNE, STM32_OTGFS_DIEPINT(epno));
|
stm32_putreg(OTGFS_DIEPINT_INEPNE, STM32_OTGFS_DIEPINT(privep->epphy));
|
||||||
|
|
||||||
/* Set the endpoint in NAK mode */
|
/* Set the endpoint in NAK mode */
|
||||||
|
|
||||||
@@ -4588,35 +4591,35 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv)
|
|||||||
regval |= OTGFS_DCFG_DSPD_FS;
|
regval |= OTGFS_DCFG_DSPD_FS;
|
||||||
stm32_putreg(regval, STM32_OTGFS_DCFG);
|
stm32_putreg(regval, STM32_OTGFS_DCFG);
|
||||||
|
|
||||||
/* set Rx FIFO size */
|
/* Set Rx FIFO size */
|
||||||
|
|
||||||
stm32_putreg(CONFIG_USBDEV_RXFIFO_SIZE, STM32_OTGFS_GRXFSIZ);
|
stm32_putreg(CONFIG_USBDEV_RXFIFO_SIZE, STM32_OTGFS_GRXFSIZ);
|
||||||
|
|
||||||
/* EP0 TX */
|
/* EP0 TX */
|
||||||
|
|
||||||
address = CONFIG_USBDEV_RXFIFO_SIZE;
|
address = CONFIG_USBDEV_RXFIFO_SIZE;
|
||||||
regval = (address << OTGFS_DIEPTXF0_TX0FD_SHIFT) ||
|
regval = (address << OTGFS_DIEPTXF0_TX0FD_SHIFT) |
|
||||||
(CONFIG_USBDEV_EP0_TXFIFO_SIZE << OTGFS_DIEPTXF0_TX0FSA_SHIFT);
|
(CONFIG_USBDEV_EP0_TXFIFO_SIZE << OTGFS_DIEPTXF0_TX0FSA_SHIFT);
|
||||||
stm32_putreg(regval, STM32_OTGFS_DIEPTXF0);
|
stm32_putreg(regval, STM32_OTGFS_DIEPTXF0);
|
||||||
|
|
||||||
/* EP1 TX */
|
/* EP1 TX */
|
||||||
|
|
||||||
address += CONFIG_USBDEV_EP0_TXFIFO_SIZE;
|
address += CONFIG_USBDEV_EP0_TXFIFO_SIZE;
|
||||||
regval = (address << OTGFS_DIEPTXF_INEPTXSA_SHIFT) ||
|
regval = (address << OTGFS_DIEPTXF_INEPTXSA_SHIFT) |
|
||||||
(CONFIG_USBDEV_EP1_TXFIFO_SIZE << OTGFS_DIEPTXF_INEPTXFD_SHIFT);
|
(CONFIG_USBDEV_EP1_TXFIFO_SIZE << OTGFS_DIEPTXF_INEPTXFD_SHIFT);
|
||||||
stm32_putreg(regval, STM32_OTGFS_DIEPTXF1);
|
stm32_putreg(regval, STM32_OTGFS_DIEPTXF1);
|
||||||
|
|
||||||
/* EP2 TX */
|
/* EP2 TX */
|
||||||
|
|
||||||
address += CONFIG_USBDEV_EP1_TXFIFO_SIZE;
|
address += CONFIG_USBDEV_EP1_TXFIFO_SIZE;
|
||||||
regval = (address << OTGFS_DIEPTXF_INEPTXSA_SHIFT) ||
|
regval = (address << OTGFS_DIEPTXF_INEPTXSA_SHIFT) |
|
||||||
(CONFIG_USBDEV_EP2_TXFIFO_SIZE << OTGFS_DIEPTXF_INEPTXFD_SHIFT);
|
(CONFIG_USBDEV_EP2_TXFIFO_SIZE << OTGFS_DIEPTXF_INEPTXFD_SHIFT);
|
||||||
stm32_putreg(regval, STM32_OTGFS_DIEPTXF2);
|
stm32_putreg(regval, STM32_OTGFS_DIEPTXF2);
|
||||||
|
|
||||||
/* EP3 TX */
|
/* EP3 TX */
|
||||||
|
|
||||||
address += CONFIG_USBDEV_EP2_TXFIFO_SIZE;
|
address += CONFIG_USBDEV_EP2_TXFIFO_SIZE;
|
||||||
regval = (address << OTGFS_DIEPTXF_INEPTXSA_SHIFT) ||
|
regval = (address << OTGFS_DIEPTXF_INEPTXSA_SHIFT) |
|
||||||
(CONFIG_USBDEV_EP3_TXFIFO_SIZE << OTGFS_DIEPTXF_INEPTXFD_SHIFT);
|
(CONFIG_USBDEV_EP3_TXFIFO_SIZE << OTGFS_DIEPTXF_INEPTXFD_SHIFT);
|
||||||
stm32_putreg(regval, STM32_OTGFS_DIEPTXF3);
|
stm32_putreg(regval, STM32_OTGFS_DIEPTXF3);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user