Skip to content

Commit

Permalink
counter: Update counter API in order to provide more flexibility
Browse files Browse the repository at this point in the history
This commit introduces new "reset" parameter to the set_top_value()
making resetting counter optional during change of top value.

Such change allows for zephyrproject-rtos#12068 implementation on hardware which
does not provide alarms.

Signed-off-by: Piotr Zięcik <[email protected]>
Signed-off-by: Krzysztof Chruscinski <[email protected]>
  • Loading branch information
pizi-nordic committed May 30, 2019
1 parent e523c73 commit d8232f6
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 105 deletions.
18 changes: 9 additions & 9 deletions drivers/counter/counter_imx_epit.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,24 @@ static u32_t imx_epit_read(struct device *dev)
return value;
}

static int imx_epit_set_top_value(struct device *dev, u32_t ticks,
counter_top_callback_t callback,
void *user_data)
static int imx_epit_set_top_value(struct device *dev,
const struct counter_top_cfg *cfg)
{
EPIT_Type *base = get_epit_config(dev)->base;
struct imx_epit_data *driver_data = dev->driver_data;

/* Disable EPIT Output Compare interrupt for consistency */
EPIT_SetIntCmd(base, false);

driver_data->callback = callback;
driver_data->user_data = user_data;
driver_data->callback = cfg->callback;
driver_data->user_data = cfg->user_data;

/* Set both reload and counter values to "ticks" */
EPIT_SetOverwriteCounter(base, true);
EPIT_SetCounterLoadValue(base, ticks);
/* Set reload value and optionally counter to "ticks" */
EPIT_SetOverwriteCounter(base,
!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET));
EPIT_SetCounterLoadValue(base, cfg->ticks);

if (callback != NULL) {
if (cfg->callback != NULL) {
/* (Re)enable EPIT Output Compare interrupt */
EPIT_SetIntCmd(base, true);
}
Expand Down
12 changes: 4 additions & 8 deletions drivers/counter/counter_ll_stm32_rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,17 +197,13 @@ static u32_t rtc_stm32_get_top_value(struct device *dev)
}


static int rtc_stm32_set_top_value(struct device *dev, u32_t ticks,
counter_top_callback_t callback,
void *user_data)
static int rtc_stm32_set_top_value(struct device *dev,
const struct counter_top_cfg *cfg)
{
const struct counter_config_info *info = dev->config->config_info;

ARG_UNUSED(dev);
ARG_UNUSED(callback);
ARG_UNUSED(user_data);

if (ticks != info->max_top_value) {
if ((cfg->ticks != info->max_top_value) ||
!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
return -ENOTSUP;
} else {
return 0;
Expand Down
15 changes: 8 additions & 7 deletions drivers/counter/counter_mcux_rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,20 +133,21 @@ static int mcux_rtc_cancel_alarm(struct device *dev, u8_t chan_id)
return 0;
}

static int mcux_rtc_set_top_value(struct device *dev, u32_t ticks,
counter_top_callback_t callback,
void *user_data)
static int mcux_rtc_set_top_value(struct device *dev,
const struct counter_top_cfg *cfg)
{
const struct counter_config_info *info = dev->config->config_info;
struct mcux_rtc_data *data = dev->driver_data;

if (ticks != info->max_top_value) {
LOG_ERR("Wrap can only be set to 0x%x", info->max_top_value);
if ((cfg->ticks != info->max_top_value) ||
!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
LOG_ERR("Wrap can only be set to 0x%x. "
"Counter reset is not supported.", info->max_top_value);
return -ENOTSUP;
}

data->top_callback = callback;
data->top_user_data = user_data;
data->top_callback = cfg->callback;
data->top_user_data = cfg->user_data;

return 0;
}
Expand Down
17 changes: 9 additions & 8 deletions drivers/counter/counter_nrfx_rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,9 +137,8 @@ static int counter_nrfx_cancel_alarm(struct device *dev, u8_t chan_id)
return 0;
}

static int counter_nrfx_set_top_value(struct device *dev, u32_t ticks,
counter_top_callback_t callback,
void *user_data)
static int counter_nrfx_set_top_value(struct device *dev,
const struct counter_top_cfg *cfg)
{
const struct counter_nrfx_config *nrfx_config = get_nrfx_config(dev);
const nrfx_rtc_t *rtc = &nrfx_config->rtc;
Expand All @@ -155,12 +154,14 @@ static int counter_nrfx_set_top_value(struct device *dev, u32_t ticks,
}

nrfx_rtc_cc_disable(rtc, TOP_CH);
nrfx_rtc_counter_clear(rtc);
if (!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
nrfx_rtc_counter_clear(rtc);
}

dev_data->top_cb = callback;
dev_data->top_user_data = user_data;
dev_data->top = ticks;
nrfx_rtc_cc_set(rtc, TOP_CH, ticks, callback ? true : false);
dev_data->top_cb = cfg->callback;
dev_data->top_user_data = cfg->user_data;
dev_data->top = cfg->ticks;
nrfx_rtc_cc_set(rtc, TOP_CH, cfg->ticks, cfg->callback ? true : false);

return 0;
}
Expand Down
17 changes: 9 additions & 8 deletions drivers/counter/counter_nrfx_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,8 @@ static int counter_nrfx_cancel_alarm(struct device *dev, u8_t chan_id)
}


static int counter_nrfx_set_top_value(struct device *dev, u32_t ticks,
counter_top_callback_t callback,
void *user_data)
static int counter_nrfx_set_top_value(struct device *dev,
const struct counter_top_cfg *cfg)
{
const struct counter_nrfx_config *nrfx_config = get_nrfx_config(dev);
const nrfx_timer_t *timer = &nrfx_config->timer;
Expand All @@ -174,13 +173,15 @@ static int counter_nrfx_set_top_value(struct device *dev, u32_t ticks,
}

nrfx_timer_compare_int_disable(timer, TOP_CH);
nrfx_timer_clear(timer);
if (!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
nrfx_timer_clear(timer);
}

data->top_cb = callback;
data->top_user_data = user_data;
data->top_cb = cfg->callback;
data->top_user_data = cfg->user_data;
nrfx_timer_extended_compare(timer, TOP_CH,
ticks, COUNTER_OVERFLOW_SHORT,
callback ? true : false);
cfg->ticks, COUNTER_OVERFLOW_SHORT,
cfg->callback ? true : false);

return 0;
}
Expand Down
4 changes: 1 addition & 3 deletions drivers/counter/counter_qmsi_aon.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,7 @@ static u32_t aon_counter_qmsi_read(struct device *dev)
}

