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

cpu/sam0_common/../rtt: correcly clear flags. #12188

Merged
merged 1 commit into from
Sep 11, 2019

Conversation

jcarrano
Copy link
Contributor

Contribution description

The INTFLAGS register is cleared by writing a 1 to the corresponding interrupt flag bit. From the samr21's manual:

Writing a zero to this bit has no effect.
Writing a one to this bit clears the Compare 0 interrupt flag.

This is a common pattern in flag registers.

This RTT driver is using or-equal to clear the flags, which means it can possibly clear other interrupts. There's a small chance that one event is missed if it happens very close to another event.

Testing procedure

I did not test this, I just read the manual and did what it says. I'm opening this PR because I think it does not make sense to have an open issue whose fix is only two lines.

Issues/PRs references

Fixes #10351.

@jcarrano jcarrano added Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) Area: cpu Area: CPU/MCU ports labels Sep 10, 2019
@jcarrano jcarrano added the Area: timers Area: timer subsystems label Sep 10, 2019
@benpicco benpicco added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Sep 10, 2019
@benpicco
Copy link
Contributor

Good catch!
But there is more:

diff --git a/cpu/sam0_common/periph/rtt.c b/cpu/sam0_common/periph/rtt.c
index 3f7de9049..34f05e52f 100644
--- a/cpu/sam0_common/periph/rtt.c
+++ b/cpu/sam0_common/periph/rtt.c
@@ -98,7 +98,7 @@ void rtt_init(void)
     _wait_syncbusy();
 
     /* initially clear flag */
-    RTC->MODE0.INTFLAG.reg |= RTC_MODE0_INTFLAG_CMP0
+    RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0
                            |  RTC_MODE0_INTFLAG_OVF;
 
     NVIC_EnableIRQ(RTC_IRQn);
@@ -116,12 +116,12 @@ void rtt_set_overflow_cb(rtt_cb_t cb, void *arg)
     _overflow_arg = arg;
 
     /* enable overflow interrupt */
-    RTC->MODE0.INTENSET.bit.OVF = 1;
+    RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_OVF;
 }
 void rtt_clear_overflow_cb(void)
 {
     /* disable overflow interrupt */
-    RTC->MODE0.INTENCLR.bit.OVF = 1;
+    RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_OVF;
 }
 
 uint32_t rtt_get_counter(void)
@@ -158,14 +158,14 @@ void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
     _wait_syncbusy();
 
     /* enable compare interrupt and clear flag */
-    RTC->MODE0.INTFLAG.reg |= RTC_MODE0_INTFLAG_CMP0;
-    RTC->MODE0.INTENSET.reg |= RTC_MODE0_INTENSET_CMP0;
+    RTC->MODE0.INTFLAG.reg  = RTC_MODE0_INTFLAG_CMP0;
+    RTC->MODE0.INTENSET.reg = RTC_MODE0_INTENSET_CMP0;
 }
 
 void rtt_clear_alarm(void)
 {
     /* clear compare interrupt */
-    RTC->MODE0.INTENCLR.bit.CMP0 = 1;
+    RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
 }
 
 void rtt_poweron(void)

Tested on samr21-xpro and same54-xpro.

@kaspar030 kaspar030 added CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels Sep 10, 2019
@benpicco
Copy link
Contributor

Thank you! You can squash already.

And better call the commit cpu/sam0_common: rtt: correcly clear flags, I don't know what those ../ are supposed to mean.

Copy link
Contributor

@benpicco benpicco left a comment

Choose a reason for hiding this comment

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

Remedies the misguided use of those registers.

Tested both on samr21-xpro and same54-xpro with tests/periph_rtt.

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.

Nice cleanup !
One last change remaining and I will test on SAML21 and SAML1X tonight or tomorrow.

cpu/sam0_common/periph/rtt.c Outdated Show resolved Hide resolved
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
Tested against SAML10/SAML11/SAML21/SAME54 + arduino-zero (SAMD21) with tests/periph_rtt
@jcarrano thanks for the fixup. Squash & go !

The INTFLAGS register is cleared by writing a 1 to the corresponding interrupt
flag bit. From the samr21's manual:

> Writing a zero to this bit has no effect.
> Writing a one to this bit clears the Compare 0 interrupt flag.

This is a common pattern in flag registers.

This RTT driver is using or-equal to clear the flags, which means it can
possibly clear other interrupts. There's a small chance that one event is
missed if it happens very close to another event.

Credits to @benpicco, @dylad for pointing out missing fixes.
@benpicco benpicco merged commit c12b88e into RIOT-OS:master Sep 11, 2019
@kb2ma kb2ma added this to the Release 2019.10 milestone Sep 16, 2019
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 Area: timers Area: timer subsystems CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

sam0_common/periph/rtt: Interrupt flags are not correctly cleared
5 participants