Skip to content

Feat nrf time rtc support #6202

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

Closed
wants to merge 2 commits into from

Conversation

hoihu
Copy link
Contributor

@hoihu hoihu commented Jun 27, 2020

This is a cleanup version of the inputs collected in #6171
(I didn't want to force push the update to that PR because it contains implementation details
via ticker module that might be useful for others)

Basically it adds support for time.ticks_ms / time.ticks_us via RTC1, configured in 30usec tick mode. It also
adds the time.ticks_add and time.ticks_diff helper functions.

For this to work properly the RTC1's overflow irq is handled and a msec / usec ticks counter appropiately
generated (see also commit comment for this relatively complex matter). Thanks for @dpgeorge for
basically providing the solution there!

The PR also contains support for MICROPY_EVENT_POLL_HOOK. The wakeup from WFI is done via RTC1's
CCR0, configured in app. 1msec intervals. Basically that makes the nrf port ready for asyncio.

This feature can be enabled using MICROPY_PY_TIME_TICKS. If disabled, the system uses the legacy
ticks and sleep methods.

@hoihu hoihu mentioned this pull request Jun 27, 2020
@hoihu hoihu force-pushed the feat-nrf-time-rtc-support branch 2 times, most recently from 2b5ddf2 to 80b7ece Compare June 27, 2020 22:13
@dpgeorge
Copy link
Member

Looks really good!

@glennrub
Copy link
Contributor

From my side, it looks good as well.
I've tested the patch a bit, including WFI, overflow and my obscure "IRQ in IRQ" scenario. I all seems to work very well. I've also test integrated it into my nrf91 sockets, and you have solved my need for timer. Thank you @hoihu !

@hoihu
Copy link
Contributor Author

hoihu commented Jun 30, 2020

From my side, it looks good as well.
I've tested the patch a bit, including WFI, overflow and my obscure "IRQ in IRQ" scenario. I all seems to work very well. I've also test integrated it into my nrf91 sockets, and you have solved my need for timer. Thank you @hoihu !

Great, thanks!

hoihu added 2 commits July 2, 2020 22:19
Add time.ticks_ms / time.ticks_us support using RTC1 as timebase.
Also add the time.ticks_add resp. time.ticks_diff helper functions.

This feature can be enabled using MICROPY_PY_TIME_TICKS. If disabled
the system uses the legacy sleep methods.

In addition support for MICROPY_EVENT_POLL_HOOK was added
to the time.sleep_ms(x) function, making this function more power
efficient and allows support for select.poll / asyncio. To support
this, the RTC's CCR0 was used to schedule a ~1msec event to wakeup
the CPU.

Some important notes about the RTC timebase:

- Since the granularity of RTC1's ticks are app. 30usec, time.ticks_us
is not perfect, but moreless usable. For tighter measurments, the
ticker's 1MHz counter should be used.

- time.ticks_ms(x) should *not* be called in an irq with
higher prio than the RTC overflow irq (3). If so, it introduces
a race condition and possibly leads to wrong tick calculations.

- See also micropython#6171
for further informations.
@hoihu hoihu force-pushed the feat-nrf-time-rtc-support branch from 80b7ece to fd33bcf Compare July 2, 2020 20:19
@hoihu
Copy link
Contributor Author

hoihu commented Jul 2, 2020

I force pushed the review feedbacks, changes are:

  • MICROPY_EVENT_POLL_HOOK is enabled unconditionally in mp_hal_stdin_rx_chr
  • The first RTC's CC irq is now properly scheduled (I used a macro there too). The RTC counter is soft-reset proof (not sure if that really matters, but might be nice on the REPL).
  • Deleted unused #include

From my point of view ready to go in.

dpgeorge pushed a commit that referenced this pull request Jul 8, 2020
This commit adds time.ticks_ms/us support using RTC1 as the timebase.  It
also adds the time.ticks_add/diff helper functions.  This feature can be
enabled using MICROPY_PY_TIME_TICKS.  If disabled the system uses the
legacy sleep methods and does not have any ticks functions.

In addition support for MICROPY_EVENT_POLL_HOOK was added to the
time.sleep_ms(x) function, making this function more power efficient and
allows support for select.poll/asyncio.  To support this, the RTC's CCR0
was used to schedule a ~1msec event to wakeup the CPU.

Some important notes about the RTC timebase:

- Since the granularity of RTC1's ticks are approx 30usec, time.ticks_us is
not perfect, does not have 1us resolution, but is otherwise quite usable.
For tighter measurments the ticker's 1MHz counter should be used.

- time.ticks_ms(x) should *not* be called in an IRQ with higher prio than
the RTC overflow irq (3).  If so it introduces a race condition and
possibly leads to wrong tick calculations.

See #6171 and #6202.
@dpgeorge
Copy link
Member

dpgeorge commented Jul 8, 2020

Thanks for updating, and for the effort putting this together. Now merged in 15574cd and 59ed3bd (with minor edits to reorder some bits, and remove MICROPY_PY_TIME_TICKS guard from MICROPY_EVENT_POLL_HOOK definition).

@dpgeorge dpgeorge closed this Jul 8, 2020
amirgon pushed a commit to lvgl/lv_micropython that referenced this pull request Sep 4, 2020
This commit adds time.ticks_ms/us support using RTC1 as the timebase.  It
also adds the time.ticks_add/diff helper functions.  This feature can be
enabled using MICROPY_PY_TIME_TICKS.  If disabled the system uses the
legacy sleep methods and does not have any ticks functions.

In addition support for MICROPY_EVENT_POLL_HOOK was added to the
time.sleep_ms(x) function, making this function more power efficient and
allows support for select.poll/asyncio.  To support this, the RTC's CCR0
was used to schedule a ~1msec event to wakeup the CPU.

Some important notes about the RTC timebase:

- Since the granularity of RTC1's ticks are approx 30usec, time.ticks_us is
not perfect, does not have 1us resolution, but is otherwise quite usable.
For tighter measurments the ticker's 1MHz counter should be used.

- time.ticks_ms(x) should *not* be called in an IRQ with higher prio than
the RTC overflow irq (3).  If so it introduces a race condition and
possibly leads to wrong tick calculations.

See micropython#6171 and micropython#6202.
tannewt pushed a commit to tannewt/circuitpython that referenced this pull request May 12, 2022
samd: Don't rely on RTC interrupt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants