From d15e6a56d51eaa3c96f6bbd0cfbb528b07a6c21d Mon Sep 17 00:00:00 2001 From: patacongo Date: Tue, 29 Sep 2009 16:38:36 +0000 Subject: [PATCH] Add GPIO logic git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2105 42af7a65-404d-4744-a932-0658087f49c3 --- arch/arm/src/stm32/stm32_gpio.c | 215 +++++++++++++++++++++++++++- arch/arm/src/stm32/stm32_gpio.h | 5 + arch/arm/src/stm32/stm32_internal.h | 66 +++++---- 3 files changed, 261 insertions(+), 25 deletions(-) diff --git a/arch/arm/src/stm32/stm32_gpio.c b/arch/arm/src/stm32/stm32_gpio.c index a92fd1d1c6..a806baeed5 100755 --- a/arch/arm/src/stm32/stm32_gpio.c +++ b/arch/arm/src/stm32/stm32_gpio.c @@ -41,6 +41,7 @@ #include #include +#include "up_arch.h" #include "chip.h" #include "stm32_gpio.h" #include "stm32_internal.h" @@ -52,9 +53,37 @@ /**************************************************************************** * Private Types ****************************************************************************/ +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uint32 g_gpiobase[STM32_NGPIO] = +{ +#if STM32_NGPIO > 0 + STM32_GPIOA_BASE, +#endif +#if STM32_NGPIO > 1 + STM32_GPIOB_BASE, +#endif +#if STM32_NGPIO > 2 + STM32_GPIOC_BASE, +#endif +#if STM32_NGPIO > 3 + STM32_GPIOD_BASE, +#endif +#if STM32_NGPIO > 4 + STM32_GPIOE_BASE, +#endif +#if STM32_NGPIO > 5 + STM32_GPIOF_BASE, +#endif +#if STM32_NGPIO > 6 + STM32_GPIOG_BASE, +#endif +}; /**************************************************************************** - * Private Function Prototypes + * Private Functions ****************************************************************************/ /**************************************************************************** @@ -71,6 +100,190 @@ int stm32_configgpio(uint32 cfgset) { + uint32 gpiobase; + uint32 cr; + uint32 regval; + uint32 regaddr; + unsigned int gpio; + unsigned int pin; + unsigned int pos; + unsigned int mode; + unsigned int cnf; + boolean output; + + /* Verify that this hardware supports the select GPIO port */ + + gpio = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (gpio < STM32_NGPIO) + { + /* Get the port base address */ + + gpiobase = g_gpiobase[gpio]; + + /* Get the pin number and select the port configuration register for that pin */ + + pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + if (pin < 8) + { + cr = gpiobase + STM32_GPIO_CRL_OFFSET; + pos = pin; + } + else + { + cr = gpiobase + STM32_GPIO_CRH_OFFSET; + pos = pin - 8; + } + + /* Input or output? */ + + output = ((cfgset & GPIO_OUTPUT_PIN) != 0); + + /* Decode the mode and configuration */ + + if (output) + { + mode = (cfgset & GPIO_MODE_MASK) >> GPIO_MODE_SHIFT; + } + else + { + mode = 0; + } + + cnf = (cfgset & GPIO_CNF_MASK) >> GPIO_CNF_SHIFT; + + /* Set the port configuration register */ + + regval = getreg32(cr); + regval &= ~(GPIO_CR_MODE_MASK(pos)|GPIO_CRL_CNF_MASK(pos)); + regval |= (mode << GPIO_CR_MODE_SHIFT(pos)) | (cnf << GPIO_CRL_CNF_SHIFT(pos)); + putreg32(regval, cr); + + /* Set or reset the corresponding BRR/BSRR bit */ + + if (output) + { + /* It is an output pin, we need to set/clear the output value */ + + + if ((cfgset & GPIO_OUTPUT_VALUE) != 0) + { + /* Use the BSRR register to set the output */ + + regaddr = gpiobase + STM32_GPIO_BSRR_OFFSET; + } + else + { + /* Use the BRR register to clear */ + + regaddr = gpiobase + STM32_GPIO_BRR_OFFSET; + } + } + else + { + if ((cfgset & GPIO_MODE_MASK) == GPIO_CNF_INPULLDWN) + { + regaddr = gpiobase + STM32_GPIO_BSRR_OFFSET; + } + else if ((cfgset & GPIO_MODE_MASK) == GPIO_CNF_INPULLUP) + { + regaddr = gpiobase + STM32_GPIO_BRR_OFFSET; + } + else + { + return OK; + } + } + + regval = getreg32(regaddr); + regval |= (1 << pin); + putreg32(regval, regaddr); + return OK; + } + return ERROR; } +/**************************************************************************** + * Name: stm32_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void stm32_gpiowrite(uint32 pinset, boolean value) +{ + uint32 gpiobase; + uint32 offset; + unsigned int gpio; + unsigned int pin; + + gpio = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (gpio < STM32_NGPIO) + { + /* Get the port base address */ + + gpiobase = g_gpiobase[gpio]; + + /* Get the pin number */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + + /* Set or clear the output on the pin */ + + if (value) + { + offset = STM32_GPIO_BSRR_OFFSET; + } + else + offset = STM32_GPIO_BRR_OFFSET; + { + } + putreg32((1 << pin), gpiobase + offset); + } +} + +/**************************************************************************** + * Name: stm32_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +boolean stm32_gpioread(uint32 pinset) +{ + uint32 gpiobase; + unsigned int gpio; + unsigned int pin; + + gpio = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + if (gpio < STM32_NGPIO) + { + /* Get the port base address */ + + gpiobase = g_gpiobase[gpio]; + + /* Get the pin number and return the input state of that pin */ + + pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; + return ((getreg32(gpiobase + STM32_GPIO_IDR_OFFSET) & (1 << pin)) != 0); + } + return 0; +} + +/**************************************************************************** + * Function: stm32_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +#if 0 /* Not implemented */ +int stm32_dumpgpio(uint32 pinset, const char *msg) +{ +} +#endif + + diff --git a/arch/arm/src/stm32/stm32_gpio.h b/arch/arm/src/stm32/stm32_gpio.h index e01639c3b4..4e2c9f8acb 100644 --- a/arch/arm/src/stm32/stm32_gpio.h +++ b/arch/arm/src/stm32/stm32_gpio.h @@ -148,6 +148,11 @@ /* Port configuration register low */ +#define GPIO_CR_MODE_SHIFT(n) ((n) << 1) +#define GPIO_CR_MODE_MASK(n) (3 << GPIO_CR_MODE_SHIFT(n)) +#define GPIO_CRL_CNF_SHIFT(n) (2+((n) << 1)) +#define GPIO_CRL_CNF_MASK(n) (3 << GPIO_CRL_CNF_SHIFT(n)) + #define GPIO_CRL_MODE0_SHIFT (0) /* Bits 1:0: Port mode bits */ #define GPIO_CRL_MODE0_MASK (3 << GPIO_CRL_MODE0_SHIFT) #define GPIO_CRL_CNF0_SHIFT (2) /* Bits 3:2: Port configuration bits */ diff --git a/arch/arm/src/stm32/stm32_internal.h b/arch/arm/src/stm32/stm32_internal.h index e737473b5e..b6608d0ed1 100755 --- a/arch/arm/src/stm32/stm32_internal.h +++ b/arch/arm/src/stm32/stm32_internal.h @@ -59,34 +59,52 @@ /* Bit-encoded input to stm32_configgpio() *******************************************/ /* Encoding: - * FFFn nPPP IIIn nnnn nnnn nnnn VPPP BBBB - * - * These bits set the primary function of the pin: - * FFFn nnnn nnnn nnnn nnnn nnnn nnnn nnnn + * .... .... .... .... OFFS S... VPPP BBBB */ -#define GPIO_FUNC_SHIFT 29 /* Bit 31-29: GPIO function */ -#define GPIO_FUNC_MASK (7 << GPIO_FUNC_SHIFT) -#define GPIO_FUNC_INFLOAT (0 << GPIO_FUNC_SHIFT) /* Input floating */ -#define GPIO_FUNC_INPULLUP (1 << GPIO_FUNC_SHIFT) /* Input pull-up */ -#define GPIO_FUNC_INPULLDWN (2 << GPIO_FUNC_SHIFT) /* Input pull-down */ -#define GPIO_FUNC_ANALOGIN (3 << GPIO_FUNC_SHIFT) /* Analog input */ -#define GPIO_FUNC_OUTOD (4 << GPIO_FUNC_SHIFT) /* Output open-drain */ -#define GPIO_FUNC_OUTPP (5 << GPIO_FUNC_SHIFT) /* Output push-pull */ -#define GPIO_FUNC_AFPP (6 << GPIO_FUNC_SHIFT) /* Altnernate function push-pull */ -#define GPIO_FUNC_AFOD (7 << GPIO_FUNC_SHIFT) /* Altnernate function open-drain */ +/* Output mode: + * + * .... .... .... .... O... .... VPPP BBBB + */ + +#define GPIO_OUTPUT_PIN (1 << 15) /* Bit 15: Output mode */ + +/* These bits set the primary function of the pin: + * .... .... .... .... FFF. .... .... .... + */ + +#define GPIO_CNF_SHIFT 13 /* Bits 13-14: GPIO function */ +#define GPIO_CNF_MASK (3 << GPIO_CNF_SHIFT) + +# define GPIO_CNF_ANALOGIN (0 << GPIO_CNF_SHIFT) /* Analog input */ +# define GPIO_CNF_INFLOAT (1 << GPIO_CNF_SHIFT) /* Input floating */ +# define GPIO_CNF_INPULLUP (2 << GPIO_CNF_SHIFT) /* Input pull-up */ +# define GPIO_CNF_INPULLDWN (3 << GPIO_CNF_SHIFT) /* Input pull-down */ + +# define GPIO_CNF_OUTPP (0 << GPIO_CNF_SHIFT) /* Output push-pull */ +# define GPIO_CNF_OUTOD (1 << GPIO_CNF_SHIFT) /* Output open-drain */ +# define GPIO_CNF_AFPP (2 << GPIO_CNF_SHIFT) /* Altnernate function push-pull */ +# define GPIO_CNF_AFOD (3 << GPIO_CNF_SHIFT) /* Altnernate function open-drain */ + +/* Maximum frequency selection: + * .... .... .... .... ...S S... .... .... + */ + +#define GPIO_MODE_SHIFT 11 /* Bits 11-12: GPIO frequency selection */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_MODE_INPUT (0 << GPIO_MODE_SHIFT) /* Input mode (reset state) */ +# define GPIO_MODE_10MHz (1 << GPIO_MODE_SHIFT) /* Output mode, max speed 10 MHz */ +# define GPIO_MODE_2MHz (2 << GPIO_MODE_SHIFT) /* Output mode, max speed 2 MHz */ +# define GPIO_MODE_50MHz (3 << GPIO_MODE_SHIFT) /* Output mode, max speed 50 MHz */ /* If the pin is an GPIO digital output, then this identifies the initial output value: - * nnnn nnnn nnnn nnnn nnnn nnnn Vnnn nnnn + * .... .... .... .... .... .... V... .... */ -#define GPIO_VALUE_SHIFT 7 /* Bit 7: If output, inital value of output */ -#define GPIO_VALUE_MASK (1 << GPIO_VALUE_SHIFT) -#define GPIO_VALUE_ZERO (0 << GPIO_VALUE_SHIFT) /* Initial value is zero */ -#define GPIO_VALUE_ONE (1 << GPIO_VALUE_SHIFT) /* Initial value is one */ +#define GPIO_OUTPUT_VALUE (1 << 7) /* Bit 7: If output, inital value of output */ /* This identifies the GPIO port: - * nnnn nnnn nnnn nnnn nnnn nnnn nPPP nnnn + * .... .... .... .... .... .... .PPP .... */ #define GPIO_PORT_SHIFT 4 /* Bit 4-6: Port number */ @@ -100,11 +118,11 @@ #define GPIO_PORTG (6 << GPIO_PORT_SHIFT) /* GPIOG */ /* This identifies the bit in the port: - * nnnn nnnn nnnn nnnn nnnn nnnn nnnn BBBB + * .... .... .... .... .... .... .... BBBB */ -#define GPIO_NUMBER_SHIFT 0 /* Bits 0-3: GPIO number: 0-15 */ -#define GPIO_NUMBER_MASK (15 << GPIO_NUMBER_SHIFT) +#define GPIO_PIN_SHIFT 0 /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) /************************************************************************************ * Public Types @@ -180,7 +198,7 @@ EXTERN void stm32_gpiowrite(uint32 pinset, boolean value); * ****************************************************************************/ -EXTERN boolean stm32_gpioread(uint32 pinset, boolean value); +EXTERN boolean stm32_gpioread(uint32 pinset); /**************************************************************************** * Function: stm32_dumpgpio