You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2021/09/22 01:25:23 UTC
[incubator-nuttx] 01/04: stm32:Etablish device before enabling
outputs
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 d5e306e6f300cda9984bf03222a8ff36134b3213
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Thu Sep 16 10:43:59 2021 -0700
stm32: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. This
produced a 430 nS glich on a F4 @168 Mhz. It was a enough
to corrupt an I2C device with a bus monitor.
---
arch/arm/src/stm32/stm32_gpio.c | 83 ++++++++++++++++++++++++++++-------------
1 file changed, 58 insertions(+), 25 deletions(-)
diff --git a/arch/arm/src/stm32/stm32_gpio.c b/arch/arm/src/stm32/stm32_gpio.c
index 3e59649..c5bc424 100644
--- a/arch/arm/src/stm32/stm32_gpio.c
+++ b/arch/arm/src/stm32/stm32_gpio.c
@@ -406,6 +406,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;
@@ -463,6 +464,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);
@@ -496,32 +532,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) */