summaryrefslogtreecommitdiff
path: root/nuttx/arch
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-03-24 14:30:53 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-03-24 14:30:53 -0600
commitfd2a0abe7a06e10b76f83378435b2fa221145f69 (patch)
treec83314ead2edd6272715967f165dfb848e077a25 /nuttx/arch
parentc4613bbae60372416f4cd8413d65a7d72a7b92b5 (diff)
downloadpx4-nuttx-fd2a0abe7a06e10b76f83378435b2fa221145f69.tar.gz
px4-nuttx-fd2a0abe7a06e10b76f83378435b2fa221145f69.tar.bz2
px4-nuttx-fd2a0abe7a06e10b76f83378435b2fa221145f69.zip
SAMV7 USB DCD is code complete and ready for test
Diffstat (limited to 'nuttx/arch')
-rw-r--r--nuttx/arch/arm/src/samv7/sam_usbdevhs.c61
1 files changed, 42 insertions, 19 deletions
diff --git a/nuttx/arch/arm/src/samv7/sam_usbdevhs.c b/nuttx/arch/arm/src/samv7/sam_usbdevhs.c
index 1c28f1597..831b0e70f 100644
--- a/nuttx/arch/arm/src/samv7/sam_usbdevhs.c
+++ b/nuttx/arch/arm/src/samv7/sam_usbdevhs.c
@@ -465,7 +465,6 @@ static int sam_usbhs_interrupt(int irq, void *context);
/* Endpoint helpers *********************************************************/
-static void sam_ep_halt(struct usbdev_ep_s *ep, bool resume);
static void sam_ep_reset(struct sam_usbdev_s *priv, uint8_t epno);
static void sam_epset_reset(struct sam_usbdev_s *priv, uint16_t epset);
static inline struct sam_ep_s *
@@ -1253,6 +1252,8 @@ static void sam_req_wrsetup(struct sam_usbdev_s *priv,
*fifo++ = *buf++;
}
+ MEMORY_SYNC();
+
/* Indicate that there is data in the TX packet memory. This will
* be cleared when the next data out interrupt is received.
*/
@@ -1489,6 +1490,8 @@ static void sam_req_rddone(struct sam_usbdev_s *priv,
{
*dest++ = *fifo++;
}
+
+ MEMORY_SYNC();
}
/****************************************************************************
@@ -1733,6 +1736,8 @@ static void sam_ep0_read(uint8_t *buffer, size_t buflen)
{
*buffer++ = *fifo++;
}
+
+ MEMORY_SYNC();
}
/****************************************************************************
@@ -1756,6 +1761,8 @@ static void sam_ep0_wrstatus(const uint8_t *buffer, size_t buflen)
*fifo++ = *buffer++;
}
+ MEMORY_SYNC();
+
/* Initiate the transfer and configure to receive the transfer complete
* interrupt.
*/
@@ -3001,6 +3008,8 @@ static void sam_suspend(struct sam_usbdev_s *priv)
static void sam_resume(struct sam_usbdev_s *priv)
{
+ uint32_t regval;
+
/* This function is called when either (1) a WKUP interrupt is received from
* the host PC, or (2) the class device implementation calls the wakeup()
* method.
@@ -3020,6 +3029,12 @@ static void sam_resume(struct sam_usbdev_s *priv)
sam_usbhs_enableclk();
+ /* Un-freeze clocking */
+
+ regval = sam_getreg(SAM_USBHS_CTRL);
+ regval &= ~USBHS_CTRL_FRZCLK;
+ sam_putreg(regval, SAM_USBHS_CTRL);
+
/* Revert to the previous state */
priv->devstate = priv->prevstate;
@@ -3782,7 +3797,7 @@ static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume)
sam_putreg(USBHS_DEVEPTINT_STALLEDI, SAM_USBHS_DEVEPTIDR(epno));
- regaddr = SAM_USBHS_DEVEPCFG(epno);
+ regaddr = SAM_USBHS_DEVEPTCFG(epno);
regval = sam_getreg(regaddr);
regval |= USBHS_DEVEPTCFG_AUTOSW;
sam_putreg(regval, regaddr);
@@ -3847,7 +3862,7 @@ static int sam_ep_stall(struct usbdev_ep_s *ep, bool resume)
privep->epstate = USBHS_EPSTATE_STALLED;
privep->stalled = true;
- regaddr = AM_USBHS_DEVEPCTG(epno);
+ regaddr = SAM_USBHS_DEVEPTCFG(epno);
regval = sam_getreg(regaddr);
regval &= ~USBHS_DEVEPTCFG_AUTOSW;
sam_putreg(regval, regaddr);
@@ -4100,28 +4115,25 @@ static int sam_pullup(FAR struct usbdev_s *dev, bool enable)
usbtrace(TRACE_DEVPULLUP, (uint16_t)enable);
- /* DETACH PULLD_DIS DP DM Condition
- *
- * 0 1 Pull High VBUS present
- * Up Impedance
- * 1 0 Pull Pull No VBUS
- * Down Down
- * 1 1 High High VBUS present +
- * Impedance Imedpance Disconnect
- */
-
- regval = sam_getreg(SAM_USBHS_DEVCTRL);
if (enable)
{
/* DETACH=0: USBHS is attached. Pulls up the DP line */
+ regval = sam_getreg(SAM_USBHS_DEVCTRL);
regval &= ~USBHS_DEVCTRL_DETACH;
sam_putreg(regval, SAM_USBHS_DEVCTRL);
}
else
{
+ /* Freeze clocking */
+
+ regval = sam_getreg(SAM_USBHS_CTRL);
+ regval |= USBHS_CTRL_FRZCLK;
+ sam_putreg(regval, SAM_USBHS_CTRL);
+
/* DETACH=1: USBHS is detached, UTMI transceiver is suspended. */
+ regval = sam_getreg(SAM_USBHS_DEVCTRL);
regval |= USBHS_DEVCTRL_DETACH;
sam_putreg(regval, SAM_USBHS_DEVCTRL);
@@ -4131,6 +4143,11 @@ static int sam_pullup(FAR struct usbdev_s *dev, bool enable)
{
priv->devstate = USBHS_DEVSTATE_POWERED;
}
+
+ if (priv->prevstate > USBHS_DEVSTATE_POWERED)
+ {
+ priv->prevstate = USBHS_DEVSTATE_POWERED;
+ }
}
return OK;
@@ -4336,7 +4353,7 @@ static void sam_hw_setup(struct sam_usbdev_s *priv)
/* Initialization complete... Freeze the clock */
regval = sam_getreg(SAM_USBHS_CTRL);
- regval |= ~USBHS_CTRL_FRZCLK;
+ regval |= USBHS_CTRL_FRZCLK;
sam_putreg(regval, SAM_USBHS_CTRL);
}
@@ -4444,10 +4461,16 @@ static void sam_hw_shutdown(struct sam_usbdev_s *priv)
USBHS_DEVINT_SUSPD;
sam_putreg(regval, SAM_USBHS_DEVICR);
- /* Disconnect the device / disable the pull-up */
+ /* Disconnect the device */
sam_pullup(&priv->usbdev, false);
+ /* Disable USB hardware */
+
+ regval = sam_getreg(SAM_USBHS_CTRL);
+ regval &= ~USBHS_CTRL_USBE;
+ sam_putreg(regval, SAM_USBHS_CTRL);
+
/* Disable clocking to the USBHS peripheral */
sam_usbhs_disableclk();
@@ -4531,14 +4554,14 @@ errout:
void up_usbuninitialize(void)
{
+ struct sam_usbdev_s *priv = &g_usbhs;
+ irqstate_t flags;
+
/* For now there is only one USB controller, but we will always refer to
* it using a pointer to make any future ports to multiple USB controllers
* easier.
*/
- struct sam_usbdev_s *priv = &g_usbhs;
- irqstate_t flags;
-
flags = irqsave();
usbtrace(TRACE_DEVUNINIT, 0);