summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2015-03-24 10:05:21 -0600
committerGregory Nutt <gnutt@nuttx.org>2015-03-24 10:05:21 -0600
commit072f253ab63e16067c1019991d9a6da5a1b9219d (patch)
treeca8005cebf38eaeea9fecb43800d18709b805225
parent72a289c4ce6d44f9aaafbec546599cb3a72f5525 (diff)
downloadpx4-nuttx-072f253ab63e16067c1019991d9a6da5a1b9219d.tar.gz
px4-nuttx-072f253ab63e16067c1019991d9a6da5a1b9219d.tar.bz2
px4-nuttx-072f253ab63e16067c1019991d9a6da5a1b9219d.zip
SAMV7 USB: Updates to early initialization logic
-rw-r--r--apps/nshlib/Kconfig1
-rw-r--r--nuttx/arch/arm/src/samv7/chip/sam_usbhs.h4
-rw-r--r--nuttx/arch/arm/src/samv7/sam_usbdevhs.c123
3 files changed, 72 insertions, 56 deletions
diff --git a/apps/nshlib/Kconfig b/apps/nshlib/Kconfig
index ca1a029e8..1bdd597d1 100644
--- a/apps/nshlib/Kconfig
+++ b/apps/nshlib/Kconfig
@@ -6,6 +6,7 @@
config NSH_LIBRARY
bool "NSH Library"
default n
+ select NETUTILS_NETLIB if NET
---help---
Build the NSH support library. This is used, for example, by
examples/nsh in order to implement the full NuttShell (NSH).
diff --git a/nuttx/arch/arm/src/samv7/chip/sam_usbhs.h b/nuttx/arch/arm/src/samv7/chip/sam_usbhs.h
index d5710d889..ba9293766 100644
--- a/nuttx/arch/arm/src/samv7/chip/sam_usbhs.h
+++ b/nuttx/arch/arm/src/samv7/chip/sam_usbhs.h
@@ -204,7 +204,7 @@
#define USBHS_DEVCTRL_RMWKUP (1 << 9) /* Bit 9: Send Remote Wake Up */
#define USBHS_DEVCTRL_SPDCONF_SHIFT (10) /* Bits 10-11: Mode Configuration */
#define USBHS_DEVCTRL_SPDCONF_MASK (3 << USBHS_DEVCTRL_SPDCONF_SHIFT)
-# define USBHS_DEVCTRL_SPDCONF_NORMAL 0 << USBHS_DEVCTRL_SPDCONF_SHIFT)
+# define USBHS_DEVCTRL_SPDCONF_NORMAL (0 << USBHS_DEVCTRL_SPDCONF_SHIFT)
# define USBHS_DEVCTRL_SPDCONF_LOWPOWER (1 << USBHS_DEVCTRL_SPDCONF_SHIFT)
#define USBHS_DEVCTRL_LS (1 << 12) /* Bit 12: Low-Speed Mode Force */
#define USBHS_DEVCTRL_TSTJ (1 << 13) /* Bit 13: Test mode J */
@@ -739,6 +739,8 @@
#define USBHS_CTRL_FRZCLK (1 << 14) /* Bit 14: Freeze USB Clock */
#define USBHS_CTRL_USBE (1 << 15) /* Bit 15: USBHS Enable */
#define USBHS_CTRL_UIMOD (1 << 25) /* Bit 25: USBHS Mode */
+# define USBHS_CTRL_UIMOD_HOST (0 << 25) /* 0=Host mode */
+# define USBHS_CTRL_UIMOD_DEVICE (1 << 25) /* 1= Device mode */
/* General Status Register */
diff --git a/nuttx/arch/arm/src/samv7/sam_usbdevhs.c b/nuttx/arch/arm/src/samv7/sam_usbdevhs.c
index 525be8c53..97cc4c0ed 100644
--- a/nuttx/arch/arm/src/samv7/sam_usbdevhs.c
+++ b/nuttx/arch/arm/src/samv7/sam_usbdevhs.c
@@ -11,6 +11,11 @@
*
* Copyright (c) 2009, Atmel Corporation
*
+ * Additional updates for the SAMV7 was taken from Atmel sample code for the
+ * SAMV71:
+ *
+ * Copyright (c) 2014, Atmel Corporation
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -4065,16 +4070,14 @@ static void sam_reset(struct sam_usbdev_s *priv)
uint32_t regval;
uint8_t epno;
- /* Make sure that clocking is enabled to the USBHS peripheral.
- *
- * NOTE: In the Atmel example code, they also enable USB clocking
- * at this point (via the BIAS in the CKGR_UCKR register). In this
- * implementation, that should not be necessary here because we
- * never disable BIAS to begin with.
- */
+ /* Make sure that clocking is enabled to the USBHS peripheral. */
sam_usbhs_enableclk();
+ regval = sam_getreg(SAM_USBHS_CTRL);
+ regval &= ~USBHS_CTRL_FRZCLK;
+ sam_putreg(regval, SAM_USBHS_CTRL);
+
/* Tell the class driver that we are disconnected. The class driver
* should then accept any new configurations.
*/
@@ -4121,18 +4124,29 @@ static void sam_reset(struct sam_usbdev_s *priv)
priv->usbdev.speed = USB_SPEED_FULL;
- /* Clear all pending interrupt status */
+ /* Enable normal operational interrupts (including endpoint 0) */
- regval = USBHS_DEVINT_UPRSM | USBHS_DEVINT_EORSM | USBHS_DEVINT_WAKEUP |
- USBHS_DEVINT_EORST | USBHS_DEVINT_SOF | USBHS_DEVINT_MSOF |
+ regval = USBHS_DEVINT_EORST | USBHS_DEVINT_WAKEUP | USBHS_DEVINT_SUSPD |
+ USBHS_DEVINT_SOF | USBHS_DEVINT_PEP0;
+#ifdef CONFIG_USBDEV_DUALSPEED
+ regval |= USBHS_DEVINT_MSOF;
+#endif
+ sam_putreg(regval, SAM_USBHS_DEVIER);
+
+ /* Reset following interrupts flag */
+
+ regval = USBHS_DEVINT_EORST | USBHS_DEVINT_SOF | USBHS_DEVINT_MSOF |
USBHS_DEVINT_SUSPD;
sam_putreg(regval, SAM_USBHS_DEVICR);
- /* Enable normal operational interrupts (including endpoint 0) */
+ /* Raise the first suspend interrupt */
- regval = USBHS_DEVINT_EORSM | USBHS_DEVINT_WAKEUP | USBHS_DEVINT_SUSPD |
- USBHS_DEVINT_PEP0;
- sam_putreg(regval, SAM_USBHS_DEVIER);
+ regval = sam_getreg(SAM_USBHS_DEVIFR);
+ regval |= USBHS_DEVINT_SUSPD;
+ sam_putreg(regval, SAM_USBHS_DEVIFR);
+
+ regval |= USBHS_DEVINT_WAKEUP;
+ sam_putreg(regval, SAM_USBHS_DEVIFR);
sam_dumpep(priv, EP0);
}
@@ -4146,57 +4160,55 @@ static void sam_hw_setup(struct sam_usbdev_s *priv)
uint32_t regval;
int i;
- /* Paragraph 32.5.1, "Power Management". The USBHS is not continuously
- * clocked. For using the USBHS, the programmer must first enable the
- * USBHS Clock in the Power Management Controller (PMC_PCER register).
- * Then enable the PLL (PMC_UCKR register). Finally, enable BIAS in
- * PMC_UCKR register. However, if the application does not require USBHS
- * operations, the USBHS clock can be stopped when not needed and
- * restarted later.
- *
- * Here, we set only the PCER. PLL configuration was performed in
- * sam_clockconfig() earlier in the boot sequence.
+ /* Enable clocking tot he USBHS peripheral. Here, we set only the PCER.
+ * UPLL configuration was performed in sam_clockconfig() earlier in the
+ * boot sequence.
*/
sam_usbhs_enableclk();
- /* Reset and disable endpoints */
+ /* Disable USB hardware and select device mode */
- sam_epset_reset(priv, SAM_EPSET_ALL);
+ regval = sam_getreg(SAM_USBHS_CTRL);
+ regval &= ~USBHS_CTRL_USBE;
+ sam_putreg(regval, SAM_USBHS_CTRL);
+
+ regval |= USBHS_CTRL_UIMOD_DEVICE;
+ sam_putreg(regval, SAM_USBHS_CTRL);
+
+ /* Enable USB hardware and unfreeze clocking */
- /* Configure the pull-up on D+ and disconnect it */
+ regval |= USBHS_CTRL_USBE;
+ sam_putreg(regval, SAM_USBHS_CTRL);
+
+ regval &= ~USBHS_CTRL_FRZCLK;
+ sam_putreg(regval, SAM_USBHS_CTRL);
+
+ /* Select High Speed */
regval = sam_getreg(SAM_USBHS_DEVCTRL);
- regval |= USBHS_DEVCTRL_DETACH;
+ regval |= USBHS_DEVCTRL_SPDCONF_NORMAL;
sam_putreg(regval, SAM_USBHS_DEVCTRL);
- /* Reset the USBHS block
- *
- * Paragraph 33.5.1. "One transceiver is shared with the USB High Speed
- * Device (port A). The selection between Host Port A and USB Device is
- * controlled by the USBHS enable bit (EN_USBHS) located in the USBHS_CTRL
- * control register.
- *
- * "In the case the port A is driven by the USB High Speed Device, the ...
- * transceiver is automatically selected for Device operation once the
- * USB High Speed Device is enabled."
- */
+ /* Wait for UTMI clocking to be usable */
-#warning REVISIT
-#if 0
- regval &= ~xxxx;
- sam_putreg(regval, SAM_USBHS_DEVCTRL);
+ while ((sam_getreg(SAM_USBHS_SR) & USBHS_SR_CLKUSABLE) == 0);
+
+ /* Make sure that we are not in Low-Speed mode */
- regval |= xxxx;
+ regval = sam_getreg(SAM_USBHS_DEVCTRL);
+ regval &= ~USBHS_DEVCTRL_LS;
sam_putreg(regval, SAM_USBHS_DEVCTRL);
-#endif
- /* REVISIT: Per recommendations and sample code, USB clocking (as
- * configured in the PMC CKGR_UCKR) is set up after reseting the UDHPS.
- * However, that initialation has already been done in sam_clockconfig().
- * Also, that clocking is shared with the UHPHS USB host logic; the
- * device logica cannot autonomously control USB clocking.
- */
+ /* Reset and disable all endpoints (including endpoint 0) */
+
+ sam_epset_reset(priv, SAM_EPSET_ALL);
+
+ /* Disconnect the device */
+
+ regval = sam_getreg(SAM_USBHS_DEVCTRL);
+ regval |= USBHS_DEVCTRL_DETACH;
+ sam_putreg(regval, SAM_USBHS_DEVCTRL);
/* Initialize DMA channels */
@@ -4256,10 +4268,11 @@ static void sam_hw_setup(struct sam_usbdev_s *priv)
sam_putreg(USBHS_DEVINT_ALL, SAM_USBHS_DEVIDR);
- /* The Atmel sample code disables USB clocking here (via the PMC
- * CKGR_UCKR). However, we cannot really do that here because that
- * clocking is also needed by the UHPHS host.
- */
+ /* Initialization complete... Freeze the clock */
+
+ regval = sam_getreg(SAM_USBHS_CTRL);
+ regval |= ~USBHS_CTRL_FRZCLK;
+ sam_putreg(regval, SAM_USBHS_CTRL);
}
/****************************************************************************