Skip to content

Fix us_ticker for NRF52 series #6796

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

Merged
merged 1 commit into from
May 7, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions targets/TARGET_NORDIC/TARGET_NRF5x/us_ticker.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,31 +234,28 @@ void common_rtc_set_interrupt(uint32_t us_timestamp, uint32_t cc_channel,
// the interrupt generation.
uint64_t current_time64 = common_rtc_64bit_us_get();
// [add upper 32 bits from the current time to the timestamp value]
uint64_t timestamp64 = us_timestamp +
(current_time64 & ~(uint64_t)0xFFFFFFFF);
uint64_t timestamp64 = (current_time64 & ~(uint64_t)0xFFFFFFFF) | us_timestamp;
// [if the original timestamp value happens to be after the 32 bit counter
// of microsends overflows, correct the upper 32 bits accordingly]
if (us_timestamp < (uint32_t)(current_time64 & 0xFFFFFFFF)) {
if (timestamp64 < current_time64) {
timestamp64 += ((uint64_t)1 << 32);
}
// [microseconds -> ticks, always round the result up to avoid too early
// interrupt generation]
uint32_t compare_value =
(uint32_t)CEIL_DIV((timestamp64) * RTC_INPUT_FREQ, 1000000);

uint32_t compare_value = RTC_WRAP((uint32_t)CEIL_DIV((timestamp64) * RTC_INPUT_FREQ, 1000000));

core_util_critical_section_enter();
// The COMPARE event occurs when the value in compare register is N and
// the counter value changes from N-1 to N. Therefore, the minimal safe
// difference between the compare value to be set and the current counter
// value is 2 ticks. This guarantees that the compare trigger is properly
// setup before the compare condition occurs.
uint32_t closest_safe_compare = common_rtc_32bit_ticks_get() + 2;
if ((int)(compare_value - closest_safe_compare) <= 0) {
uint32_t closest_safe_compare = RTC_WRAP(common_rtc_32bit_ticks_get() + 2);
if (closest_safe_compare - compare_value < 2) {
Copy link
Member

Choose a reason for hiding this comment

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

I might have missed something, but if compare_value is equal to the current RTC ticks value, that is compare_value == common_rtc_32bit_ticks_get(), this condition will be false and an invalid value will be written to CC register. Was that intentional? That new condition might well be replaced with: if (compare_value + 1 == closest_safe_compare).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think you are right. It should have been <= 2 in the comparison. However, the new 5.9 tickers are about to land so I don't think we should fix this.

compare_value = closest_safe_compare;
}

nrf_rtc_cc_set(COMMON_RTC_INSTANCE, cc_channel, RTC_WRAP(compare_value));
nrf_rtc_cc_set(COMMON_RTC_INSTANCE, cc_channel, compare_value);
nrf_rtc_event_enable(COMMON_RTC_INSTANCE, int_mask);

core_util_critical_section_exit();
Expand Down