Finish port of GPIO driver for STM3240

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4122 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2011-11-23 15:08:05 +00:00
parent 67eb344218
commit 5bcaa4dfb8
4 changed files with 428 additions and 241 deletions

View File

@ -53,20 +53,26 @@
#define STM32_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */
#define STM32_SYSCFG_PMC_OFFSET 0x0004 /* SYSCFG peripheral mode configuration register */
#define STM32_SYSCFG_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */
#define STM32_SYSCFG_EXTICR1_OFFSET 0x0008 /* SYSCFG external interrupt configuration register 1 */
#define STM32_SYSCFG_EXTICR2_OFFSET 0x000c /* SYSCFG external interrupt configuration register 2 */
#define STM32_SYSCFG_EXTICR3_OFFSET 0x0010 /* SYSCFG external interrupt configuration register 3 */
#define STM32_SYSCFG_EXTICR4_OFFSET 0x0014 /* SYSCFG external interrupt configuration register 4 */
#define STM32_SYSCFG_CMPCR_OFFSET 0x0020 /* Compensation cell control register */
/* Register Addresses *******************************************************************************/
#define STM32_SYSCFG_MEMRMP (STM32_SYSCFG_BASE+STM32_SYSCFG_MEMRMP_OFFSET)
#define STM32_SYSCFG_PMC (STM32_SYSCFG_BASE+STM32_SYSCFG_PMC_OFFSET)
#define STM32_SYSCFG_EXTICR(p) (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR_OFFSET(p))
#define STM32_SYSCFG_EXTICR1 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR1_OFFSET)
#define STM32_SYSCFG_EXTICR2 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR2_OFFSET)
#define STM32_SYSCFG_EXTICR3 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR3_OFFSET)
#define STM32_SYSCFG_EXTICR4 (STM32_SYSCFG_BASE+STM32_SYSCFG_EXTICR4_OFFSET)
#define STM32_SYSCFG_CMPCR (STM32_SYSCFG_BASE+STM32_SYSCFG_CMPCR_OFFSET)
/* Register Bitfield Definitions ********************************************************************/
@ -75,10 +81,10 @@
#define SYSCFG_MEMRMP_SHIFT (0) /* Bits 1:0 MEM_MODE: Memory mapping selection */
#define SYSCFG_MEMRMP_MASK (3 << SYSCFG_MEMRMP_SHIFT)
# define SYSCFG_MEMRMP _MASK (0 << SYSCFG_MEMRMP_SHIFT) /* 00: Main Flash memory mapped at 0x0000 0000 */
# define SYSCFG_MEMRMP _MASK (1 << SYSCFG_MEMRMP_SHIFT) /* 01: System Flash memory mapped at 0x0000 0000 */
# define SYSCFG_MEMRMP _MASK (2 << SYSCFG_MEMRMP_SHIFT) /* 10: FSMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x0000 0000 */
# define SYSCFG_MEMRMP _MASK (3 << SYSCFG_MEMRMP_SHIFT) /* 11: Embedded SRAM (112kB) mapped at 0x0000 0000 */
# define SYSCFG_MEMRMP_FLASH (0 << SYSCFG_MEMRMP_SHIFT) /* 00: Main Flash memory mapped at 0x0000 0000 */
# define SYSCFG_MEMRMP_SYSTEM (1 << SYSCFG_MEMRMP_SHIFT) /* 01: System Flash memory mapped at 0x0000 0000 */
# define SYSCFG_MEMRMP_FSMC (2 << SYSCFG_MEMRMP_SHIFT) /* 10: FSMC Bank1 (NOR/PSRAM 1 and 2) mapped at 0x0000 0000 */
# define SYSCFG_MEMRMP_SRAM (3 << SYSCFG_MEMRMP_SHIFT) /* 11: Embedded SRAM (112kB) mapped at 0x0000 0000 */
/* SYSCFG peripheral mode configuration register */
@ -96,41 +102,45 @@
#define SYSCFG_EXTICR_PORTH (7) /* 0111: PH[x] pin */
#define SYSCFG_EXTICR_PORTI (8) /* 1000: PI[x] pin */
#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-3: EXIT 0 coinfiguration */
#define SYSCFG_EXTICR1_EXTI0_MASK (15 << SYSCFG_EXTICR1_EXTI0_SHIFT)
#define SYSCFG_EXTICR1_EXTI1_SHIFT (0) /* Bits 4-7: EXIT 1 coinfiguration */
#define SYSCFG_EXTICR1_EXTI1_MASK (15 << SYSCFG_EXTICR1_EXTI1_SHIFT)
#define SYSCFG_EXTICR1_EXTI2_SHIFT (0) /* Bits 8-11: EXIT 2 coinfiguration */
#define SYSCFG_EXTICR1_EXTI2_MASK (15 << SYSCFG_EXTICR1_EXTI2_SHIFT)
#define SYSCFG_EXTICR1_EXTI3_SHIFT (0) /* Bits 12-15: EXIT 3 coinfiguration */
#define SYSCFG_EXTICR1_EXTI3_MASK (15 << SYSCFG_EXTICR1_EXTI3_SHIFT)
#define SYSCFG_EXTICR_PORT_MASK (15)
#define SYSCFG_EXTICR_EXTI_SHIFT(g) (((g) & 3) << 2)
#define SYSCFG_EXTICR_EXTI_MASK(g) (SYSCFG_EXTICR_PORT_MASK << (SYSCFG_EXTICR_EXTI_SHIFT(g)))
#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-3: EXIT 4 coinfiguration */
#define SYSCFG_EXTICR2_EXTI4_MASK (15 << SYSCFG_EXTICR2_EXTI4_SHIFT)
#define SYSCFG_EXTICR2_EXTI5_SHIFT (0) /* Bits 4-7: EXIT 5 coinfiguration */
#define SYSCFG_EXTICR2_EXTI5_MASK (15 << SYSCFG_EXTICR2_EXTI5_SHIFT)
#define SYSCFG_EXTICR2_EXTI6_SHIFT (0) /* Bits 8-11: EXIT 6 coinfiguration */
#define SYSCFG_EXTICR2_EXTI6_MASK (15 << SYSCFG_EXTICR2_EXTI6_SHIFT)
#define SYSCFG_EXTICR2_EXTI7_SHIFT (0) /* Bits 12-15: EXIT 7 coinfiguration */
#define SYSCFG_EXTICR2_EXTI7_MASK (15 << SYSCFG_EXTICR2_EXTI7_SHIFT)
#define SYSCFG_EXTICR1_EXTI0_SHIFT (0) /* Bits 0-3: EXTI 0 coinfiguration */
#define SYSCFG_EXTICR1_EXTI0_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI0_SHIFT)
#define SYSCFG_EXTICR1_EXTI1_SHIFT (4) /* Bits 4-7: EXTI 1 coinfiguration */
#define SYSCFG_EXTICR1_EXTI1_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI1_SHIFT)
#define SYSCFG_EXTICR1_EXTI2_SHIFT (8) /* Bits 8-11: EXTI 2 coinfiguration */
#define SYSCFG_EXTICR1_EXTI2_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI2_SHIFT)
#define SYSCFG_EXTICR1_EXTI3_SHIFT (12) /* Bits 12-15: EXTI 3 coinfiguration */
#define SYSCFG_EXTICR1_EXTI3_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR1_EXTI3_SHIFT)
#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-3: EXIT 8 coinfiguration */
#define SYSCFG_EXTICR3_EXTI8_MASK (15 << SYSCFG_EXTICR3_EXTI8_SHIFT)
#define SYSCFG_EXTICR3_EXTI9_SHIFT (0) /* Bits 4-7: EXIT 9 coinfiguration */
#define SYSCFG_EXTICR3_EXTI9_MASK (15 << SYSCFG_EXTICR3_EXTI9_SHIFT)
#define SYSCFG_EXTICR3_EXTI10_SHIFT (0) /* Bits 8-11: EXIT 10 coinfiguration */
#define SYSCFG_EXTICR3_EXTI10_MASK (15 << SYSCFG_EXTICR3_EXTI10_SHIFT)
#define SYSCFG_EXTICR3_EXTI11_SHIFT (0) /* Bits 12-15: EXIT 11 coinfiguration */
#define SYSCFG_EXTICR3_EXTI11_MASK (15 << SYSCFG_EXTICR3_EXTI11_SHIFT)
#define SYSCFG_EXTICR2_EXTI4_SHIFT (0) /* Bits 0-3: EXTI 4 coinfiguration */
#define SYSCFG_EXTICR2_EXTI4_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI4_SHIFT)
#define SYSCFG_EXTICR2_EXTI5_SHIFT (4) /* Bits 4-7: EXTI 5 coinfiguration */
#define SYSCFG_EXTICR2_EXTI5_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI5_SHIFT)
#define SYSCFG_EXTICR2_EXTI6_SHIFT (8) /* Bits 8-11: EXTI 6 coinfiguration */
#define SYSCFG_EXTICR2_EXTI6_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI6_SHIFT)
#define SYSCFG_EXTICR2_EXTI7_SHIFT (12) /* Bits 12-15: EXTI 7 coinfiguration */
#define SYSCFG_EXTICR2_EXTI7_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR2_EXTI7_SHIFT)
#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-3: EXIT 12 coinfiguration */
#define SYSCFG_EXTICR4_EXTI12_MASK (15 << SYSCFG_EXTICR4_EXTI12_SHIFT)
#define SYSCFG_EXTICR4_EXTI13_SHIFT (0) /* Bits 4-7: EXIT 13 coinfiguration */
#define SYSCFG_EXTICR4_EXTI13_MASK (15 << SYSCFG_EXTICR4_EXTI13_SHIFT)
#define SYSCFG_EXTICR4_EXTI14_SHIFT (0) /* Bits 8-11: EXIT 14 coinfiguration */
#define SYSCFG_EXTICR4_EXTI14_MASK (15 << SYSCFG_EXTICR4_EXTI14_SHIFT)
#define SYSCFG_EXTICR4_EXTI15_SHIFT (0) /* Bits 12-15: EXIT 15 coinfiguration */
#define SYSCFG_EXTICR4_EXTI15_MASK (15 << SYSCFG_EXTICR4_EXTI15_SHIFT)
#define SYSCFG_EXTICR3_EXTI8_SHIFT (0) /* Bits 0-3: EXTI 8 coinfiguration */
#define SYSCFG_EXTICR3_EXTI8_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI8_SHIFT)
#define SYSCFG_EXTICR3_EXTI9_SHIFT (4) /* Bits 4-7: EXTI 9 coinfiguration */
#define SYSCFG_EXTICR3_EXTI9_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI9_SHIFT)
#define SYSCFG_EXTICR3_EXTI10_SHIFT (8) /* Bits 8-11: EXTI 10 coinfiguration */
#define SYSCFG_EXTICR3_EXTI10_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI10_SHIFT)
#define SYSCFG_EXTICR3_EXTI11_SHIFT (12) /* Bits 12-15: EXTI 11 coinfiguration */
#define SYSCFG_EXTICR3_EXTI11_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR3_EXTI11_SHIFT)
#define SYSCFG_EXTICR4_EXTI12_SHIFT (0) /* Bits 0-3: EXTI 12 coinfiguration */
#define SYSCFG_EXTICR4_EXTI12_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI12_SHIFT)
#define SYSCFG_EXTICR4_EXTI13_SHIFT (4) /* Bits 4-7: EXTI 13 coinfiguration */
#define SYSCFG_EXTICR4_EXTI13_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI13_SHIFT)
#define SYSCFG_EXTICR4_EXTI14_SHIFT (8) /* Bits 8-11: EXTI 14 coinfiguration */
#define SYSCFG_EXTICR4_EXTI14_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI14_SHIFT)
#define SYSCFG_EXTICR4_EXTI15_SHIFT (12) /* Bits 12-15: EXTI 15 coinfiguration */
#define SYSCFG_EXTICR4_EXTI15_MASK (SYSCFG_EXTICR_PORT_MASK << SYSCFG_EXTICR4_EXTI15_SHIFT)
/* Compensation cell control register */

