-
Notifications
You must be signed in to change notification settings - Fork 136
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
[stm32] Adding Real Time Clock (RTC) for STM32G4 #1055
base: develop
Are you sure you want to change the base?
Conversation
|
This comment was marked as resolved.
This comment was marked as resolved.
It occured to me that I am also debating if the I pressume that the ideal interface for the Rtc would be similar to For initialization something I think |
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.
I have done this by not overwriting entries in the rcc_enable dict.
Seems fine. Honestly the whole remap thing is quite a hack anyways…
I am also debating if the Rtc class should take the asynchronous and synchronous prescalars as template paramters.
No, try to stick to the initialize<SystemClock>()
convention.
I presume that the ideal interface for the Rtc would be similar to
std::chrono::steady_clock
Yes, but I think the system_clock
may fit better.
I would use int64_t
, as this is also used in std::chrono, and makes it possible to use all the library functions directly. The uint32_t
modm::Clock
is just optimizations for the Timers.
For initialization something I think
std::chrono::year_month_day
Maybe? Would be nice not to have to do calendar calculations in software when it's already done in hardware, but dunno if the hardware supports that.
@@ -167,4 +167,4 @@ Rcc::isEnabled() | |||
%% endfor | |||
} | |||
|
|||
} // namespace modm::platform | |||
} // namespace modm::platform |
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.
best to change your editor to add a newline at the end of file, otherwise there'll be a lot of these changes in the modm code base ;-P
bool | ||
Rtc::initialize(const DateTime dateTime, const Prescaler prescaler, uint32_t waitCycles) | ||
{ | ||
/// TODO: Assert that RTC frequency is less than APB1 frequency |
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.
You would typically pass the SystemClock as a template (function) parameter here to figure out which bus the RTC is clocked from, and then use the modm::Prescaler
static methods (or a custom constexpr computation that you can also unit test separately) to compute your prescalers for the right running rate (1Hz?) and assert their required tolerance.
This architecture enables that you can switch to different SlowSystemClock::enable()
configurations at runtime and call the initialize<SlowSystemClock, ...>()
functions without too much code duplication. At least in theory, I've only had prototypes of this working, using different clocks is only useful for power saving, which modm… doesn't support anyways.
bool | ||
Rtc::getDateTime(DateTime &dateTime, uint32_t waitCycles) | ||
{ | ||
/// TODO: Determine if ABP1 frequency is less than seven times RTC frequency |
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.
You would write this information to a bool
member in initialize()
and query it here. it's a bit inelegant, but kinda how we do things here.
* | ||
*/ | ||
static bool | ||
getDateTime(DateTime &dateTime, uint32_t waitCycles = 2048); |
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.
Should there perhaps also be a setDateTime, if the hardware support that? Would be useful for stuff like proper FAT file time etc.
* @return float | ||
*/ | ||
static bool | ||
getSubSecond(float &subsecond, uint32_t waitCycles = 2048); |
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.
maybe only provide the system_clock::now()
interface instead of this function? Hm, at least not to float ;-P
return true; | ||
} | ||
return false; | ||
} |
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.
what does this do?
c4839fb
to
c627c1d
Compare
Thanks for the nice comments! I have tried to resolve most of the issues and will solve the remaining hopefully this week. In resolving these issues I have encountered the following problems that I would like your take on:
Thanks in advance for your help! |
No, that informatio should come from SystemClock, which should contain the full clock configuration.
Prescaler A is only 7-bit so you can linearly iterate 1-128 and find a suitable prescaler S that fits the tolerance. Maybe a prescaler s ≥1000 ticks so that you get millisecond resolution? You can do it at compile time with constexpr, then it's easy to code and costs almost nothing in compile time and you can unit test it separately. Perhaps you should pass a frequency parameter so that people can specify what subsecond frequency they require.
Ok, that's fine, just may have been nice.
modm does not yet have the concept for brown out detection. Just reinitialize everything.
Ugh, I was hoping there'd just be a uint32_t unix timestamp in there. |
This is still work in progress, but I believe that I need a bit of help to finish it up! Currently, I intend to use RTC solely for the for getting timestamps used for logging to a flash chip. This PR should resolve some of the points discussed in #730.
I have left a lot of TODOs in code which I will try to resolve within the near future. However, I would like your input on the following points:
rcc
, the enable peripheral function does not enable the the APB1 peripheral clock for RTC (at least for the G4 family). The function does however enable the RTC withRCC->BDCR |= RCC_BDCR_RTCEN;
. I believe that both should be enabled within this function, or what do you think?std::tm
exists, and I am debating if I should use this or some other standard library struct. I have not implemented the driver withstd::tm
yet because it counts years since 1900 and weekday starting from 0. This does not align with the STM32G4 RTC which only support two digit years and where Monday = 1 and Sunday = 7. Of course, I can make the conversion, but then this would have to be carried out everywhere in the RTC code. What is your opinion on this?math::utils
or somewhere a like? Afterall there are other drivers also converting to and from BCD in modm.Finally, I have not yet devised a novel test for verifying that the
synchronize
function is actually working. From looking at the documentation I suppose it should be working, but my experience is that there is usually, some bug lurking in my untested code. Have you got any idea for such a test? My initial thought was to test if I could (approximately) zero the subsecond counter.