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 */