Add GPIO logic

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2105 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2009-09-29 16:38:36 +00:00
parent dc1f5265a1
commit d15e6a56d5
3 changed files with 261 additions and 25 deletions

View File

@ -41,6 +41,7 @@
#include <sys/types.h>
#include <debug.h>
#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

View File

@ -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 */

View File

@ -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