View File

@ -54,7 +54,7 @@
#define STM32_AFIO_EVCR_OFFSET 0x0000 /* Event control register */
#define STM32_AFIO_MAPR_OFFSET 0x0004 /* AF remap and debug I/O configuration register */
#define STM32_AFIO_EXTICR_OFFSET(p) (0x0008 + ((p) & 0xC)) /* Registers are displaced by 4! */
#define STM32_AFIO_EXTICR_OFFSET(p) (0x0008 + ((p) & 0x000c)) /* Registers are displaced by 4! */
#define STM32_AFIO_EXTICR1_OFFSET 0x0008 /* External interrupt configuration register 1 */
#define STM32_AFIO_EXTICR2_OFFSET 0x000c /* External interrupt configuration register 2 */
#define STM32_AFIO_EXTICR3_OFFSET 0x0010 /* External interrupt configuration register 3 */

View File

@ -52,6 +52,14 @@
#include "chip.h"
#include "stm32_gpio.h"
#if defined(CONFIG_STM32_STM32F40XX)
# include "chip/stm32_syscfg.h"
#endif
/****************************************************************************
* Private Types
****************************************************************************/
/****************************************************************************
* Private Data
****************************************************************************/
@ -96,179 +104,6 @@ const uint32_t g_gpiobase[STM32_NGPIO_PORTS] =
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: stm32_gpio_configlock (for the STM32F10xxx family
****************************************************************************/
#if defined(CONFIG_STM32_STM32F10XX)
static int stm32_gpio_configlock(uint32_t cfgset, bool altlock)
{
uint32_t base;
uint32_t cr;
uint32_t regval;
uint32_t regaddr;
unsigned int port;
unsigned int pin;
unsigned int pos;
unsigned int modecnf;
bool input;
/* Verify that this hardware supports the select GPIO port */
port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
if (port >= STM32_NGPIO_PORTS)
{
return -EINVAL;
}
/* Get the port base address */
base = g_gpiobase[port];
/* 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 = base + STM32_GPIO_CRL_OFFSET;
pos = pin;
}
else
{
cr = base + STM32_GPIO_CRH_OFFSET;
pos = pin - 8;
}
/* Input or output? */
input = ((cfgset & GPIO_INPUT) != 0);
/* Decode the mode and configuration */
regval = getreg32(cr);
/* Is present (old) config already in GPIO_ALT? and we got request to
* lock the alternative configuration. If so we allow the following
* changes only:
* - to HiZ (unlocking the configuration)
* - AFPP
* - AFOD
*/
uint32_t oldmode = (regval >> GPIO_CR_MODECNF_SHIFT(pos));
if (altlock &&
(oldmode & (GPIO_MODE_MASK >> GPIO_MODE_SHIFT)) && /* previous state was output? */
((oldmode>>2) & GPIO_CR_CNF_ALTOD) > GPIO_CR_CNF_OUTOD && /* previous state is ALT? */
( ((cfgset & GPIO_CNF_MASK) >> GPIO_CNF_SHIFT) < GPIO_CR_CNF_ALTPP || /* new state is not output ALT? */
input ) ) /* or it is input */
{
return -EINVAL;
}
if (input)
{
/* Input.. force mode = INPUT */
modecnf = 0;
}
else
{
/* Output or alternate function */
modecnf = (cfgset & GPIO_MODE_MASK) >> GPIO_MODE_SHIFT;
}
modecnf |= ((cfgset & GPIO_CNF_MASK) >> GPIO_CNF_SHIFT) << 2;
/* Set the port configuration register */
regval &= ~(GPIO_CR_MODECNF_MASK(pos));
regval |= (modecnf << GPIO_CR_MODECNF_SHIFT(pos));
putreg32(regval, cr);
/* Set or reset the corresponding BRR/BSRR bit */
if (!input)
{
/* It is an output or an alternate function. We have to look at the CNF
* bits to know which.
*/
unsigned int cnf = (cfgset & GPIO_CNF_MASK);
if (cnf != GPIO_CNF_OUTPP && cnf != GPIO_CNF_OUTOD)
{
/* Its an alternate function pin... we can return early */
return OK;
}
}
else
{
/* It is an input pin... Should it configured as an EXTI interrupt? */
if ((cfgset & GPIO_EXTI) != 0)
{
int shift;
/* Yes.. Set the bits in the EXTI CR register */
regaddr = STM32_AFIO_EXTICR(pin);
regval = getreg32(regaddr);
shift = AFIO_EXTICR_EXTI_SHIFT(pin);
regval &= ~(AFIO_EXTICR_PORT_MASK << shift);
regval |= (((uint32_t)port) << shift);
putreg32(regval, regaddr);
}
if ((cfgset & GPIO_CNF_MASK) != GPIO_CNF_INPULLUD)
{
/* Neither... we can return early */
return OK;
}
}
/* If it is an output... set the pin to the correct initial state.
* If it is pull-down or pull up, then we need to set the ODR
* appropriately for that function.
*/
if ((cfgset & GPIO_OUTPUT_SET) != 0)
{
/* Use the BSRR register to set the output */
regaddr = base + STM32_GPIO_BSRR_OFFSET;
}
else
{
/* Use the BRR register to clear */
regaddr = base + STM32_GPIO_BRR_OFFSET;
}
regval = getreg32(regaddr);
regval |= (1 << pin);
putreg32(regval, regaddr);
return OK;
}
#endif
/****************************************************************************
* Name: stm32_gpio_configlock (for the STM32F40xxx family
****************************************************************************/
#if defined(CONFIG_STM32_STM32F40XX)
static int stm32_gpio_configlock(uint32_t cfgset, bool altlock)
{
# warning "Missing logic"
return -ENOSYS;
}
#endif
/****************************************************************************
* Function: stm32_gpioremap
*
@ -394,10 +229,352 @@ void stm32_gpioinit(void)
* To-Do: Auto Power Enable
****************************************************************************/
/****************************************************************************
* Name: stm32_configgpio (for the STM32F10xxx family)
****************************************************************************/
#if defined(CONFIG_STM32_STM32F10XX)
int stm32_configgpio(uint32_t cfgset)
{
return stm32_gpio_configlock(cfgset, true);
uint32_t base;
uint32_t cr;
uint32_t regval;
uint32_t regaddr;
unsigned int port;
unsigned int pin;
unsigned int pos;
unsigned int modecnf;
bool input;
/* Verify that this hardware supports the select GPIO port */
port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
if (port >= STM32_NGPIO_PORTS)
{
return -EINVAL;
}
/* Get the port base address */
base = g_gpiobase[port];
/* 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 = base + STM32_GPIO_CRL_OFFSET;
pos = pin;
}
else
{
cr = base + STM32_GPIO_CRH_OFFSET;
pos = pin - 8;
}
/* Input or output? */
input = ((cfgset & GPIO_INPUT) != 0);
/* Decode the mode and configuration */
regval = getreg32(cr);
if (input)
{
/* Input.. force mode = INPUT */
modecnf = 0;
}
else
{
/* Output or alternate function */
modecnf = (cfgset & GPIO_MODE_MASK) >> GPIO_MODE_SHIFT;
}
modecnf |= ((cfgset & GPIO_CNF_MASK) >> GPIO_CNF_SHIFT) << 2;
/* Set the port configuration register */
regval &= ~(GPIO_CR_MODECNF_MASK(pos));
regval |= (modecnf << GPIO_CR_MODECNF_SHIFT(pos));
putreg32(regval, cr);
/* Set or reset the corresponding BRR/BSRR bit */
if (!input)
{
/* It is an output or an alternate function. We have to look at the CNF
* bits to know which.
*/
unsigned int cnf = (cfgset & GPIO_CNF_MASK);
if (cnf != GPIO_CNF_OUTPP && cnf != GPIO_CNF_OUTOD)
{
/* Its an alternate function pin... we can return early */
return OK;
}
}
else
{
/* It is an input pin... Should it configured as an EXTI interrupt? */
if ((cfgset & GPIO_EXTI) != 0)
{
int shift;
/* Yes.. Set the bits in the EXTI CR register */
regaddr = STM32_AFIO_EXTICR(pin);
regval = getreg32(regaddr);
shift = AFIO_EXTICR_EXTI_SHIFT(pin);
regval &= ~(AFIO_EXTICR_PORT_MASK << shift);
regval |= (((uint32_t)port) << shift);
putreg32(regval, regaddr);
}
if ((cfgset & GPIO_CNF_MASK) != GPIO_CNF_INPULLUD)
{
/* Neither... we can return early */
return OK;
}
}
/* If it is an output... set the pin to the correct initial state.
* If it is pull-down or pull up, then we need to set the ODR
* appropriately for that function.
*/
if ((cfgset & GPIO_OUTPUT_SET) != 0)
{
/* Use the BSRR register to set the output */
regaddr = base + STM32_GPIO_BSRR_OFFSET;
}
else
{
/* Use the BRR register to clear */
regaddr = base + STM32_GPIO_BRR_OFFSET;
}
regval = getreg32(regaddr);
regval |= (1 << pin);
putreg32(regval, regaddr);
return OK;
}
#endif
/****************************************************************************
* Name: stm32_configgpio (for the STM32F40xxx family)
****************************************************************************/
#if defined(CONFIG_STM32_STM32F40XX)
int stm32_configgpio(uint32_t cfgset)
{
uintptr_t base;
uint32_t regval;
uint32_t setting;
unsigned int regoffset;
unsigned int port;
unsigned int pin;
unsigned int pos;
unsigned int pinmode;
/* Verify that this hardware supports the select GPIO port */
port = (cfgset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT;
if (port >= STM32_NGPIO_PORTS)
{
return -EINVAL;
}
/* Get the port base address */
base = g_gpiobase[port];
/* Get the pin number and select the port configuration register for that
* pin
*/
pin = (cfgset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
/* Set up the mode register (and remember whether the pin mode) */
switch (cfgset & GPIO_MODE_MASK)
{
default:
case GPIO_INPUT: /* Input mode */
pinmode = GPIO_MODER_INPUT;
break;
case GPIO_OUTPUT: /* General purpose output mode */
pinmode = GPIO_MODER_OUTPUT;
break;
case GPIO_ALT: /* Alternate function mode */
pinmode = GPIO_MODER_ALT;
break;
case GPIO_ANALOG: /* Analog mode */
pinmode = GPIO_MODER_ANALOG;
break;
}
regval = getreg32(base + STM32_GPIO_MODER_OFFSET);
regval &= ~GPIO_MODER_MASK(pin);
regval |= ((uint32_t)pinmode << GPIO_MODER_SHIFT(pin));
putreg32(regval, base + STM32_GPIO_MODER_OFFSET);
/* Set up the pull-up/pull-down configuration (all but analog pins) */
setting = GPIO_PUPDR_NONE;
if (pinmode != GPIO_MODER_ANALOG)
{
switch (cfgset & GPIO_PUPD_MASK)
{
default:
case GPIO_FLOAT: /* No pull-up, pull-down */
break;
case GPIO_PULLUP: /* Pull-up */
setting = GPIO_PUPDR_PULLUP;
break;
case GPIO_PULLDOWN: /* Pull-down */
setting = GPIO_PUPDR_PULLDOWN;
break;
}
}
regval = getreg32(base + STM32_GPIO_PUPDR_OFFSET);
regval &= ~GPIO_PUPDR_MASK(pin);
regval |= (setting << GPIO_PUPDR_SHIFT(pin));
putreg32(regval, base + STM32_GPIO_PUPDR_OFFSET);
/* Set the alternate function (Only alternate function pins) */
if (pinmode == GPIO_MODER_ALT)
{
setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT;
}
else
{
setting = 0;
}
if (pin < 8)
{
regoffset = STM32_GPIO_AFRL_OFFSET;
pos = pin;
}
else
{
regoffset = STM32_GPIO_ARFH_OFFSET;
pos = pin - 8;
}
regval = getreg32(base + regoffset);
regval &= ~GPIO_AFR_MASK(pos);
regval |= (setting << GPIO_AFR_SHIFT(pos));
putreg32(regval, base + regoffset);
/* Set speed (Only outputs and alternate function pins) */
if (pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT)
{
switch (cfgset & GPIO_SPEED_MASK)
{
default:
case GPIO_SPEED_2MHz: /* 2 MHz Low speed output */
setting = GPIO_OSPEED_2MHz;
break;
case GPIO_SPEED_25MHz: /* 25 MHz Medium speed output */
setting = GPIO_OSPEED_25MHz;
break;
case GPIO_SPEED_20MHz: /* 50 MHz Fast speed output */
setting = GPIO_OSPEED_50MHz;
break;
case GPIO_SPEED_100MHz: /* 100 MHz High speed output */
setting = GPIO_OSPEED_100MHz;
break;
}
}
else
{
setting = 0;
}
regval = getreg32(base + STM32_GPIO_OSPEED_OFFSET);
regval &= ~GPIO_OSPEED_MASK(pos);
regval |= (setting << GPIO_OSPEED_SHIFT(pos));
putreg32(regval, base + STM32_GPIO_OSPEED_OFFSET);
/* Set push-pull/open-drain (Only outputs and alternate function pins) */
regval = getreg32(base + STM32_GPIO_OTYPER_OFFSET);
setting = GPIO_OTYPER_OD(pin);
if ((pinmode == GPIO_MODER_OUTPUT || pinmode == GPIO_MODER_ALT) &&
(cfgset & GPIO_OPENDRAIN) != 0)
{
regval |= setting;
}
else
{
regval &= ~setting;
}
putreg32(regval, base + STM32_GPIO_OTYPER_OFFSET);
/* If it is an input pin, hould it configured as an EXTI interrupt? */
if ((cfgset & GPIO_EXTI) != 0)
{
/* "In STM32 F1 the selection of the EXTI line source is performed through
* the EXTIx bits in the AFIO_EXTICRx registers, while in F2 series this
* selection is done through the EXTIx bits in the SYSCFG_EXTICRx registers.
*
* "Only the mapping of the EXTICRx registers has been changed, without any
* changes to the meaning of the EXTIx bits. However, the range of EXTI
* bits values has been extended to 0b1000 to support the two ports added
* in F2, port H and I (in F1 series the maximum value is 0b0110)."
*/
uint32_t regaddr;
int shift;
/* Set the bits in the SYSCFG EXTICR register */
regaddr = STM32_SYSCFG_EXTICR(pin);
regval = getreg32(regaddr);
shift = SYSCFG_EXTICR_EXTI_SHIFT(pin);
regval &= ~(SYSCFG_EXTICR_PORT_MASK << shift);
regval |= (((uint32_t)port) << shift);
putreg32(regval, regaddr);
}
/* If it is an output... set the pin to the correct initial state. */
else if (pinmode == GPIO_MODER_OUTPUT)
{
bool value = ((cfgset & GPIO_OUTPUT_SET) != 0);
stm32_gpiowrite(cfgset, value);
}
return OK;
}
#endif
/****************************************************************************
* Name: stm32_unconfiggpio
@ -434,7 +611,7 @@ int stm32_unconfiggpio(uint32_t cfgset)
/* To-Do: Mark its unuse for automatic power saving options */
return stm32_gpio_configlock(cfgset, false);
return stm32_configgpio(cfgset);
}
/****************************************************************************

View File

@ -307,7 +307,7 @@ extern "C" {
* .... .... ..O. .... ....
*/
#define GPIO_OPENDRAM (1 << 9) /* Bit9: 1=Open-drain output */
#define GPIO_OPENDRAIN (1 << 9) /* Bit9: 1=Open-drain output */
#define GPIO_PUSHPULL (0) /* Bit9: 0=Push-pull output */
/* If the pin is a GPIO digital output, then this identifies the initial output value.