This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
commit 5e19ebb818056f3433f7501a819673b85c9c6ea8 Author: David Sidrane <david.sidr...@nscdg.com> AuthorDate: Fri Sep 17 06:35:00 2021 -0700 stm32F7:Etablish device before enabling outputs This prevents gliches on changing to an output mode. If not the ALT mux can be selecting a IP block that is drving the line to say 0. Then the output is connected to that source, then swithced to the correct source. --- arch/arm/src/stm32f7/stm32_gpio.c | 83 +++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 25 deletions(-) diff --git a/arch/arm/src/stm32f7/stm32_gpio.c b/arch/arm/src/stm32f7/stm32_gpio.c index a3b1a01..162776b 100644 --- a/arch/arm/src/stm32f7/stm32_gpio.c +++ b/arch/arm/src/stm32f7/stm32_gpio.c @@ -114,6 +114,7 @@ int stm32_configgpio(uint32_t cfgset) uintptr_t base; uint32_t regval; uint32_t setting; + uint32_t alt_setting; unsigned int regoffset; unsigned int port; unsigned int pin; @@ -171,6 +172,41 @@ int stm32_configgpio(uint32_t cfgset) flags = enter_critical_section(); + /* Determine the alternate function (Only alternate function pins) */ + + if (pinmode == GPIO_MODER_ALT) + { + alt_setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT; + } + else + { + alt_setting = 0; + } + + /* Set the alternate function (Only alternate function pins) + * This is done before configuring the Outputs on a change to + * an Alternate function. + */ + + if (alt_setting != 0) + { + if (pin < 8) + { + regoffset = STM32_GPIO_AFRL_OFFSET; + pos = pin; + } + else + { + regoffset = STM32_GPIO_AFRH_OFFSET; + pos = pin - 8; + } + + regval = getreg32(base + regoffset); + regval &= ~GPIO_AFR_MASK(pos); + regval |= (alt_setting << GPIO_AFR_SHIFT(pos)); + putreg32(regval, base + regoffset); + } + /* Now apply the configuration to the mode register */ regval = getreg32(base + STM32_GPIO_MODER_OFFSET); @@ -204,32 +240,29 @@ int stm32_configgpio(uint32_t cfgset) 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_AFRH_OFFSET; - pos = pin - 8; - } + /* Set the alternate function (Only alternate function pins) + * This is done after configuring the the pin's connection + * on a change away from an Alternate function. + */ - regval = getreg32(base + regoffset); - regval &= ~GPIO_AFR_MASK(pos); - regval |= (setting << GPIO_AFR_SHIFT(pos)); - putreg32(regval, base + regoffset); + if (alt_setting == 0) + { + if (pin < 8) + { + regoffset = STM32_GPIO_AFRL_OFFSET; + pos = pin; + } + else + { + regoffset = STM32_GPIO_AFRH_OFFSET; + pos = pin - 8; + } + + regval = getreg32(base + regoffset); + regval &= ~GPIO_AFR_MASK(pos); + regval |= (alt_setting << GPIO_AFR_SHIFT(pos)); + putreg32(regval, base + regoffset); + } /* Set speed (Only outputs and alternate function pins) */