Skip to content

alif: implement machine.RTC.datetime, enable remaining time functions, and implement littlefs, FAT and mbedTLS time #17900

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 5 commits into from
Aug 15, 2025

Conversation

dpgeorge
Copy link
Member

Summary

This PR finishes the time implementation on the alif port:

  • adds machine.RTC.datetime to get/set the RTC
  • adds time.time(), time.time_ns(), time.localtime(), time.mktime(), time.gmtime()
  • implements time for littlefs and FAT
  • implements time for certificates for mbedTLS

The Epoch is 1970 and the time range is the year 1970 to 2106. Resolution is 30 microseconds (achievable via time.time_ns()).

Testing

Tested on OPENMV_AE3, running the entire test suite:

  • all extmod time tests now pass
  • all SSL certificate based network tests now pass

Trade-offs and Alternatives

The LPRTC peripheral is a 32-bit counter with a 16-bit prescaler. I configured the counter to count at 1Hz (to get maximum date range) and then used the prescaler value to get 30 microsecond resolution. That's essentially a 32+15=47-bit counter. That's the best scheme I could come up with.

@dpgeorge
Copy link
Member Author

@kwagyeman @iabdalkader FYI

@kwagyeman
Copy link
Contributor

@dpgeorge - Do you need us to check or approve anything?

@dpgeorge
Copy link
Member Author

I you have any review comments, please make them. Note that this changes the prescaler on the LPRTC to 32768, so it clocks at 1Hz. The comments in the code explain the reasoning.

@kwagyeman
Copy link
Contributor

kwagyeman commented Aug 13, 2025

I don't have any comments, just for you to keep your eye on adding RTC Memory too at some point for the AE3 and N6 to access the battery backup RAM. @iabdalkader may have some.

@iabdalkader
Copy link
Contributor

If I understand correctly, the tradeoff is between date range and resolution? I'd say finer resolution is more important, and more likely to be needed than a 100+ years range. However at the same time 30us is good enough for any application, I think. So either way is fine with me, your call.

@dpgeorge
Copy link
Member Author

dpgeorge commented Aug 14, 2025

If I understand correctly, the tradeoff is between date range and resolution?

Sort of. It's really a resolution of the LPRTC alarm more than anything.

30us is good enough for any application

Note that you can never get better (or worse) than 30us for the combined counter+prescaler resolution. That's just 1/32kHz, the resolution of the LPRTC clock. The question is where you draw the line between counter and prescaler: the counter+prescaler are a 48-bit counter counting at 32kHz and you can chose what the prescaler counts to before clocking the counter by 1.

  • If you make the prescaler upper limit its minimum then the counter counts at 32kHz and the prescaler is unused. That means the alarm has resolution of 1/32kHz=30us. But it also means the maximum range is 2**32/32768=2**17=128k seconds=1.5 days. So that's no good.
  • If you make the prescaler upper limit its maximum then the counter counts at 0.5Hz. The alarm has resolution of 2 seconds and the range is 272 years.
  • I chose to make the prescaler upper limit 32768 to simplify the logic. The counter counts at 1Hz, the alarm has resolution of 1 second, and the range is 136 years (Epoch of 1970+136=up to year 2106).

In all the above cases the prescaler is used to get extra resolution, so that counter+prescaler always has 30us resolution. See mp_hal_time_get().

@iabdalkader
Copy link
Contributor

  • The counter counts at 1Hz, the alarm has resolution of 1 second

Still seems good enough for the RTC.

The LPRTC peripheral is a 32-bit counter with a 16-bit prescaler.  It's
configured here to count at 1Hz (to get maximum date range) and then the
prescaler value is used to get 30 microsecond resolution.  That's
essentially a 32+15=47-bit counter.

Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Signed-off-by: Damien George <damien@micropython.org>
Adds: `time.time()`, `time.time_ns()`, `time.localtime()`, `time.mktime()`
and `time.gmtime()`.

Signed-off-by: Damien George <damien@micropython.org>
@dpgeorge dpgeorge merged commit f146244 into micropython:master Aug 15, 2025
7 checks passed
@dpgeorge dpgeorge deleted the alif-more-time branch August 15, 2025 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants