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/11/07 09:52:57 UTC

[incubator-nuttx] 02/03: arch/arm/stm32/stm32_qencoder: add support for Qenco index pin

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 7b595ab73aa41ecb61919413a50a41005f58b69e
Author: raiden00pl <ra...@railab.me>
AuthorDate: Sat Nov 6 19:13:51 2021 +0100

    arch/arm/stm32/stm32_qencoder: add support for Qenco index pin
---
 arch/arm/src/stm32/Kconfig          |   4 +
 arch/arm/src/stm32/stm32_qencoder.c | 155 +++++++++++++++++++++++++++++++++++-
 arch/arm/src/stm32/stm32_qencoder.h |  19 +++++
 3 files changed, 177 insertions(+), 1 deletion(-)

diff --git a/arch/arm/src/stm32/Kconfig b/arch/arm/src/stm32/Kconfig
index fb022b2..ac9ed10 100644
--- a/arch/arm/src/stm32/Kconfig
+++ b/arch/arm/src/stm32/Kconfig
@@ -11166,6 +11166,10 @@ config STM32_QENCODER_DISABLE_EXTEND16BTIMERS
 	bool "Disable QEncoder timers extension from 16-bit to 32-bit"
 	default n
 
+config STM32_QENCODER_INDEX_PIN
+	bool "Enable QEncoder timers support for index pin"
+	default n
+
 config STM32_TIM1_QE
 	bool "TIM1 QE"
 	default n
diff --git a/arch/arm/src/stm32/stm32_qencoder.c b/arch/arm/src/stm32/stm32_qencoder.c
index 14edc10..ddac56e 100644
--- a/arch/arm/src/stm32/stm32_qencoder.c
+++ b/arch/arm/src/stm32/stm32_qencoder.c
@@ -311,7 +311,12 @@ struct stm32_lowerhalf_s
 
   FAR const struct stm32_qeconfig_s *config; /* static configuration */
 
-  bool             inuse;    /* True: The lower-half driver is in-use */
+  bool             inuse;        /* True: The lower-half driver is in-use */
+#ifdef CONFIG_STM32_QENCODER_INDEX_PIN
+  uint32_t         index_pin;    /* Index pin GPIO */
+  bool             index_use;    /* True: Index pin is configured */
+  int32_t          index_offset; /* Index pin offset */
+#endif
 
 #ifndef CONFIG_STM32_QENCODER_DISABLE_EXTEND16BTIMERS
   volatile int32_t position; /* The current position offset */
@@ -356,6 +361,7 @@ static int stm32_position(FAR struct qe_lowerhalf_s *lower,
                           FAR int32_t *pos);
 static int stm32_setposmax(FAR struct qe_lowerhalf_s *lower, uint32_t pos);
 static int stm32_reset(FAR struct qe_lowerhalf_s *lower);
+static int stm32_setindex(FAR struct qe_lowerhalf_s *lower, uint32_t pos);
 static int stm32_ioctl(FAR struct qe_lowerhalf_s *lower, int cmd,
                        unsigned long arg);
 
@@ -372,6 +378,7 @@ static const struct qe_ops_s g_qecallbacks =
   .position  = stm32_position,
   .setposmax = stm32_setposmax,
   .reset     = stm32_reset,
+  .setindex  = stm32_setindex,
   .ioctl     = stm32_ioctl,
 };
 
@@ -761,6 +768,43 @@ static int stm32_interrupt(int irq, FAR void *context, FAR void *arg)
 }
 #endif
 
+#ifdef CONFIG_STM32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: stm32_qe_index_irq
+ *
+ * Description:
+ *   Common encoder index pin interrupt.
+ *
+ ****************************************************************************/
+
+static int stm32_qe_index_irq(int irq, FAR void *context, FAR void *arg)
+{
+  FAR struct stm32_lowerhalf_s *priv;
+  bool valid = false;
+
+  DEBUGASSERT(arg);
+
+  /* Get QE data */
+
+  priv = (FAR struct stm32_lowerhalf_s *)arg;
+
+  /* Get pin state */
+
+  valid = stm32_gpioread(priv->index_pin);
+
+  /* Only if pin still high to avoid noises */
+
+  if (valid == true)
+    {
+      /* Force postion to index offset */
+
+      stm32_putreg32(priv, STM32_GTIM_CNT_OFFSET, priv->index_offset);
+    }
+
+  return OK;
+}
+#endif
+
 /****************************************************************************
  * Name: stm32_setup
  *
@@ -994,6 +1038,12 @@ static int stm32_setup(FAR struct qe_lowerhalf_s *lower)
     }
 #endif
 
+#ifdef CONFIG_STM32_QENCODER_INDEX_PIN
+  /* At default index pin offset is 0 */
+
+  priv->index_offset = 0;
+#endif
+
   /* Enable the TIM Counter */
 
   cr1 = stm32_getreg16(priv, STM32_GTIM_CR1_OFFSET);
