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:
patacongo
2012-04-10 18:27:13 +00:00
parent fb202ee945
commit 2272d671f0
2 changed files with 75 additions and 72 deletions
+2 -2
View File
@@ -153,7 +153,7 @@
#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_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_DIEPINT1_OFFSET 0x0928 /* Device endpoint-1 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_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_DOEPINT_EPOFFSET 0x0008 /* Device endpoint-x interrupt register */
+23 -20
View File
@@ -134,6 +134,7 @@
/* Trace interrupt codes */
#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_EPIN (10 + 1)
@@ -792,7 +793,9 @@ static void stm32_ep0in_activate(void)
/* 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;
regval = (USB_SIZEOF_CTRLREQ * 3 << OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT) ||
(OTGFS_DOEPTSIZ0_PKTCNT) ||
regval = (USB_SIZEOF_CTRLREQ * 3 << OTGFS_DOEPTSIZ0_XFRSIZ_SHIFT) |
(OTGFS_DOEPTSIZ0_PKTCNT) |
(3 << OTGFS_DOEPTSIZ0_STUPCNT_SHIFT);
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 */
pktcnt = 1;
regval |= (1 << OTGFS_DIEPTSIZ_PKTCNT_SHIFT);
}
else
{
@@ -903,7 +905,7 @@ static void stm32_epin_transfer(FAR struct stm32_ep_s *privep,
/* Set the XFRSIZ and PKTCNT */
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
* 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 */
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));
/* 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 */
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,
privreq->req.xfrd, privep->zlp);
@@ -2098,9 +2101,7 @@ static inline void stm32_ep0out_setup(struct stm32_usbdev_s *priv)
return;
}
/* Terminate any pending requests - since all DTDs will have been retired
* because of the setup packet.
*/
/* Terminate any pending requests */
stm32_req_cancel(&priv->epout[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
* effect.
*
* PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Dont Care, DPID = Dont
* PKTSTS = Global OUT NAK, BCNT = 0, EPNUM = Don't Care, DPID = Don't
* Care.
*/
@@ -2679,7 +2680,7 @@ static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv)
* on the specified OUT endpoint.
*
* PKTSTS = Data OUT Transfer Done, BCNT = 0, EPNUM = OUT EP Num on
* which the data transfer is complete, DPID = Dont Care.
* which the data transfer is complete, DPID = Don't Care.
*/
case OTGFS_GRXSTSD_PKTSTS_OUTDONE:
@@ -2695,7 +2696,7 @@ static inline void stm32_rxinterrupt(FAR struct stm32_usbdev_s *priv)
* interrupt).
*
* PKTSTS = Setup Stage Done, BCNT = 0, EPNUM = Control EP Num,
* DPID = Dont Care.
* DPID = Don't Care.
*/
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;
uint32_t regval;
usbtrace(TRACE_INTENTRY(STM32_TRACEINTID_USB), 0);
/* Assure that we are in device mode */
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;
}
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
* 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).
*/
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 */
@@ -4588,35 +4591,35 @@ static void stm32_hwinitialize(FAR struct stm32_usbdev_s *priv)
regval |= OTGFS_DCFG_DSPD_FS;
stm32_putreg(regval, STM32_OTGFS_DCFG);
/* set Rx FIFO size */
/* Set Rx FIFO size */
stm32_putreg(CONFIG_USBDEV_RXFIFO_SIZE, STM32_OTGFS_GRXFSIZ);
/* EP0 TX */
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);
stm32_putreg(regval, STM32_OTGFS_DIEPTXF0);
/* EP1 TX */
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);
stm32_putreg(regval, STM32_OTGFS_DIEPTXF1);
/* EP2 TX */
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);
stm32_putreg(regval, STM32_OTGFS_DIEPTXF2);
/* EP3 TX */
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);
stm32_putreg(regval, STM32_OTGFS_DIEPTXF3);