static int aon_counter_qmsi_set_top(struct device *dev,
u32_t ticks,
counter_top_callback_t callback,
void *user_data)
const struct counter_top_cfg *cfg)

{
return -ENODEV;
Expand Down
15 changes: 9 additions & 6 deletions drivers/counter/counter_qmsi_aonpt.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,19 +113,22 @@ static u32_t aon_timer_qmsi_read(struct device *dev)
}

static int aon_timer_qmsi_set_top(struct device *dev,
u32_t ticks,
counter_top_callback_t callback,
void *user_data)
const struct counter_top_cfg *cfg)
{
qm_aonpt_config_t qmsi_cfg;
int result = 0;

user_cb = callback;
/* Counter is always reset when top value is updated. */
if (cfg->flags & COUNTER_TOP_CFG_DONT_RESET) {
return -ENOTSUP;
}

user_cb = cfg->callback;

qmsi_cfg.callback = aonpt_int_callback;
qmsi_cfg.int_en = true;
qmsi_cfg.count = ticks;
qmsi_cfg.callback_data = user_data;
qmsi_cfg.count = cfg->ticks;
qmsi_cfg.callback_data = cfg->user_data;

if (IS_ENABLED(CONFIG_AON_API_REENTRANCY)) {
k_sem_take(RP_GET(dev), K_FOREVER);
Expand Down
12 changes: 4 additions & 8 deletions drivers/counter/counter_rtc_qmsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,13 @@ static int rtc_qmsi_cancel_alarm(struct device *dev, u8_t chan_id)
return 0;
}

static int rtc_qmsi_set_top(struct device *dev, u32_t ticks,
counter_top_callback_t callback,
void *user_data)
static int rtc_qmsi_set_top(struct device *dev,
const struct counter_top_cfg *cfg)
{
const struct counter_config_info *info = dev->config->config_info;

ARG_UNUSED(dev);
ARG_UNUSED(callback);
ARG_UNUSED(user_data);

if (ticks != info->max_top_value) {
if ((cfg->ticks != info->max_top_value) ||
!(cfg->flags & COUNTER_TOP_CFG_DONT_RESET)) {
return -ENOTSUP;
} else {
return 0;
Expand Down
19 changes: 11 additions & 8 deletions drivers/counter/counter_sam0_tc32.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,30 +226,33 @@ static int counter_sam0_tc32_cancel_alarm(struct device *dev, u8_t chan_id)
return 0;
}

static int counter_sam0_tc32_set_top_value(struct device *dev, u32_t ticks,
counter_top_callback_t callback,
void *user_data)
static int counter_sam0_tc32_set_top_value(struct device *dev,
const struct counter_top_cfg *top_cfg)
{
bool reset = true;
struct counter_sam0_tc32_data *data = DEV_DATA(dev);
const struct counter_sam0_tc32_config *const cfg = DEV_CFG(dev);
TcCount32 *tc = cfg->regs;
int key = irq_lock();

if (top_cfg->flags & COUNTER_TOP_CFG_DONT_RESET) {
return -ENOTSUP;
}

if (data->ch.callback) {
irq_unlock(key);
return -EBUSY;
}

if (callback) {
data->top_cb = callback;
data->top_user_data = user_data;
if (top_cfg->callback) {
data->top_cb = top_cfg->callback;
data->top_user_data = top_cfg->user_data;
tc->INTENSET.reg = TC_INTFLAG_MC0;
} else {
tc->INTENCLR.reg = TC_INTFLAG_MC0;
}

tc->CC[0].reg = ticks;
tc->CC[0].reg = top_cfg->ticks;

if (reset) {
tc->CTRLBSET.reg = TC_CTRLBSET_CMD_RETRIGGER;
Expand All @@ -258,7 +261,7 @@ static int counter_sam0_tc32_set_top_value(struct device *dev, u32_t ticks,
* Top trigger is on equality of the rising edge only, so
* manually reset it if the counter has missed the new top.
*/
if (counter_sam0_tc32_read(dev) >= ticks) {
if (counter_sam0_tc32_read(dev) >= top_cfg->ticks) {
tc->CTRLBSET.reg = TC_CTRLBSET_CMD_RETRIGGER;
}
}
Expand Down
24 changes: 17 additions & 7 deletions drivers/counter/timer_dtmr_cmsdk_apb.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,22 +69,32 @@ static u32_t dtmr_cmsdk_apb_read(struct device *dev)
}

static int dtmr_cmsdk_apb_set_top_value(struct device *dev,
u32_t ticks,
counter_top_callback_t callback,
void *user_data)
const struct counter_top_cfg *top_cfg)
{
const struct dtmr_cmsdk_apb_cfg * const cfg =
dev->config->config_info;
struct dtmr_cmsdk_apb_dev_data *data = dev->driver_data;

data->top_callback = callback;
data->top_user_data = user_data;
data->top_callback = top_cfg->callback;
data->top_user_data = top_cfg->user_data;

/* Store the reload value */
data->load = ticks;
data->load = top_cfg->ticks;

/* Set the timer to count */
cfg->dtimer->timer1load = ticks;
if (top_cfg->flags & COUNTER_TOP_CFG_DONT_RESET) {
/*
* Write to background load register will not affect
* the current value of the counter.
*/
cfg->dtimer->timer1bgload = top_cfg->ticks;
} else {
/*
* Write to load register will also set
* the current value of the counter.
*/
cfg->dtimer->timer1load = top_cfg->ticks;
}

/* Enable IRQ */
cfg->dtimer->timer1ctrl |= (DUALTIMER_CTRL_INTEN
Expand Down
19 changes: 11 additions & 8 deletions drivers/counter/timer_tmr_cmsdk_apb.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,25 +69,28 @@ static u32_t tmr_cmsdk_apb_read(struct device *dev)
}

static int tmr_cmsdk_apb_set_top_value(struct device *dev,
u32_t ticks,
counter_top_callback_t callback,
void *user_data)
const struct counter_top_cfg *top_cfg)
{
const struct tmr_cmsdk_apb_cfg * const cfg =
dev->config->config_info;
struct tmr_cmsdk_apb_dev_data *data = dev->driver_data;

data->top_callback = callback;
data->top_user_data = user_data;
/* Counter is always reset when top value is updated. */
if (top_cfg->flags & COUNTER_TOP_CFG_DONT_RESET) {
return -ENOTSUP;
}

data->top_callback = top_cfg->callback;
data->top_user_data = top_cfg->user_data;

/* Store the reload value */
data->load = ticks;
data->load = top_cfg->ticks;

/* Set value register to count */
cfg->timer->value = ticks;
cfg->timer->value = top_cfg->ticks;

/* Set the timer reload to count */
cfg->timer->reload = ticks;
cfg->timer->reload = top_cfg->ticks;

/* Enable IRQ */
cfg->timer->ctrl |= TIMER_CTRL_IRQ_EN;
Expand Down
Loading

0 comments on commit d8232f6

Please sign in to comment.