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:25 UTC

[incubator-nuttx] 03/04: stm32H7: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 a8d5f21f8196c56c661adcbb7767cfa2a892fa5f
Author: David Sidrane <Da...@NscDg.com>
AuthorDate: Fri Sep 17 06:35:49 2021 -0700

    stm32H7: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/stm32h7/stm32_gpio.c | 92 ++++++++++++++++++++++++++++-----------
 1 file changed, 67 insertions(+), 25 deletions(-)

diff --git a/arch/arm/src/stm32h7/stm32_gpio.c b/arch/arm/src/stm32h7/stm32_gpio.c
index f2da8fd..cf5180a 100644
--- a/arch/arm/src/stm32h7/stm32_gpio.c
+++ b/arch/arm/src/stm32h7/stm32_gpio.c
@@ -140,6 +140,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;
@@ -201,6 +202,50 @@ int stm32_configgpio(uint32_t cfgset)
 
   flags = enter_critical_section();
 
+  /* Determine the alternate function (Only alternate function pins) */
+
+  if (pinmode == GPIO_MODER_ALT)
+    {
+      setting = (cfgset & GPIO_AF_MASK) >> GPIO_AF_SHIFT;
+    }
+  else
+    {
+      setting = 0;
+    }
+
+  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);
@@ -234,32 +279,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) */