cpu/atmega_common: implement emulated RTC support#13394
cpu/atmega_common: implement emulated RTC support#13394miri64 merged 3 commits intoRIOT-OS:masterfrom
Conversation
|
While this is nice and generic, now that I'm thinking about it, we don't need to pull in the whole RTT abstraction to just have a timer counting to 32. |
|
Just using Timer 2 directly shaves off 658 bytes of ROM for before: after: The RTC also lost that slight drift probably caused by repeatedly setting the RTT alarm - it's much simpler now. |
|
Retriggered so this doesn't accidentally get stuck on #13481 |
|
Tested on |
|
All green, but I haven't followed the discussion to know which alternative ( this or #8842) should be preferred, @roberthartung @maribu @gschorcht thoughts? |
|
I haven't read the complete discussion in PR #8842 which tried to provided RTC as well as RTT support. RTT support was added with PR #12815. A logical conclusion is to add the RTC support now. If I'm right, the most important point in the discussion in PR #8842 was the question, whether RTC couldn't reuse the RTT and whether a common wrapper could be used for that. According to @benpicco the reason why wan't possible, was that the RTT uses a prescaler of 32 by default and the resulting clock frequency would be 1024 Hz. I didn't think about it til now, but now the following question arises: |
The timer would still be only 8 bit. That's an 'emulated' RTT too, there are no long running counters. So there is no benefit in stacking abstractions on top of each other. |
|
@fjmolinas #8842 has been abandoned, now this PR provides a new approach based on the new RTC helper functions, which makes it much smaller. |
Add a function to verify all members of a struct tm are within the valid range.
This implements a basic Real Time Clock based on TIM2. As the timer is too fast and wraps around after just 8 bits, it is not used directly. Instead TIM2 is responsible for providing a 1 Hz tick by generating an alarm every second. The current time data is kept in the `.noinit` section, so it will survive a reboot, but the clock will not be updated while the bootloader runs, so expect inaccuracies.
Every ATmega board that can run an Real Time Timer can also run
an emulated Real Time Clock.
Got all supported boards by adding `FEATURES_REQUIRED += arch_8bit`
to `tests/periph_rtt` and running
sed -i 's/FEATURES_PROVIDED += periph_rtt/
FEATURES_PROVIDED += periph_rtc\n
FEATURES_PROVIDED += periph_rtt/g'
on them.
Yep, I'm fine with it just wanted to make sure not to step over other work. |
Contribution description
This re-purposes the Real Time Timer of the ATmega family as a Real Time Clock.
It is not as good as a real RTC as it's operation is entirely software based.
The RTT warps around too quickly to act as a counter, but it will act as a 1 Hz clock to increment the RTC counter.
This means the clock will not update in situations where the interrupt is not run (e.g. bootloader) or is delayed (e.g. disabled interrupts).
But it ensures compatibility with applications that rely on an RTC and the discussion in #8842 showed there is interest in this.
To mitigate being reset through reboot, the counter data is kept in the
.noinitsection.There it survived at least the bootloader of the
avr-rss2.To prevent returning severely corrupted data on cold boot, a new function
rtc_tm_valid()is introduced.It checks if the
struct tmwould be normalized to verify the data is valid.It might be useful for other RTC implementations as well.
Testing procedure
Run
tests/periph_rtcon a supported board (atmega256rfr2-xpro,avr-rss2,derfmega128,derfmega256,mega-xplained,microduino-corerf).The
rtccommand inexamples/defaultshould also work as expected.Issues/PRs references
Alternative to #8842