-
Notifications
You must be signed in to change notification settings - Fork 8.1k
driver: rtc: enable NXP sRTC driver. #94407
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
driver: rtc: enable NXP sRTC driver. #94407
Conversation
Holt-Sun
commented
Aug 12, 2025
- Add NXP sRTC device tree binding and NXP sRTC driver file.
- Update NXP device and board device tree and prj conf files.
- Add conf files in samples rtc for all supported boards.
- Add conf files in test rtc to run pass test for supported boards.
- Update readme doc.
67c3838
to
278b300
Compare
Please split the PR into multiple commits: driver, boards, samples, tests... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Device is not an RTC, its a low power counter, those use the counter API
drivers/rtc/rtc_nxp_srtc.c
Outdated
static uint32_t nxp_srtc_convert_datetime_to_seconds(const struct rtc_time *timeptr) | ||
{ | ||
/* Number of days from begin of the non Leap-year*/ | ||
uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, | ||
181U, 212U, 243U, 273U, 304U, 334U}; | ||
uint32_t seconds; | ||
uint16_t year = timeptr->tm_year + 1900; | ||
|
||
/* Compute number of days from 1970 till given year*/ | ||
seconds = ((uint32_t)year - YEAR_RANGE_START) * DAYS_IN_A_YEAR; | ||
/* Add leap year days */ | ||
seconds += (((uint32_t)year / 4U) - (YEAR_RANGE_START / 4U)); | ||
/* Add number of days till given month*/ | ||
seconds += monthDays[timeptr->tm_mon + 1]; | ||
/* | ||
* Add days in given month. We subtract the current day as it is | ||
* represented in the hours, minutes and seconds field | ||
*/ | ||
seconds += ((uint32_t)timeptr->tm_mday - 1U); | ||
/* For leap year if month less than or equal to Febraury, decrement day counter*/ | ||
if ((0U == (year & 3U)) && ((timeptr->tm_mon + 1) <= 2U) && 0U != seconds) { | ||
seconds--; | ||
} | ||
|
||
assert(seconds < UINT32_MAX / SECONDS_IN_A_DAY); | ||
seconds = (seconds * SECONDS_IN_A_DAY) + ((uint32_t)timeptr->tm_hour * SECONDS_IN_A_HOUR) + | ||
((uint32_t)timeptr->tm_min * SECONDS_IN_A_MINUTE) + timeptr->tm_sec; | ||
|
||
return seconds; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, converting between datetime and timestamp is not allowed in rtc drivers, if its needed, the device is not an rtc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://docs.zephyrproject.org/latest/hardware/peripherals/rtc.html#overview "An RTC is a low power device which tracks time using broken-down time. It should not be confused with low-power counters which sometimes share the same name, acronym, or both."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The sRTC in RM is showed as standard RTC for NXP device:
And in our MCUXpresso SDK, it is configured and used as a real timer clock. Previously, this RTC is maintained in counter model because the RTC driver model is added since zephyr 3.4. With RTC driver model available, we think it is more suitable to treat it as standard RTC in zephyr:
1, Keep consistency with MCUXpresso SDK.
2. Keep consistency with chip reference manual(soc design)
3. Applied in RTC driver model, it can have typical RTC features which is not provided in counter model: clockout/wakeup, calibration, normal second update. It doesn't need to workaround the counter feature like channel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the sRTC does not fit the counter API, nor the RTC API, a new API is needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both the zephyr counter model and RTC model can work with NXP RTC. The RTC driver model fits NXP RTC most. It makes sense to support both for customer selection.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The convertion functions from/to tick and rtc time wouldbe public, and tested. They would then be used by apps directly, or implicitly through this hypothesized rtc_counter.c driver.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Holt-Sun, the idea is that a generic RTC driver is written using the counter API as a target instead of a hardware. That way, we only need to write a simple counter driver for these device which look more like a counter. Then any counter can be used immediately with RTC API by going through this translation driver. The user just use the normal RTC API, no difference.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And also I think bjarkinis right that this code is very complex and maybe not needing to be, and we don't want to maintain it , especially not on many different drivers repeated similarly. Probably using time.h from standard library is going both way simplify and way optimize things
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Holt-Sun, the idea is that a generic RTC driver is written using the counter API as a target instead of a hardware. That way, we only need to write a simple counter driver for these device which look more like a counter. Then any counter can be used immediately with RTC API by going through this translation driver. The user just use the normal RTC API, no difference.
Ok, I will use another PR to go with this way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bjarki-andreasen, @decsny and all other reviewers, i have created new PR #95087 to go with the "a generic RTC driver is written using the counter API as a target instead of a hardware.". In this PR, standard library from time.h are used to convert ticks and times as requested. Please kindly review.
278b300
to
075da88
Compare
Done. Thanks. |
075da88
to
5c164d9
Compare
There are 2 build failures which will be fixed in another 2 PRs |
- stm32f3_disco | ||
- mimxrt700_evk/mimxrt798s/cm33_cpu0 | ||
- mimxrt700_evk/mimxrt798s/cm33_cpu1 | ||
- frdm_k22f |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
those platforms share the same config, maybe you can use a
sample.drivers.nxp_rtc
filter: dt_compat_enabled("nxp-rtc")
extra_configs:
- CONFIG_RTC_ALARM=y
- CONFIG_RTC_UPDATE=y
- CONFIG_RTC_CALIBRATION=y
and move below to common
common:
tags:
- samples
- rtc
- api
depends_on:
- rtc
harness: console
harness_config:
type: one_line
regex:
- "RTC date and time: 2024-11-17 04:19:01"
and change the origin on with another filter
sample.drivers.rtc:
filter: not dt_compat_enabled("nxp-rtc")
Support more RTC features like clock-output, time-seconds-frequency, etc. Signed-off-by: Holt Sun <[email protected]>
Add NXP RTC driver based on RTC driver model. Signed-off-by: Holt Sun <[email protected]>
Update rtc device tree data for k2x and k8x. Signed-off-by: Holt Sun <[email protected]>
1. Add confs for nxp boards. 2. Update doc. Signed-off-by: Holt Sun <[email protected]>
Set rtc status ok and add it into board alias. Signed-off-by: Holt Sun <[email protected]>
Add rtc test confs for nxp boards. Signed-off-by: Holt Sun <[email protected]>
5c164d9
to
78ace67
Compare
|
@Holt-Sun can we close this PR? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My opinion is clear, but given the fact that this driver does not impose any changes on the RTC API itself, the driver is ok.
I added some comments, specifically related to using time.h and checking the struct rtc_time passed to the driver is actually provided in a state which can be converted to a timestamp, which is not necessarily the case, given most RTCs support only matching on certain fields.
static uint32_t nxp_rtc_convert_datetime_to_seconds(const struct rtc_time *timeptr) | ||
{ | ||
/* Number of days from begin of the non Leap-year*/ | ||
uint16_t monthDays[] = {0U, 0U, 31U, 59U, 90U, 120U, 151U, | ||
181U, 212U, 243U, 273U, 304U, 334U}; | ||
uint32_t seconds; | ||
uint16_t year = timeptr->tm_year + 1900; | ||
|
||
/* Compute number of days from 1970 till given year*/ | ||
seconds = ((uint32_t)year - YEAR_RANGE_START) * DAYS_IN_A_YEAR; | ||
/* Add leap year days */ | ||
seconds += (((uint32_t)year / 4U) - (YEAR_RANGE_START / 4U)); | ||
/* Add number of days till given month*/ | ||
seconds += monthDays[timeptr->tm_mon + 1]; | ||
/* | ||
* Add days in given month. We subtract the current day as it is | ||
* represented in the hours, minutes and seconds field | ||
*/ | ||
seconds += ((uint32_t)timeptr->tm_mday - 1U); | ||
/* For leap year if month less than or equal to Febraury, decrement day counter*/ | ||
if ((0U == (year & 3U)) && ((timeptr->tm_mon + 1) <= 2U) && 0U != seconds) { | ||
seconds--; | ||
} | ||
|
||
assert(seconds < UINT32_MAX / SECONDS_IN_A_DAY); | ||
seconds = (seconds * SECONDS_IN_A_DAY) + ((uint32_t)timeptr->tm_hour * SECONDS_IN_A_HOUR) + | ||
((uint32_t)timeptr->tm_min * SECONDS_IN_A_MINUTE) + timeptr->tm_sec; | ||
|
||
return seconds; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use time.h, the rtc API and its types are built to be compatible with it, just typecast struct rtc_time
to struct tm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applied in new PR #95087
if (id != 0 || (mask && (timeptr == 0)) || | ||
(timeptr && !rtc_utils_validate_rtc_time(timeptr, mask))) { | ||
return -EINVAL; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the alarm time only needs to initialize the fields set in mask, the time could have arbitrary values in every field but tm_hour, and if that's the only field specified in the mask, it will validate just fine, while the later conversion to seconds will explode. Add a check here to enforce every field needed for the conversion to a timestamp is set, then validate that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is usually not necessary, but for this driver it definitely is
# | ||
# SPDX-License-Identifier: Apache-2.0 | ||
# | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this driver needs every field of the alarm time initialized, specify this using the CONFIG_TEST_RTC_ALARM_TIME_MASK=79 adjusting the mask to match what is needed for the datetime to unix timestamp conversion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In new PR, the CONFIG_TEST_RTC_ALARM_TIME_MASK is 255.
After discussion, we will provide a generic counter RTC API using counter APIs to work which is going on in #95087 (comment) |