From 698d6d129445c1a06b93e6a0890d8ae275d3cca2 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 9 Aug 2016 17:05:11 -0600 Subject: [PATCH] SAM3/4: Extend clocking logic to enable clocking on ports D-F --- arch/arm/src/sam34/sam_gpio.c | 98 +++++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 27 deletions(-) diff --git a/arch/arm/src/sam34/sam_gpio.c b/arch/arm/src/sam34/sam_gpio.c index 5b2b65a0ee..259bea4bd3 100644 --- a/arch/arm/src/sam34/sam_gpio.c +++ b/arch/arm/src/sam34/sam_gpio.c @@ -97,7 +97,7 @@ static inline uintptr_t sam_gpiobase(gpio_pinset_t cfgset) * Name: sam_gpiopin * * Description: - * Returun the base address of the GPIO register set + * Return the base address of the GPIO register set * ****************************************************************************/ @@ -106,6 +106,69 @@ static inline int sam_gpiopin(gpio_pinset_t cfgset) return 1 << ((cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); } +/**************************************************************************** + * Name: sam_gpio_enableclk + * + * Description: + * Enable clocking on the PIO port. Port clocking is required in the + * following cases: + * + * - In order to read values in input pins from the port + * - If the port supports interrupting pins + * - If glitch filtering is enabled + * - If necessary to read the input value on an open drain output (this + * may be done in TWI logic to detect hangs on the I2C bus). + * + ****************************************************************************/ + +static inline int sam_gpio_enableclk(gpio_pinset_t cfgset) +{ + /* Enable the peripheral clock for the GPIO's port controller. + * A GPIO input value is only sampled if the peripheral clock for its + * controller is enabled. + */ + + switch (cfgset & GPIO_PORT_MASK) + { + case GPIO_PORT_PIOA: + sam_pioa_enableclk(); + break; + + case GPIO_PORT_PIOB: + sam_piob_enableclk(); + break; + +#ifdef GPIO_PORT_PIOC + case GPIO_PORT_PIOC: + sam_pioc_enableclk(); + break; +#endif + +#ifdef GPIO_PORT_PIOD + case GPIO_PORT_PIOD: + sam_piod_enableclk(); + break; +#endif + +#ifdef GPIO_PORT_PIOE + case GPIO_PORT_PIOE: + sam_pioe_enableclk(); + break; +#endif + +#ifdef GPIO_PORT_PIOF + case GPIO_PORT_PIOF: + sam_piof_enableclk(); + break; +#endif + + default: + return -EINVAL; + } + + return OK; +} + /**************************************************************************** * Name: sam_configinput * @@ -172,6 +235,7 @@ static inline int sam_configinput(uintptr_t base, uint32_t pin, { regval &= ~pin; } + putreg32(regval, base + SAM_PIO_SCHMITT_OFFSET); #endif @@ -180,37 +244,17 @@ static inline int sam_configinput(uintptr_t base, uint32_t pin, putreg32(pin, base + SAM_PIO_ODR_OFFSET); putreg32(pin, base + SAM_PIO_PER_OFFSET); - /* Enable the peripheral clock for the GPIO's port controller. - * A GPIO input value is only sampled if the peripheral clock for its - * controller is enabled. - */ - - switch (cfgset & GPIO_PORT_MASK) - { - case GPIO_PORT_PIOA: - sam_pioa_enableclk(); - break; - - case GPIO_PORT_PIOB: - sam_piob_enableclk(); - break; - -#ifdef GPIO_HAVE_PERIPHCD - case GPIO_PORT_PIOC: - sam_pioc_enableclk(); - break; -#endif - - default: - return -EINVAL; - } - /* To-Do: If DEGLITCH is selected, need to configure DIFSR, SCIFSR, and * IFDGSR registers. This would probably best be done with * another, new API... perhaps sam_configfilter() */ - return OK; + /* Enable the peripheral clock for the GPIO's port controller. + * A GPIO input value is only sampled if the peripheral clock for its + * controller is enabled. + */ + + return sam_gpio_enableclk(cfgset); } /****************************************************************************