-
-
Notifications
You must be signed in to change notification settings - Fork 7.5k
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
rp2/machine_rtc: add initial support for RTC. #6928
Conversation
90315cc
to
7cc6412
Compare
ports/rp2/machine_rtc.c
Outdated
ret = rtc_get_datetime(&t); | ||
if (!ret) { | ||
// XXX: raise exception ? | ||
return mp_const_none; |
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 exception would be best here? maybe mp_raise_OSError(MP_EIO) ?
BTW, does anyone have any idea how to make the commit message check happy? I did change the commit message already but it seems to be always checking the original one :/ |
The build provided by @kadamski worked fine in Thonny -- it was now able to set RTC with the same time syncing code as used for ESP32. |
@dpgeorge this looks like it conforms to your Git commit conventions but still fails - has something changed? |
@kevindawson The regex used for the commit message check seems to be here. I think the problem in this case is that the message after the colon doesn’t start with a capital letter. |
error: commit 2bad8b5: Subject line should contain ': ' and end in '.': rp2/machine_rtc: add initial support for RTC.
∴"rp2/machine_rtc: Add initial support for RTC." ps. I'm looking forward to having a hack around with this :)) |
Initial support for machine.RTC on rp2 port. It only supports datetime() method and nothing else. The method gets/returns a tuple of 8 items, just like esp32 port, for example, but the usec parameter is ignored as the RP2 RTC only works up to seconds precision. The Pico RTC isn't very useful as the time is lost during reset and there seems to be no way to easily power up just the RTC clock with a low current voltage, but still there seems to be use-cases for that, see issues micropython#6831, and a thonny issue micropython#1592. It was also requested for inclusion on v1.15 roadmap on micropython#6832. Signed-off-by: Krzysztof Adamski <k@japko.eu>
@kevindawson rebased the patch and made the first letter of the commit message uppercase. |
@tjvr who do I request to perform the approve running workflow |
@dpgeorge would you please add this to your task list |
Thanks for this, definitely something that's needed! I think it makes sense to have the arguments to >>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2021, 6, 11, 18, 34, 51, 87566) So that's: See also #7318. |
@dpgeorge I aggree it would be good to fix the datetime to use the same API as CPython. I'm not sure, however, how to do this correctly as, on the other hand, it wouldn't be good to have different implementation on different ports, right? See also PR 5553 which is related. |
Right. But at the moment the existing ports are not consistent among themselves (as #5553 explains). And I think it's fair enough to add the method here on the rp2 port with the new desired API, because there is no existing code written specifically for rp2 that uses datetime, so it's a fresh start. I know it's not the best situation, but to make progress towards a consistent API that matches CPython's datetime, I think making this step on rp2 is good progress. Put differently, I think it'd just make things worse to not match CPython's datetime here. |
Well, that is not entirely true. Since this is part of machine API, basically any code that uses machine.RTC from some other port, will have to adapt, if we change it for rp2. The constructor of the datetime and the actual value represented by this object, was, so far, consistent between ports as far as I know and that would break this consistency and the users would have to handle that situation on their own. The elegant solution would be to create a new API that would be consistent while keeping the old one for legacy reasons, at least for some time. Something like a machine.RTC2. Or maybe it is time to consider something more general and better than the machine itself? Something like a device module that would have unified API that is not reconstructed by each port individually but would just call some callbacks internally that requests the data in a machine specific way but the actual API itself has just one implementation? This is something a circuitpython did well - the ports do not provide full python objects, like machine.RTC() but they provide some functions called common_hal_XXX instead to do the actual operations (like reading the datetime, setting the datetime in case of RTC). This is more limiting than each port implementing the full object but on the other hand it is much more userfriendly and micropython did grow large enough for this to pose large problem already. Note that implementing things this way (with HAL), not only makes the API consistent between ports but also reduces the boilerplate code that has to be written for each and every port and makes maintaining easier thanks to less duplicated code. So, what is your end verdict? Do we merge this PR as is to keep the API more consistent between ports and fix the incompatibility with CPython as a separate topic or should I change my PR? |
Yes that is true.
I had a look and stm32, esp32, esp8266 are all (almost) consistent with the cc3200 is different, it matches CPython, but it doesn't have a mimxrt has
That's a big step. It might be possible to just make
Yes I agree CircuitPython did this well. And we are slowly moving in that direction, eg
Ok, the options would be:
It feels like option (1) is the most sensible, to not break existing code. |
That is true, the constructor could work in both cases but the return value is the problem here.
Indeed, the way machine_spi.c is done is (I think) what I was talking about! If I would volunteer to do a PR for creating something like extmod/machine_rtc.c (based on the techniques used in extmod/machine_spi.c) and implement this for the ports I could test it on, would you be interested and find time to review this? I would prefer to do this in a backwards compatible way, however, by providing this unified module alongside the existing machine_rtc implementations, to be honest. But if you think it is ok to break backwards compatibility, I can do it this way too.
Well, the new API would only be needed if we wanted to keep backwards compatibility which, you know, is a nice thing to have, even if we're talking Python here :)
I agree. |
Ok, let's go for option (1).
Yes, that would be great. Note that SPI/I2C have a dynamic protocol table because they are used for both software and hardware implementations. That's probably not going to be needed for RTC because it only has one implementation. See also
Yes that would be necessary (backwards compatible). What I was thinking would be to provide a generic hook macro in the locals dict for a class/module so the port can add arbitrary method/functions (in an ideal situation that would not contain anything, so all ports are the same, but to start with it's a way to unify implementations). |
See #7383 for a PR to change the mimxrt port to the same datetime tuple as is used here. |
I'm confused now... I installed rp2-pico-20210613-unstable-v1.15-211-g3ab8806c0.uf2 and experimented according to https://github.com/micropython/micropython/pull/5553/files:
I expected at least year, month and day to match the assigned values. |
It looks like there is a confusion regarding numbering the weekday. When I'm giving 6 for Sunday, then Pico's
Previously I thought that weekday argument to Specifying sunday as 7 for ESP32 (v1.14 on 2021-02-02)
specifying Sunday as 6:
|
According to pico-sdk docs (https://raspberrypi.github.io/pico-sdk-doxygen/structdatetime__t.html), the weekday is 0-6 where 0 is Sunday. That is quite confusing, as you have to start counting weekdays at 0, while the months and days of a month are counted starting from 1. Then, there is this problem of the first day in week - according to ISO 8601, it is Monday, but US, Canada, Australia (and probably some others) recognize Sunday as the first day of a week, so does Pico. All in all, I think this weekday is nothing but confusing and we will benefit from getting rid of it, as was explained here. What I can do as a quick fix for your problem is this:
|
Giving error for weekday 7 is good idea! In addition to this, it should be documented with RTC. Also please don't forget the discrepancy between |
The rtc_set_datetime() from pico-sdk will validate the values in the datetime_t structure and refuse to set the time if they aren't valid. It makes sense to raise an exception if this happens instead of failing silently which might be confusing (as an example, see: micropython#6928 (comment) ).
The rtc_set_datetime() from pico-sdk will validate the values in the datetime_t structure and refuse to set the time if they aren't valid. It makes sense to raise an exception if this happens instead of failing silently which might be confusing (as an example, see: micropython#6928 (comment) ).
@aivarannamaa thanks for your raport, it reveals more problems with RTC than I originally seen. We have focused on making sure the order of arguments in the tuple we give to RTC.datetime() is the same on all machines but we didn't make sure the meaning of those fields is also the same! I will try to check how that works on other ports this evening and may provide some more patches, maybe that is only rp2 specific problem and other implementations are all the same.. As for the RTC.datetime() vs time.localtime() discrepancy it is a good idea to open a new issue for that. I am not sure we we should always sync the RTC and localtime or not so lets discuss this there. Will open the issue or should I? Note that, according to my initial check, the ESP32 implementation simply ignores the dayw argument when the datetime() is called with a tuple, which would explain why using 6 and 7 gives the same results. |
Please open it yourself, then you can already propose your solution ideas! |
The implementation for mimxrt also ignores the weekday value on input. It is calculated on output from the date. |
The rtc_set_datetime() from pico-sdk will validate the values in the datetime_t structure and refuse to set the time if they aren't valid. It makes sense to raise an exception if this happens instead of failing silently which might be confusing (as an example, see: micropython#6928 (comment) ).
The rtc_set_datetime() from pico-sdk will validate the values in the datetime_t structure and refuse to set the time if they aren't valid. It makes sense to raise an exception if this happens instead of failing silently which might be confusing (as an example, see: #6928 (comment) ).
The rtc_set_datetime() from pico-sdk will validate the values in the datetime_t structure and refuse to set the time if they aren't valid. It makes sense to raise an exception if this happens instead of failing silently which might be confusing (as an example, see: micropython/micropython#6928 (comment) ).
Initial support for machine.RTC on rp2 port. It only supports datetime()
method and nothing else. The method gets/returns a tuple of 8 items,
just like esp32 port, for example, but the usec parameter is ignored as
the RP2 RTC only works up to seconds precision.
Signed-off-by: Krzysztof Adamski k@japko.eu