diff options
Diffstat (limited to 'os')
| -rw-r--r-- | os/hal/include/hal_qei.h | 3 | ||||
| -rw-r--r-- | os/hal/ports/NRF51/NRF51822/hal_qei_lld.c | 38 | ||||
| -rw-r--r-- | os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.c | 2 | ||||
| -rw-r--r-- | os/hal/ports/STM32/LLD/TIMv1/hal_qei_lld.h | 67 | ||||
| -rw-r--r-- | os/hal/src/hal_qei.c | 48 | 
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
 | 
