diff --git a/arch/arm/src/sam3u/sam3u_internal.h b/arch/arm/src/sam3u/sam3u_internal.h index bcc7eb5d56..64851987fc 100755 --- a/arch/arm/src/sam3u/sam3u_internal.h +++ b/arch/arm/src/sam3u/sam3u_internal.h @@ -78,11 +78,11 @@ */ #define GPIO_CFG_SHIFT (11) /* Bits 11-13: GPIO configuration bits */ -#define GPIO_CFG_MASK (3 << GPIO_CNF_SHIFT) -# define GPIO_CFG_DEFAULT (0 << GPIO_CNF_SHIFT) /* Default, no attribute */ -# define GPIO_CFG_PULLUP (1 << GPIO_CNF_SHIFT) /* Bit 11: Internal pull-up */ -# define GPIO_CFG_DEGLITCH (2 << GPIO_CNF_SHIFT) /* Bit 12: Internal glitch filter */ -# define GPIO_CFG_OPENDRAIN (4 << GPIO_CNF_SHIFT) /* Bit 13: Open drain */ +#define GPIO_CFG_MASK (3 << GPIO_CFG_SHIFT) +# define GPIO_CFG_DEFAULT (0 << GPIO_CFG_SHIFT) /* Default, no attribute */ +# define GPIO_CFG_PULLUP (1 << GPIO_CFG_SHIFT) /* Bit 11: Internal pull-up */ +# define GPIO_CFG_DEGLITCH (2 << GPIO_CFG_SHIFT) /* Bit 12: Internal glitch filter */ +# define GPIO_CFG_OPENDRAIN (4 << GPIO_CFG_SHIFT) /* Bit 13: Open drain */ /* If the pin is an GPIO output, then this identifies the initial output value: * .... .... V... .... @@ -97,9 +97,9 @@ #define GPIO_PORT_SHIFT (5) /* Bit 5-6: Port number */ #define GPIO_PORT_MASK (3 << GPIO_PORT_SHIFT) -# define GPIO_PORT_PIOA (0 << GPIO_CNF_SHIFT) -# define GPIO_PORT_PIOB (1 << GPIO_CNF_SHIFT) -# define GPIO_PORT_PIOC (2 << GPIO_CNF_SHIFT) +# define GPIO_PORT_PIOA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORT_PIOC (2 << GPIO_PORT_SHIFT) /* This identifies the bit in the port: * .... .... ...B BBBB @@ -223,20 +223,6 @@ EXTERN void sam3u_gpiowrite(uint16_t pinset, bool value); EXTERN bool sam3u_gpioread(uint16_t pinset); -/************************************************************************************ - * Function: sam3u_dumpgpio - * - * Description: - * Dump all GPIO registers associated with the port of the provided pin description. - * - ************************************************************************************/ - -#ifdef CONFIG_DEBUG -EXTERN int sam3u_dumpgpio(uint16_t pinset, const char *msg); -#else -# define sam3u_dumpgpio(p,m) -#endif - #undef EXTERN #if defined(__cplusplus) } diff --git a/arch/arm/src/sam3u/sam3u_pio.c b/arch/arm/src/sam3u/sam3u_pio.c index 6c40c1dcdb..7ae1d90b4a 100755 --- a/arch/arm/src/sam3u/sam3u_pio.c +++ b/arch/arm/src/sam3u/sam3u_pio.c @@ -63,101 +63,225 @@ ****************************************************************************/ /**************************************************************************** - * Private Function Prototypes + * Private Data ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/**************************************************************************** + * Name: sam3u_gpiobase + * + * Description: + * Returun the base address of the GPIO register set + * + ****************************************************************************/ + +static inline uintptr_t sam3u_gpiobase(uint16_t cfgset) +{ + int port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + return SAM3U_PION_BASE(port >> GPIO_PORT_SHIFT); +} + +/**************************************************************************** + * Name: sam3u_gpiopin + * + * Description: + * Returun the base address of the GPIO register set + * + ****************************************************************************/ + +static inline int sam3u_gpiopin(uint16_t cfgset) +{ + return 1 << ((cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +/**************************************************************************** * Name: sam3u_configinput * * Description: * Configure a GPIO input pin based on bit-encoded description of the pin. * - ************************************************************************************/ + ****************************************************************************/ -static inline int sam3u_configinput(uint16_t cfgset) +static inline int sam3u_configinput(uintptr_t base, uint32_t pin, + uint16_t cfgset) { -#warning "Not implemented" -return -ENOSYS; + /* Disable interrupts on the pin */ + + putreg32(pin, base+SAM3U_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & GPIO_CFG_PULLUP) != 0) + { + putreg32(pin, base+SAM3U_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base+SAM3U_PIO_PUDR_OFFSET); + } + + /* Check if filtering should be enabled */ + + if ((cfgset & GPIO_CFG_DEGLITCH) != 0) + { + putreg32(pin, base+SAM3U_PIO_IFER_OFFSET); + } + else + { + putreg32(pin, base+SAM3U_PIO_IFDR_OFFSET); + } + + /* Configure the pin as an input and enable the GPIO function */ + + putreg32(pin, base+SAM3U_PIO_ODR_OFFSET); + putreg32(pin, base+SAM3U_PIO_PER_OFFSET); + + /* To-Do: If DEGLITCH is selected, need to configure DIFSR, SCIFSR, and + * registers. This would probably best be done with another, new + * API... perhaps sam3u_configfilter() + */ + + return OK; } -/************************************************************************************ +/**************************************************************************** * Name: sam3u_configoutput * * Description: * Configure a GPIO output pin based on bit-encoded description of the pin. * - ************************************************************************************/ + ****************************************************************************/ -static inline int sam3u_configoutput(uint16_t cfgset) +static inline int sam3u_configoutput(uintptr_t base, uint32_t pin, + uint16_t cfgset) { -#warning "Not implemented" -return -ENOSYS; + /* Disable interrupts on the pin */ + + putreg32(pin, base+SAM3U_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & GPIO_CFG_PULLUP) != 0) + { + putreg32(pin, base+SAM3U_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base+SAM3U_PIO_PUDR_OFFSET); + } + + /* Enable the open drain driver if requrested */ + + if ((cfgset & GPIO_CFG_OPENDRAIN) != 0) + { + putreg32(pin, base+SAM3U_PIO_MDER_OFFSET); + } + else + { + putreg32(pin, base+SAM3U_PIO_MDDR_OFFSET); + } + + /* Set default value */ + + if ((cfgset & GPIO_OUTPUT_SET) != 0) + { + putreg32(pin, base+SAM3U_PIO_SODR_OFFSET); + } + else + { + putreg32(pin, base+SAM3U_PIO_CODR_OFFSET); + } + + /* Configure the pin as an input and enable the GPIO function */ + + putreg32(pin, base+SAM3U_PIO_OER_OFFSET); + putreg32(pin, base+SAM3U_PIO_PER_OFFSET); + return OK; } -/************************************************************************************ - * Name: sam3u_configperipha +/**************************************************************************** + * Name: sam3u_configperiph * * Description: - * Configure a GPIO pin driven by a peripheral A signal based on bit-encoded - * description of the pin. + * Configure a GPIO pin driven by a peripheral A or B signal based on + * bit-encoded description of the pin. * - ************************************************************************************/ + ****************************************************************************/ -static inline int sam3u_configperipha(uint16_t cfgset) +static inline int sam3u_configperiph(uintptr_t base, uint32_t pin, + uint16_t cfgset) { -#warning "Not implemented" -return -ENOSYS; -} + uint32_t regval; -/************************************************************************************ - * Name: sam3u_configperipha - * - * Description: - * Configure a GPIO pin driven by a peripheral A signal based on bit-encoded - * description of the pin. - * - ************************************************************************************/ + /* Disable interrupts on the pin */ -static inline int sam3u_configperiphb(uint16_t cfgset) -{ -#warning "Not implemented" -return -ENOSYS; + putreg32(pin, base+SAM3U_PIO_IDR_OFFSET); + + /* Enable/disable the pull-up as requested */ + + if ((cfgset & GPIO_CFG_PULLUP) != 0) + { + putreg32(pin, base+SAM3U_PIO_PUER_OFFSET); + } + else + { + putreg32(pin, base+SAM3U_PIO_PUDR_OFFSET); + } + + /* Configure pin, depending upon the peripheral A or B*/ + + regval = getreg32(base+SAM3U_PIO_ABSR_OFFSET); + if ((cfgset & GPIO_MODE_MASK) == GPIO_PERIPHA) + { + regval &= ~pin; + } + else + { + regval |= pin; + } + putreg32(pin, base+SAM3U_PIO_ABSR_OFFSET); + + /* Disable PIO functionality */ + + putreg32(pin, base+SAM3U_PIO_PDR_OFFSET); + return OK; } /**************************************************************************** * Global Functions ****************************************************************************/ -/************************************************************************************ +/**************************************************************************** * Name: sam3u_configgpio * * Description: * Configure a GPIO pin based on bit-encoded description of the pin. * - ************************************************************************************/ + ****************************************************************************/ int sam3u_configgpio(uint16_t cfgset) { - int ret; + uintptr_t base = sam3u_gpiobase(cfgset); + uint32_t pin = sam3u_gpiopin(cfgset); + int ret; switch (cfgset & GPIO_MODE_MASK) { case GPIO_INPUT: - ret = sam3u_configinput(cfgset); + ret = sam3u_configinput(base, pin, cfgset); break; case GPIO_OUTPUT: - ret = sam3u_configoutput(cfgset); + ret = sam3u_configoutput(base, pin, cfgset); break; case GPIO_PERIPHA: - ret = sam3u_configperipha(cfgset); + case GPIO_PERIPHB: + ret = sam3u_configperiph(base, pin, cfgset); break; - case GPIO_PERIPHB: - ret = sam3u_configperiphb(cfgset); - break; - default: ret = -EINVAL; break; @@ -165,45 +289,51 @@ int sam3u_configgpio(uint16_t cfgset) return ret; } -/************************************************************************************ +/**************************************************************************** * Name: sam3u_gpiowrite * * Description: * Write one or zero to the selected GPIO pin * - ************************************************************************************/ + ****************************************************************************/ void sam3u_gpiowrite(uint16_t pinset, bool value) { -#warning "Not implemented" + uintptr_t base = sam3u_gpiobase(pinset); + uint32_t pin = sam3u_gpiopin(pinset); + + if (value) + { + putreg32(pin, base+SAM3U_PIO_SODR_OFFSET); + } + else + { + putreg32(pin, base+SAM3U_PIO_CODR_OFFSET); + } } -/************************************************************************************ +/**************************************************************************** * Name: sam3u_gpioread * * Description: * Read one or zero from the selected GPIO pin * - ************************************************************************************/ + ****************************************************************************/ bool sam3u_gpioread(uint16_t pinset) { -#warning "Not implemented" -return false; -} + uintptr_t base = sam3u_gpiobase(pinset); + uint32_t pin = sam3u_gpiopin(pinset); + uint32_t regval; -/************************************************************************************ - * Function: sam3u_dumpgpio - * - * Description: - * Dump all GPIO registers associated with the port of the provided pin description. - * - ************************************************************************************/ + if ((pinset & GPIO_MODE_MASK) == GPIO_OUTPUT) + { + regval = getreg32(base+SAM3U_PIO_ODSR_OFFSET); + } + else + { + regval = getreg32(base+SAM3U_PIO_PDSR_OFFSET); + } -#ifdef CONFIG_DEBUG -int sam3u_dumpgpio(uint16_t pinset, const char *msg) -{ -#warning "Not implemented" -return -ENOSYS; + return (regval & pin) != 0; } -#endif diff --git a/arch/arm/src/sam3u/sam3u_pio.h b/arch/arm/src/sam3u/sam3u_pio.h index 165b2e663b..ab20ace9b9 100755 --- a/arch/arm/src/sam3u/sam3u_pio.h +++ b/arch/arm/src/sam3u/sam3u_pio.h @@ -113,6 +113,7 @@ #define PIOA (0) #define PIOB (1) #define PIOC (2) +#define NPIO (3) #define SAM3U_PIO_PER(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_PER_OFFSET) #define SAM3U_PIO_PDR(n) (SAM3U_PIO_BASE(n)+SAM3U_PIO_PDR_OFFSET)