Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

counter: Update counter API in order to provide more flexibility #14794

Merged

Conversation

pizi-nordic
Copy link
Collaborator

This PR introduces new "reset" parameter to the set_top_value()
making resetting counter optional during change of top value.

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

@zephyrbot
Copy link
Collaborator

zephyrbot commented Mar 21, 2019

All checks are passing now.

Review history of this comment for details about previous failed status.
Note that some checks might have not completed yet.

@@ -329,6 +330,7 @@ static inline int counter_cancel_channel_alarm(struct device *dev,
* @retval -EBUSY if any alarm is active.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add -ENOTSUP error if option is not supported

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@@ -329,6 +330,7 @@ static inline int counter_cancel_channel_alarm(struct device *dev,
* @retval -EBUSY if any alarm is active.
*/
static inline int counter_set_top_value(struct device *dev, u32_t ticks,
bool reset,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder if it's not worth to bundle options to cfg structure like in counter_set_channel_alarm. It's then easier to add new features without braking backward compatibility (as long as false in option means legacy behavior). Now we exceed boundary of 4 arguments.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that with 5 arguments we are still more efficient that using separate data structure.

@pizi-nordic pizi-nordic force-pushed the counter-api-update branch 3 times, most recently from 206796d to de46337 Compare March 22, 2019 13:17
@pizi-nordic
Copy link
Collaborator Author

@nordic-krch: Could you please look at the last update?

@galak galak added area: API Changes to public APIs area: Counter labels Apr 19, 2019
include/counter.h Outdated Show resolved Hide resolved
Copy link
Member

@ioannisg ioannisg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok to me. Does the counter test still pass with the modified API?

@pizi-nordic
Copy link
Collaborator Author

@ioannisg: As seen in the shippable.

@ioannisg
Copy link
Member

ioannisg commented May 2, 2019

@ioannisg: As seen in the shippable.

Does Shippable actually run this test on target?

Copy link
Member

@anangl anangl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea of adding the reset parameter is good, but I think it would be indeed better to use a structure for passing the parameters to the counter_set_top_value function, as @nordic-krch suggested earlier. In most cases it will be more efficient than passing 5 arguments to the function (4 via registers and the fifth via stack), especially when the contents of the structure will be constant, what I think can be expected to happen often. And we'll gain the flexibility mentioned by @nordic-krch. Please, consider it once more. The amount of work needed to switch to this approach does not seem to be that big. I can help a bit if needed.

@nordic-krch
Copy link
Contributor

@pizi-nordic @anangl can you take a look as I've updated it to use configuration struct instead of function arguments.

include/counter.h Outdated Show resolved Hide resolved
drivers/counter/counter_ll_stm32_rtc.c Outdated Show resolved Hide resolved
drivers/counter/counter_rtc_qmsi.c Outdated Show resolved Hide resolved
include/counter.h Outdated Show resolved Hide resolved
@carlescufi
Copy link
Member

@mnkp can you please take another look and approve if happy?
@andyross if you have had a chance to look at the counter driver API PRs, could you voice your opinion on this one?

@carlescufi
Copy link
Member

@erwango @MaureenHelm can you please take a look and give feedback?

@nordic-krch
Copy link
Contributor

I've added following updates:

  • driver after changing top value checks if it does not go outside and return -ETIME if that happened.
  • added COUNTER_TOP_CFG_RESET_WHEN_LATE flag which additionally can instruct driver to reset counter when such situation occurs.

Added implementation for 4 drivers which can support that now:

  • counter_sam0_tc32.c @benpicco can you check?
  • counter_gecko_rtcc.c @mnkp can you check?
  • counter_nrfx_timer.c and counter_nrfx_rtc.c

@benpicco
Copy link
Collaborator

looks good to me.

@nordic-krch
Copy link
Contributor

@mnkp can you take a look at the recent changes? Lets make goal to merge it in 3 months from submitting. One week left.

@nordic-krch
Copy link
Contributor

@anangl could you also take a look? Since you approved there were some changes.

Copy link
Member

@mnkp mnkp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mnkp can you take a look at the recent changes? Lets make goal to merge it in 3 months from submitting. One week left.

Sorry, you're right complaining. The #16252 is introducing the concept of a guard time. I believe it would be best to reuse it. We would keep the API consistent.

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)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

By default COUNTER_TOP_CFG_DONT_RESET is not set so this if statement will evaluate to true. This is change of behavior. I didn't check the datasheet but how come this counter doesn't start counting from 0 when it's reaching the top value?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i've digged into the manual. Counter can be reset or left free running. I've added implementation to support resetting the counter.

This is change of behavior

well, behavior was a bug according to counter_set_top_value description in master:
Function sets top value and resets the counter to 0 or top value depending on counter direction.

Now it will be clarified.

@@ -91,10 +91,12 @@ static u32_t counter_gecko_read(struct device *dev)
}

static int counter_gecko_set_top_value(struct device *dev, u32_t ticks,
counter_top_callback_t callback,
void *user_data)
const struct counter_top_cfg *top_cfg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we use cfg instead of top_cfg like in all other drivers. To make it more consistent.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

cfg->callback ? true : false);

if ((cfg->flags & COUNTER_TOP_CFG_DONT_RESET) &&
(counter_nrfx_read(dev) > cfg->ticks)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be >=.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

cfg->ticks, COUNTER_OVERFLOW_SHORT,
cfg->callback ? true : false);

if ((cfg->flags & COUNTER_TOP_CFG_DONT_RESET) &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, even if the counter is reset, we can end up with the top value set lower than the current counter value. Although it could happen only for very low top values and accordingly high latencies between clearing the counter and setting the new compare value, but maybe such unusual scenario should be handled as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. Should we use the same approach in counter_nrfx_rtc, for consistency and for people having the need to set top value to 1?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@@ -91,10 +91,12 @@ static u32_t counter_gecko_read(struct device *dev)
}

static int counter_gecko_set_top_value(struct device *dev, u32_t ticks,
Copy link
Member

@anangl anangl Jun 14, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ticks is now a field of the counter_top_cfg structure. Does this compile successfully?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there is no test that uses that apparently. Fixed.

LOG_ERR("Wrap can only be set to 0x%x", info->max_top_value);
if (cfg->ticks != info->max_top_value){
LOG_ERR("Wrap can only be set to 0x%x. "
"Counter reset is not supported.", info->max_top_value);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The second part of the message is no longer valid.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@nordic-krch nordic-krch force-pushed the counter-api-update branch 2 times, most recently from 645a321 to 039f9b9 Compare June 17, 2019 06:12
drivers/counter/counter_nrfx_rtc.c Outdated Show resolved Hide resolved
drivers/counter/counter_nrfx_timer.c Outdated Show resolved Hide resolved
@nordic-krch
Copy link
Contributor

@mnkp your comments applied. Anything more?

@nordic-krch
Copy link
Contributor

@mnkp gentle ping.

Copy link
Member

@mnkp mnkp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with minor comments.

drivers/counter/counter_nrfx_rtc.c Show resolved Hide resolved
include/counter.h Outdated Show resolved Hide resolved
include/counter.h Show resolved Hide resolved
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 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]>
Signed-off-by: Benjamin Valentin <[email protected]>
@carlescufi carlescufi merged commit 69406e0 into zephyrproject-rtos:master Jun 25, 2019
@pizi-nordic pizi-nordic deleted the counter-api-update branch July 11, 2019 14:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: API Changes to public APIs area: Counter area: Tests Issues related to a particular existing or missing test
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants