From eba19bef850a551575e381f216d243ba8dd68a73 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 21 Nov 2013 16:39:49 -0600 Subject: [PATCH] LPC3131 EHCI: More fixes --- arch/arm/src/lpc31xx/lpc31_ehci.c | 39 ++++++++++++-------- arch/arm/src/lpc31xx/lpc31_memorymap.h | 2 +- arch/arm/src/sama5/sam_ehci.c | 13 +++++-- configs/olimex-lpc-h3131/src/lpc31_usbhost.c | 2 +- 4 files changed, 35 insertions(+), 21 deletions(-) diff --git a/arch/arm/src/lpc31xx/lpc31_ehci.c b/arch/arm/src/lpc31xx/lpc31_ehci.c index 3f7dc0cb11..a91a3a1d6d 100755 --- a/arch/arm/src/lpc31xx/lpc31_ehci.c +++ b/arch/arm/src/lpc31xx/lpc31_ehci.c @@ -4045,12 +4045,19 @@ static int lpc31_reset(void) uint32_t regval; unsigned int timeout; - /* "... Software should not set [HCRESET] to a one when the HCHalted bit in - * the USBSTS register is a zero. Attempting to reset an actively running - * host controller will result in undefined behavior." + /* Make sure that the EHCI is halted: "When [the Run/Stop] bit is set to 0, + * the Host Controller completes the current transaction on the USB and then + * halts. The HC Halted bit in the status register indicates when the Hos + * Controller has finished the transaction and has entered the stopped state..." */ lpc31_putreg(0, &HCOR->usbcmd); + + /* "... Software should not set [HCRESET] to a one when the HCHalted bit in + * the USBSTS register is a zero. Attempting to reset an actively running + * host controller will result in undefined behavior." + */ + timeout = 0; do { @@ -4059,7 +4066,7 @@ static int lpc31_reset(void) up_udelay(1); timeout++; - /* Get the current valud of the USBSTS register. This loop will terminate + /* Get the current value of the USBSTS register. This loop will terminate * when either the timeout exceeds one millisecond or when the HCHalted * bit is no longer set in the USBSTS register. */ @@ -4091,7 +4098,7 @@ static int lpc31_reset(void) up_udelay(5); timeout += 5; - /* Get the current valud of the USBCMD register. This loop will terminate + /* Get the current value of the USBCMD register. This loop will terminate * when either the timeout exceeds one second or when the HCReset * bit is no longer set in the USBSTS register. */ @@ -4264,16 +4271,6 @@ FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller) } /* EHCI Hardware Configuration ***********************************************/ - /* Host Controller Initialization. Paragraph 4.1 */ - /* Reset the EHCI hardware */ - - ret = lpc31_reset(); - if (ret < 0) - { - usbhost_trace1(EHCI_TRACE1_RESET_FAILED, -ret); - return NULL; - } - /* Enable USB to AHB clock and to Event router */ lpc31_enableclock(CLKID_USBOTGAHBCLK); @@ -4297,7 +4294,7 @@ FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller) lpc31_enableclock (CLKID_USBOTGAHBCLK); - /* Reset the controller */ + /* Reset the controller from the OTG peripheral */ putreg32(USBDEV_USBCMD_RST, LPC31_USBDEV_USBCMD); while ((getreg32(LPC31_USBDEV_USBCMD) & USBDEV_USBCMD_RST) != 0) @@ -4316,6 +4313,16 @@ FAR struct usbhost_connection_s *lpc31_ehci_initialize(int controller) putreg32(USBHOST_USBMODE_CMHOST | USBHOST_USBMODE_SDIS | USBHOST_USBMODE_VBPS, LPC31_USBDEV_USBMODE); + /* Host Controller Initialization. Paragraph 4.1 */ + /* Reset the EHCI hardware */ + + ret = lpc31_reset(); + if (ret < 0) + { + usbhost_trace1(EHCI_TRACE1_RESET_FAILED, -ret); + return NULL; + } + /* "In order to initialize the host controller, software should perform the * following steps: * diff --git a/arch/arm/src/lpc31xx/lpc31_memorymap.h b/arch/arm/src/lpc31xx/lpc31_memorymap.h index ba77c7eea2..49be389c97 100644 --- a/arch/arm/src/lpc31xx/lpc31_memorymap.h +++ b/arch/arm/src/lpc31xx/lpc31_memorymap.h @@ -95,7 +95,7 @@ #define LPC31_APB0_SYSCREG_OFFSET 0x00002800 /* SYSCREG block */ #define LPC31_APB0_IOCONFIG_OFFSET 0x00003000 /* IOCONFIG */ #define LPC31_APB0_GCU_OFFSET 0x00004000 /* GCU */ -#define LPC31_APB0_OTP_OFFSET 0x00005000 /* USB OTG (LPC315x only) */ +#define LPC31_APB0_OTP_OFFSET 0x00005000 /* USB OTP (LPC315x only) */ #define LPC31_APB0_RNG_OFFSET 0x00006000 /* RNG */ #define LPC31_APB1_TIMER0_OFFSET 0x00000000 /* TIMER0 */ diff --git a/arch/arm/src/sama5/sam_ehci.c b/arch/arm/src/sama5/sam_ehci.c index bbe7dee1d7..cd77f4f5a8 100755 --- a/arch/arm/src/sama5/sam_ehci.c +++ b/arch/arm/src/sama5/sam_ehci.c @@ -3922,12 +3922,19 @@ static int sam_reset(void) uint32_t regval; unsigned int timeout; + /* Make sure that the EHCI is halted: "When [the Run/Stop] bit is set to 0, + * the Host Controller completes the current transaction on the USB and then + * halts. The HC Halted bit in the status register indicates when the Hos + * Controller has finished the transaction and has entered the stopped state..." + */ + + sam_putreg(0, &HCOR->usbcmd); + /* "... Software should not set [HCRESET] to a one when the HCHalted bit in * the USBSTS register is a zero. Attempting to reset an actively running * host controller will result in undefined behavior." */ - sam_putreg(0, &HCOR->usbcmd); timeout = 0; do { @@ -3936,7 +3943,7 @@ static int sam_reset(void) up_udelay(1); timeout++; - /* Get the current valud of the USBSTS register. This loop will terminate + /* Get the current value of the USBSTS register. This loop will terminate * when either the timeout exceeds one millisecond or when the HCHalted * bit is no longer set in the USBSTS register. */ @@ -3968,7 +3975,7 @@ static int sam_reset(void) up_udelay(5); timeout += 5; - /* Get the current valud of the USBCMD register. This loop will terminate + /* Get the current value of the USBCMD register. This loop will terminate * when either the timeout exceeds one second or when the HCReset * bit is no longer set in the USBSTS register. */ diff --git a/configs/olimex-lpc-h3131/src/lpc31_usbhost.c b/configs/olimex-lpc-h3131/src/lpc31_usbhost.c index 3c6108bef8..f321123b48 100644 --- a/configs/olimex-lpc-h3131/src/lpc31_usbhost.c +++ b/configs/olimex-lpc-h3131/src/lpc31_usbhost.c @@ -160,7 +160,7 @@ void weak_function lpc31_usbhost_bootinitialize(void) /* Configure input pin to detect overrcurrent errors */ - gpio_outputhigh(LPC31_IOCONFIG_GPIO, GPIO_NOTG_OVRCR); + gpio_configinput(LPC31_IOCONFIG_GPIO, GPIO_NOTG_OVRCR); /* Configure to receive interrupts on the overrcurrent input pin */ #warning Missing logic