@@ -1243,6 +1293,45 @@ static int stm32_reset(FAR struct qe_lowerhalf_s *lower)
 }
 
 /****************************************************************************
+ * Name: stm32_setindex
+ *
+ * Description:
+ *   Set the index pin postion
+ *
+ ****************************************************************************/
+
+static int stm32_setindex(FAR struct qe_lowerhalf_s *lower, uint32_t pos)
+{
+#ifdef CONFIG_STM32_QENCODER_INDEX_PIN
+  FAR struct stm32_lowerhalf_s *priv = (FAR struct stm32_lowerhalf_s *)lower;
+  int ret = OK;
+
+  sninfo("Set QE TIM%d the index pin positon %" PRIx32 "\n",
+         priv->config->timid, pos);
+  DEBUGASSERT(lower && priv->inuse);
+
+  /* Only if index pin configured */
+
+  if (priv->index_use == false)
+    {
+      snerr("ERROR: QE TIM%d index not registered \n",
+            priv->config->timid);
+      ret = -EPERM;
+      goto errout;
+    }
+
+#ifdef CONFIG_STM32_QENCODER_INDEX_PIN
+  priv->index_offset = pos;
+#endif
+
+errout:
+  return ret;
+#else
+  return -ENOTTY;
+#endif
+}
+
+/****************************************************************************
  * Name: stm32_ioctl
  *
  * Description:
@@ -1324,4 +1413,68 @@ int stm32_qeinitialize(FAR const char *devpath, int tim)
   return OK;
 }
 
+#ifdef CONFIG_STM32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: stm32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int stm32_qe_index_init(int tim, uint32_t gpio)
+{
+  FAR struct stm32_lowerhalf_s *priv;
+  int ret = OK;
+
+  /* Find the pre-allocated timer state structure corresponding to this
+   * timer
+   */
+
+  priv = stm32_tim2lower(tim);
+  if (!priv)
+    {
+      snerr("ERROR: TIM%d support not configured\n", tim);
+      return -ENXIO;
+    }
+
+  /* Make sure that it is available */
+
+  if (priv->inuse == false)
+    {
+      snerr("ERROR: TIM%d is not in-use\n", tim);
+      ret = -EINVAL;
+    }
+
+  /* Configure QE index pin */
+
+  priv->index_pin = gpio;
+  stm32_configgpio(priv->index_pin);
+
+  /* Register interrupt */
+
+  ret = stm32_gpiosetevent(gpio, true, false, true,
+                           stm32_qe_index_irq, priv);
+  if (ret < 0)
+    {
+      snerr("ERROR: QE TIM%d failed register irq \n", tim);
+      goto errout;
+    }
+
+  /* Set flag */
+
+  priv->index_use = true;
+
+errout:
+  return ret;
+}
+#endif
+
 #endif /* CONFIG_SENSORS_QENCODER */
diff --git a/arch/arm/src/stm32/stm32_qencoder.h b/arch/arm/src/stm32/stm32_qencoder.h
index 9426c0d..baed68b 100644
--- a/arch/arm/src/stm32/stm32_qencoder.h
+++ b/arch/arm/src/stm32/stm32_qencoder.h
@@ -124,5 +124,24 @@
 
 int stm32_qeinitialize(FAR const char *devpath, int tim);
 
+#ifdef CONFIG_STM32_QENCODER_INDEX_PIN
+/****************************************************************************
+ * Name: stm32_qe_index_init
+ *
+ * Description:
+ *   Register the encoder index pin to a given Qencoder timer
+ *
+ * Input Parameters:
+ *   tim  - The qenco timer number
+ *   gpio - gpio pin configuration
+ *
+ * Returned Value:
+ *   Zero on success; A negated errno value is returned on failure.
+ *
+ ****************************************************************************/
+
+int stm32_qe_index_init(int tim, uint32_t gpio);
+#endif
+
 #endif /* CONFIG_SENSORS_QENCODER */
 #endif /* __ARCH_ARM_SRC_STM32_STM32_QENCODER_H */