cpu/sam0_common: rtt: correcly clear flags.
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.
This commit is contained in:
parent
741d5437a7
commit
f7279c84bb
@ -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)
|
||||
@ -189,16 +189,16 @@ void rtt_poweroff(void)
|
||||
void isr_rtc(void)
|
||||
{
|
||||
if (RTC->MODE0.INTFLAG.bit.OVF) {
|
||||
RTC->MODE0.INTFLAG.reg |= RTC_MODE0_INTFLAG_OVF;
|
||||
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_OVF;
|
||||
if (_overflow_cb) {
|
||||
_overflow_cb(_overflow_arg);
|
||||
}
|
||||
}
|
||||
if (RTC->MODE0.INTFLAG.bit.CMP0) {
|
||||
/* clear flag */
|
||||
RTC->MODE0.INTFLAG.reg |= RTC_MODE0_INTFLAG_CMP0;
|
||||
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
|
||||
/* disable interrupt */
|
||||
RTC->MODE0.INTENCLR.bit.CMP0 = 1;
|
||||
RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
|
||||
if (_cmp0_cb) {
|
||||
_cmp0_cb(_cmp0_arg);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user