From f75abd1037a5c2eb119533eb2f4c7c16d874abf2 Mon Sep 17 00:00:00 2001 From: Stephane D'Alu Date: Thu, 7 Jul 2016 21:25:51 +0200 Subject: added qeiAdjustI. added new field and checking in STM32 --- os/hal/include/hal_qei.h | 3 +- os/hal/ports/NRF51/NRF51822/hal_qei_lld.c | 38 +------------- os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c | 2 + os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h | 67 +++++++++++++++++++++++++ os/hal/src/hal_qei.c | 48 ++++++++++++++++-- testhal/STM32/STM32F0xx/qei/Makefile | 2 +- testhal/STM32/STM32F0xx/qei/halconf_community.h | 18 +++++++ 7 files changed, 133 insertions(+), 45 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,12 +285,49 @@ 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. * diff --git a/testhal/STM32/STM32F0xx/qei/Makefile b/testhal/STM32/STM32F0xx/qei/Makefile index 6dbcf91..6f2e54c 100644 --- a/testhal/STM32/STM32F0xx/qei/Makefile +++ b/testhal/STM32/STM32F0xx/qei/Makefile @@ -86,7 +86,7 @@ endif PROJECT = ch # Imported source files and paths -CHIBIOS = ../../../../../ChibiOS-RT +CHIBIOS = ../../../../../ChibiOS CHIBIOS_CONTRIB = $(CHIBIOS)/../ChibiOS-Contrib # Startup files. include $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_stm32f0xx.mk diff --git a/testhal/STM32/STM32F0xx/qei/halconf_community.h b/testhal/STM32/STM32F0xx/qei/halconf_community.h index 9c28ead..95f1ee6 100644 --- a/testhal/STM32/STM32F0xx/qei/halconf_community.h +++ b/testhal/STM32/STM32F0xx/qei/halconf_community.h @@ -100,6 +100,24 @@ */ #define ONEWIRE_USE_SEARCH_ROM FALSE +/*===========================================================================*/ +/* QEI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables discard of overlow + */ +#if !defined(QEI_USE_OVERFLOW_DISCARD) || defined(__DOXYGEN__) +#define QEI_USE_OVERFLOW_DISCARD FALSE +#endif + +/** + * @brief Enables min max of overlow + */ +#if !defined(QEI_USE_OVERFLOW_MINMAX) || defined(__DOXYGEN__) +#define QEI_USE_OVERFLOW_MINMAX FALSE +#endif + #endif /* HALCONF_COMMUNITY_H */ /** @} */ -- cgit v1.2.3