Skip to content
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

sam0_common: make RTC implementation common across all sam0 MCUs #11317

Merged
merged 1 commit into from
Apr 16, 2019

Conversation

benpicco
Copy link
Contributor

@benpicco benpicco commented Mar 30, 2019

Contribution description

The currently supported SAM0 MCUs (samd21, saml21, saml1x) share the same RTC peripheral, yet each of them carries it's own copy of the RTC driver.

Unify the drivers and move them to sam0_common.

Testing procedure

Only tested it on samr21-xpro with the default example and rtc settime & rtc setalarm.

Issues/PRs references

#11305 will also use this implementation.

@fedepell
Copy link
Contributor

Very good idea IMO! We had a discussion about this time ago with @dylad in relation to #10523.

I've tested it on my saml21-xpro and works fine, I've used tests/periph_rtc to test.

@benpicco benpicco force-pushed the sam0-rtc branch 2 times, most recently from 050d76b to adf611f Compare March 31, 2019 13:55
#else
RTC->MODE2.CTRL.bit.ENABLE = 0;
#endif
#ifdef REG_RTC_MODE2_SYNCBUSY
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would replace these #ifdef REG_RTC_MODE2_SYNCBUSY block by a static or static inline function here. Easier to read and more compact.

Copy link
Contributor Author

@benpicco benpicco Mar 31, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

/* DISABLE RTC MASTER */
rtc_poweroff();

rtc_clock_setup();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please call rtc_clock_setup(); before rtc_poweroff();
SAML10-XPRO get stuck within rtc_poweroff(); which is a normal behavior since we're waiting for a bit but the IP is not clocked.
Strangely, it works so far for SAMD21, SAML21 and SAML11. Atmel black magic ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for testing!
btw, do we need to call rtc_poweroff() and rtc_reset() here at all?

e.g. the RTC keeps ticking in HIBERNATE / BACKUP deep sleep mode and can wake the CPU (which triggers a reset).

I was wondering why the RTC was still starting at 0 after that - only to discover that it is being reset in rtc_init()!

Is this the intended behavior? If not, I'd much rather just remove those calls here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@benpicco I have no strong opinion about reset yet. But rtc_poweroff() is mandatary for at least SAML21.
CTRLA register at least is "Enable-Protected" which means we cannot modify it after the ENABLE bit has beent set. This is why we must use rtc_poweroff(); before configuring our rtc.
Try to run the current code on SAML21, it should hang.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I've changed the call order and made the RTC persist across reboots.
I might as well remove rtc_reset() then as it's currently unused.

Only tested on the samr21 as I don't have a saml21.

@dylad dylad self-assigned this Apr 11, 2019
@dylad dylad added Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines labels Apr 11, 2019
Copy link
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll retest on all my boards asap.

while (RTC->MODE2.CTRLA.bit.SWRST);
void rtc_init(void)
{
rtc_poweron();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's useful to enable it right know as we will disable it a few line after.
I would say to power_off at the beginning of rtc_init and power_on at the end.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well you mentioned it is necessary for the device to be powered for rtc_clock_setup() to work on saml10.

Nothing should have enabled the RTC before this function is called, so it would stall again.

Copy link
Member

@dylad dylad Apr 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well you mentioned it is necessary for the device to be powered for rtc_clock_setup() to work on saml10.

I said to call rtc_clock_setup() before rtc_poweroff().
In fact, the current code still hangs for SAML10 because we're stuck in wait_syncbusy. Enable or disable RTC has no effect because RTC IP is not feed by the required clock so the syncbusy bit will not change. Thus, rtc_poweron() is not needed here and we should setup the clock in priority. I'm sorry if I wasn't clear enough I hope my explanations get better here.
In fact, we should Setup Clock -> Disable RTC module (because of Enabled Protected regs) -> Init RTC -> Enable RTC module

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, let's try it again then. I think having the poweron/poweroff functions wrap the ENABLE bit is a bit confusing, I've wrapped them in a separate function now and made the poweron/poweroff functions actually disable the peripheral in PM/MCLK like it is done in the RTT driver.

@@ -41,13 +43,50 @@ static rtc_state_t rtc_callback;
* Thanks to this, the user will be able to set time in 2000's*/
static uint16_t reference_year = 100;

void rtc_init(void)
static void wait_syncbusy(void)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

static function should be named with _ prefix
_wait_syncbusy()
This is the same for other static functions within this page.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See our coding convention if something is unclear to you

@dylad
Copy link
Member

dylad commented Apr 14, 2019

@benpicco New changes work fine on arduino-zero but I have issue with SAML10 / SAML11 and SAML21.
Seems to me alarms are triggered only half of the time. I'll investigate further tomorrow.

Copy link
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested work on SAML10, SAML11 and SAML21.
One last nitpick and we're good.
You can squash directly.
Thanks for your hard work @benpicco

cpu/sam0_common/periph/rtc.c Outdated Show resolved Hide resolved
The currently supported SAM0 MCUs (samd21, saml21, saml1x) share the
same RTC peripheral, yet each of them carries it's own copy of the RTC
driver.

Unify the drivers and move them to sam0_common.
Copy link
Member

@dylad dylad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK.
Good job @benpicco !

@dylad dylad added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Reviewed: 3-testing The PR was tested according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines Area: cpu Area: CPU/MCU ports Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation labels Apr 16, 2019
@dylad
Copy link
Member

dylad commented Apr 16, 2019

here we go.

@dylad dylad merged commit 8c70811 into RIOT-OS:master Apr 16, 2019
@benpicco benpicco deleted the sam0-rtc branch October 30, 2019 17:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: cpu Area: CPU/MCU ports CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Reviewed: 1-fundamentals The fundamentals of the PR were reviewed according to the maintainer guidelines Reviewed: 2-code-design The code design of the PR was reviewed according to the maintainer guidelines Reviewed: 3-testing The PR was tested according to the maintainer guidelines Reviewed: 4-code-style The adherence to coding conventions by the PR were reviewed according to the maintainer guidelines Reviewed: 5-documentation The documentation details of the PR were reviewed according to the maintainer guidelines Type: enhancement The issue suggests enhanceable parts / The PR enhances parts of the codebase / documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants