counter: Update counter API in order to provide more flexibility
This commit introduces new top_value setting configuration structure with flag for controlling resetting of the counter during change of top value. Such change allows for #12068 implementation on hardware which does not provide alarms. Signed-off-by: Piotr Zięcik <piotr.ziecik@nordicsemi.no> Signed-off-by: Krzysztof Chruscinski <krzysztof.chruscinski@nordicsemi.no> Signed-off-by: Benjamin Valentin <benjamin.valentin@ml-pa.com>
This commit is contained in:
parent
3c6c8ed063
commit
69406e0f9c
14 changed files with 248 additions and 125 deletions
|
@ -39,6 +39,28 @@ extern "C" {
|
|||
|
||||
/**@} */
|
||||
|
||||
/**@defgroup COUNTER_TOP_FLAGS Flags used by @ref counter_top_cfg.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Flag preventing counter reset when top value is changed.
|
||||
*
|
||||
* If flags is set then counter is free running while top value is updated,
|
||||
* otherwise counter is reset (see @ref counter_set_top_value()).
|
||||
*/
|
||||
#define COUNTER_TOP_CFG_DONT_RESET BIT(0)
|
||||
|
||||
/**
|
||||
* @brief Flag instructing counter to reset itself if changing top value
|
||||
* results in counter going out of new top value bound.
|
||||
*
|
||||
* See @ref COUNTER_TOP_CFG_DONT_RESET.
|
||||
*/
|
||||
#define COUNTER_TOP_CFG_RESET_WHEN_LATE BIT(1)
|
||||
|
||||
/**@} */
|
||||
|
||||
/** @brief Alarm callback
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance.
|
||||
|
@ -80,6 +102,21 @@ struct counter_alarm_cfg {
|
|||
*/
|
||||
typedef void (*counter_top_callback_t)(struct device *dev, void *user_data);
|
||||
|
||||
/** @brief Top value configuration structure.
|
||||
*
|
||||
* @param ticks Top value.
|
||||
* @param callback Callback function. Can be NULL.
|
||||
* @param user_data User data passed to callback function. Not valid if
|
||||
* callback is NULL.
|
||||
* @param flags Flags. See @ref COUNTER_TOP_FLAGS.
|
||||
*/
|
||||
struct counter_top_cfg {
|
||||
u32_t ticks;
|
||||
counter_top_callback_t callback;
|
||||
void *user_data;
|
||||
u32_t flags;
|
||||
};
|
||||
|
||||
/** @brief Structure with generic counter features.
|
||||
*
|
||||
* @param max_top_value Maximal (default) top value on which counter is reset
|
||||
|
@ -103,9 +140,8 @@ typedef u32_t (*counter_api_read)(struct device *dev);
|
|||
typedef int (*counter_api_set_alarm)(struct device *dev, u8_t chan_id,
|
||||
const struct counter_alarm_cfg *alarm_cfg);
|
||||
typedef int (*counter_api_cancel_alarm)(struct device *dev, u8_t chan_id);
|
||||
typedef int (*counter_api_set_top_value)(struct device *dev, u32_t ticks,
|
||||
counter_top_callback_t callback,
|
||||
void *user_data);
|
||||
typedef int (*counter_api_set_top_value)(struct device *dev,
|
||||
const struct counter_top_cfg *cfg);
|
||||
typedef u32_t (*counter_api_get_pending_int)(struct device *dev);
|
||||
typedef u32_t (*counter_api_get_top_value)(struct device *dev);
|
||||
typedef u32_t (*counter_api_get_max_relative_alarm)(struct device *dev);
|
||||
|
@ -332,34 +368,38 @@ static inline int counter_cancel_channel_alarm(struct device *dev,
|
|||
/**
|
||||
* @brief Set counter top value.
|
||||
*
|
||||
* Function sets top value and resets the counter to 0 or top value
|
||||
* depending on counter direction. On turnaround, counter is reset and optional
|
||||
* callback is periodically called. Top value can only be changed when there
|
||||
* is no active channel alarm.
|
||||
* Function sets top value and optionally resets the counter to 0 or top value
|
||||
* depending on counter direction. On turnaround, counter can be reset and
|
||||
* optional callback is periodically called. Top value can only be changed when
|
||||
* there is no active channel alarm.
|
||||
*
|
||||
* @ref COUNTER_TOP_CFG_DONT_RESET prevents counter reset. When counter is
|
||||
* running while top value is updated, it is possible that counter progresses
|
||||
* outside the new top value. In that case, error is returned and optionally
|
||||
* driver can reset the counter (see @ref COUNTER_TOP_CFG_RESET_WHEN_LATE).
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance.
|
||||
* @param ticks Top value.
|
||||
* @param callback Callback function. Can be NULL.
|
||||
* @param user_data User data passed to callback function. Not valid if
|
||||
* callback is NULL.
|
||||
* @param cfg Configuration. Cannot be NULL.
|
||||
*
|
||||
* @retval 0 If successful.
|
||||
* @retval -ENOTSUP if request is not supported (e.g. top value cannot be
|
||||
* changed).
|
||||
* changed or counter cannot/must be reset during top value
|
||||
update).
|
||||
* @retval -EBUSY if any alarm is active.
|
||||
* @retval -ETIME if @ref COUNTER_TOP_CFG_DONT_RESET was set and new top value
|
||||
* is smaller than current counter value (counter counting up).
|
||||
*/
|
||||
static inline int counter_set_top_value(struct device *dev, u32_t ticks,
|
||||
counter_top_callback_t callback,
|
||||
void *user_data)
|
||||
static inline int counter_set_top_value(struct device *dev,
|
||||
const struct counter_top_cfg *cfg)
|
||||
{
|
||||
const struct counter_driver_api *api =
|
||||
(struct counter_driver_api *)dev->driver_api;
|
||||
|
||||
if (ticks > counter_get_max_top_value(dev)) {
|
||||
if (cfg->ticks > counter_get_max_top_value(dev)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return api->set_top_value(dev, ticks, callback, user_data);
|
||||
return api->set_top_value(dev, cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -430,7 +470,14 @@ __deprecated static inline int counter_set_alarm(struct device *dev,
|
|||
counter_callback_t callback,
|
||||
u32_t count, void *user_data)
|
||||
{
|
||||
return counter_set_top_value(dev, count, callback, user_data);
|
||||
struct counter_top_cfg cfg = {
|
||||
.ticks = count,
|
||||
.callback = callback,
|
||||
.user_data = user_data,
|
||||
.flags = 0
|
||||
};
|
||||
|
||||
return counter_set_top_value(dev, &cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue