aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
Diffstat (limited to 'os')
-rw-r--r--os/hal/include/hal_qei.h3
-rw-r--r--os/hal/ports/NRF51/NRF51822/hal_qei_lld.c38
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c2
-rw-r--r--os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h67
-rw-r--r--os/hal/src/hal_qei.c48
5 files changed, 114 insertions, 44 deletions
diff --git a/os/hal/include/hal_qei.h b/os/hal/include/hal_qei.h
index 1032c84..ce4a089 100644
--- a/os/hal/include/hal_qei.h
+++ b/os/hal/include/hal_qei.h
@@ -147,8 +147,7 @@ extern "C" {
qeicnt_t qeiGetCount(QEIDriver *qeip);
qeidelta_t qeiUpdate(QEIDriver *qeip);
qeidelta_t qeiUpdateI(QEIDriver *qeip);
- bool qei_adjust_count(qeicnt_t *count, qeidelta_t *delta,
- qeicnt_t min, qeicnt_t max, qeioverflow_t mode);
+ qeidelta_t qeiAdjustI(QEIDriver *qeip, qeidelta_t delta);
#ifdef __cplusplus
}
#endif
diff --git a/os/hal/ports/NRF51/NRF51822/hal_qei_lld.c b/os/hal/ports/NRF51/NRF51822/hal_qei_lld.c
index fbaf3aa..0979551 100644
--- a/os/hal/ports/NRF51/NRF51822/hal_qei_lld.c
+++ b/os/hal/ports/NRF51/NRF51822/hal_qei_lld.c
@@ -85,7 +85,7 @@ static void serve_interrupt(QEIDriver *qeip) {
acc = -acc; // acc is [-1024..+1023], its okay on int16_t
/* Adjust counter */
- qei_lld_adjust_count(qeip, acc);
+ qeiAdjustI(qeip, acc);
}
}
@@ -266,42 +266,6 @@ void qei_lld_disable(QEIDriver *qeip) {
qeip->qdec->TASKS_STOP = 1;
}
-/**
- * @brief Adjust counter
- *
- * @param[in] qeip pointer to the @p QEIDriver object
- * @param[in] delta value to use for adjustement
- * @return remaining adjustement that were not applied
- *
- * @notapi
- */
-qeidelta_t qei_lld_adjust_count(QEIDriver *qeip, qeidelta_t delta) {
- /* Get boundaries */
- qeicnt_t min = QEI_COUNT_MIN;
- qeicnt_t max = QEI_COUNT_MAX;
- if (qeip->config->min != qeip->config->max) {
- min = qeip->config->min;
- max = qeip->config->max;
- }
-
- /* Snapshot counter for later comparison */
- qeicnt_t count = qeip->count;
-
- /* Adjust counter value */
- bool overflowed = qei_adjust_count(&qeip->count, &delta,
- min, max, qeip->config->overflow);
-
- /* Notify for value change */
- if ((qeip->count != count) && qeip->config->notify_cb)
- qeip->config->notify_cb(qeip);
-
- /* Notify for overflow (passing the remaining delta) */
- if (overflowed && qeip->config->overflow_cb)
- qeip->config->overflow_cb(qeip, delta);
-
- /* Remaining delta */
- return delta;
-}
#endif /* HAL_USE_QEI */
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
index ea051f7..ffc4992 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c
@@ -150,6 +150,8 @@ void qei_lld_init(void) {
* @notapi
*/
void qei_lld_start(QEIDriver *qeip) {
+ osalDbgAssert((qeip->config->min == 0) || (qeip->config->max == 0),
+ "only min/max set to 0 is supported");
if (qeip->state == QEI_STOP) {
/* Clock activation and timer reset.*/
diff --git a/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h
index d0cb683..c708b5e 100644
--- a/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h
+++ b/os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h
@@ -33,6 +33,16 @@
/* Driver constants. */
/*===========================================================================*/
+/**
+ * @brief Mininum usable value for defining counter underflow
+ */
+#define QEI_COUNT_MIN (0)
+
+/**
+ * @brief Maximum usable value for defining counter overflow
+ */
+#define QEI_COUNT_MAX (65535)
+
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
@@ -202,6 +212,14 @@
#error "Invalid IRQ priority assigned to TIM8"
#endif
+#if QEI_USE_OVERFLOW_DISCARD
+#error "QEI_USE_OVERFLOW_DISCARD not supported by this driver"
+#endif
+
+#if QEI_USE_OVERFLOW_MINMAX
+#error "QEI_USE_OVERFLOW_MINMAX not supported by this driver"
+#endif
+
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
@@ -257,6 +275,45 @@ typedef struct {
* @brief Direction inversion.
*/
qeidirinv_t dirinv;
+ /**
+ * @brief Handling of counter overflow/underflow
+ *
+ * @details When overflow occurs, the counter value is updated
+ * according to:
+ * - QEI_OVERFLOW_DISCARD:
+ * discard the update value, counter doesn't change
+ */
+ qeioverflow_t overflow;
+ /**
+ * @brief Min count value.
+ *
+ * @note If min == max, then QEI_COUNT_MIN is used.
+ *
+ * @note Only min set to 0 / QEI_COUNT_MIN is supported.
+ */
+ qeicnt_t min;
+ /**
+ * @brief Max count value.
+ *
+ * @note If min == max, then QEI_COUNT_MAX is used.
+ *
+ * @note Only max set to 0 / QEI_COUNT_MAX is supported.
+ */
+ qeicnt_t max;
+ /**
+ * @brief Notify of value change
+ *
+ * @note Called from ISR context.
+ */
+ qeicallback_t notify_cb;
+ /**
+ * @brief Notify of overflow
+ *
+ * @note Overflow notification is performed after
+ * value changed notification.
+ * @note Called from ISR context.
+ */
+ void (*overflow_cb)(QEIDriver *qeip, qeidelta_t delta);
/* End of the mandatory fields.*/
} QEIConfig;
@@ -300,6 +357,16 @@ struct QEIDriver {
*/
#define qei_lld_get_count(qeip) ((qeip)->tim->CNT)
+/**
+ * @brief Set the counter value.
+ *
+ * @param[in] qeip pointer to the @p QEIDriver object
+ * @param[in] qeip counter value
+ *
+ * @notapi
+ */
+#define qei_lld_set_count(qeip, value)
+
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
diff --git a/os/hal/src/hal_qei.c b/os/hal/src/hal_qei.c
index abecdf8..eb6223e 100644
--- a/os/hal/src/hal_qei.c
+++ b/os/hal/src/hal_qei.c
@@ -42,10 +42,6 @@
/* Driver local functions. */
/*===========================================================================*/
-/*===========================================================================*/
-/* Driver exported functions. */
-/*===========================================================================*/
-
/**
* @brief Helper for correclty handling overflow/underflow
*
@@ -66,6 +62,7 @@
* was due to occur
*
*/
+static inline
bool qei_adjust_count(qeicnt_t *count, qeidelta_t *delta,
qeicnt_t min, qeicnt_t max, qeioverflow_t mode) {
/* For information on signed integer overflow see:
@@ -131,6 +128,10 @@ bool qei_adjust_count(qeicnt_t *count, qeidelta_t *delta,
}
}
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
/**
* @brief QEI Driver initialization.
* @note This function is implicitly invoked by @p halInit(), there is
@@ -284,13 +285,50 @@ qeidelta_t qeiAdjust(QEIDriver *qeip, qeidelta_t delta) {
osalDbgAssert((qeip->state == QEI_ACTIVE), "invalid state");
osalSysLock();
- delta = qei_lld_adjust_count(qeip, delta);
+ delta = qeiAdjustI(qeip, delta);
osalSysUnlock();
return delta;
}
/**
+ * @brief Adjust the counter by delta.
+ *
+ * @param[in] qeip pointer to the @p QEIDriver object.
+ * @param[in] delta the adjustement value.
+ * @return the remaining delta (can occur during overflow).
+ *
+ * @api
+ */
+qeidelta_t qeiAdjustI(QEIDriver *qeip, qeidelta_t delta) {
+ /* Get boundaries */
+ qeicnt_t min = QEI_COUNT_MIN;
+ qeicnt_t max = QEI_COUNT_MAX;
+ if (qeip->config->min != qeip->config->max) {
+ min = qeip->config->min;
+ max = qeip->config->max;
+ }
+
+ /* Get counter */
+ qeicnt_t count = qei_lld_get_count(qeip);
+
+ /* Adjust counter value */
+ bool overflowed = qei_adjust_count(&count, &delta,
+ min, max, qeip->config->overflow);
+
+ /* Notify for value change */
+ qei_lld_set_count(qeip, count);
+
+ /* Notify for overflow (passing the remaining delta) */
+ if (overflowed && qeip->config->overflow_cb)
+ qeip->config->overflow_cb(qeip, delta);
+
+ /* Remaining delta */
+ return delta;
+}
+
+
+/**
* @brief Returns the counter delta from last reading.
*
* @param[in] qeip pointer to the @p QEIDriver object