diff --git a/arch/arm/src/stm32/chip/stm32_syscfg.h b/arch/arm/src/stm32/chip/stm32_syscfg.h index 792a719db1f..f1788beeb8c 100644 --- a/arch/arm/src/stm32/chip/stm32_syscfg.h +++ b/arch/arm/src/stm32/chip/stm32_syscfg.h @@ -51,91 +51,101 @@ /* Register Offsets *********************************************************************************/ -#define STM32_SYSCFG_MEMRMP_OFFSET 0x0000 /* SYSCFG memory remap register */ -#define STM32_SYSCFG_PMC_OFFSET 0x0004 /* SYSCFG peripheral mode configuration register */ -#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 */ +#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_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) +#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 ********************************************************************/ /* SYSCFG memory remap register */ -#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_SHIFT (0) /* Bits 1:0 MEM_MODE: Memory mapping selection */ +#define SYSCFG_MEMRMP_MASK (3 << SYSCFG_MEMRMP_SHIFT) +# 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 */ -#define SYSCFG_PMC_MII_RMII_SEL (1 << 23) /* Bit 23: Ethernet PHY interface selection */ +#define SYSCFG_PMC_MII_RMII_SEL (1 << 23) /* Bit 23: Ethernet PHY interface selection */ /* SYSCFG external interrupt configuration register 1-4 */ -#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ -#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */ -#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */ -#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */ -#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */ -#define SYSCFG_EXTICR_PORTF (5) /* 0101: PF[C] pin */ -#define SYSCFG_EXTICR_PORTG (6) /* 0110: PG[x] pin */ -#define SYSCFG_EXTICR_PORTH (7) /* 0111: PH[x] pin */ -#define SYSCFG_EXTICR_PORTI (8) /* 1000: PI[x] pin */ +#define SYSCFG_EXTICR_PORTA (0) /* 0000: PA[x] pin */ +#define SYSCFG_EXTICR_PORTB (1) /* 0001: PB[x] pin */ +#define SYSCFG_EXTICR_PORTC (2) /* 0010: PC[x] pin */ +#define SYSCFG_EXTICR_PORTD (3) /* 0011: PD[x] pin */ +#define SYSCFG_EXTICR_PORTE (4) /* 0100: PE[x] pin */ +#define SYSCFG_EXTICR_PORTF (5) /* 0101: PF[C] pin */ +#define SYSCFG_EXTICR_PORTG (6) /* 0110: PG[x] pin */ +#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 */ -#define SYSCFG_CMPCR_CMPPD (1 << 0) /* Bit 0: Compensation cell power-down */ -#define SYSCFG_CMPCR_READY (1 << 8) /* Bit 8: Compensation cell ready flag */ +#define SYSCFG_CMPCR_CMPPD (1 << 0) /* Bit 0: Compensation cell power-down */ +#define SYSCFG_CMPCR_READY (1 << 8) /* Bit 8: Compensation cell ready flag */ #endif /* CONFIG_STM32_STM32F40XX */ #endif /* __ARCH_ARM_SRC_STM32_CHIP_STM32_SYSCFG_H */ diff --git a/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h b/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h index 4a171af21cc..effe8a8b546 100644 --- a/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h +++ b/arch/arm/src/stm32/chip/stm32f10xxx_gpio.h @@ -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 */ diff --git a/arch/arm/src/stm32/stm32_gpio.c b/arch/arm/src/stm32/stm32_gpio.c index 75a893beecc..7c59f4a0949 100644 --- a/arch/arm/src/stm32/stm32_gpio.c +++ b/arch/arm/src/stm32/stm32_gpio.c @@ -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); } /**************************************************************************** diff --git a/arch/arm/src/stm32/stm32_gpio.h b/arch/arm/src/stm32/stm32_gpio.h index 19e0adbe0d4..ecd96863b1e 100644 --- a/arch/arm/src/stm32/stm32_gpio.h +++ b/arch/arm/src/stm32/stm32_gpio.h @@ -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.