Skip to content
Snippets Groups Projects
Commit dfa342b5 authored by Joakim Nohlgård's avatar Joakim Nohlgård
Browse files

cpu/samd21: Avoid clearing interrupt bits unintentionally

The INTENSET, INTENCLR, INTFLAG registers are write-1-to-confirm
registers, so writing zeroes will not affect anything, on the other
hand, a compiler generated read-modify-write cycle may unintentionally
affect more bits than the one being set. Avoid by using direct
assignment instead of or-assignment (|=) or bitfield writes (.bit.xxx=).
parent 719515a0
No related branches found
No related tags found
No related merge requests found
...@@ -142,14 +142,14 @@ int timer_set_absolute(tim_t dev, int channel, unsigned int value) ...@@ -142,14 +142,14 @@ int timer_set_absolute(tim_t dev, int channel, unsigned int value)
/* set timeout value */ /* set timeout value */
switch (channel) { switch (channel) {
case 0: case 0:
TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC0; TIMER_0_DEV.INTFLAG.reg = TC_INTFLAG_MC0;
TIMER_0_DEV.CC[0].reg = value; TIMER_0_DEV.CC[0].reg = value;
TIMER_0_DEV.INTENSET.bit.MC0 = 1; TIMER_0_DEV.INTENSET.reg = TC_INTENSET_MC0;
break; break;
case 1: case 1:
TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC1; TIMER_0_DEV.INTFLAG.reg = TC_INTFLAG_MC1;
TIMER_0_DEV.CC[1].reg = value; TIMER_0_DEV.CC[1].reg = value;
TIMER_0_DEV.INTENSET.bit.MC1 = 1; TIMER_0_DEV.INTENSET.reg = TC_INTENSET_MC1;
break; break;
default: default:
return -1; return -1;
...@@ -161,14 +161,14 @@ int timer_set_absolute(tim_t dev, int channel, unsigned int value) ...@@ -161,14 +161,14 @@ int timer_set_absolute(tim_t dev, int channel, unsigned int value)
/* set timeout value */ /* set timeout value */
switch (channel) { switch (channel) {
case 0: case 0:
TIMER_1_DEV.INTFLAG.reg |= TC_INTFLAG_MC0; TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC0;
TIMER_1_DEV.CC[0].reg = value; TIMER_1_DEV.CC[0].reg = value;
TIMER_1_DEV.INTENSET.bit.MC0 = 1; TIMER_1_DEV.INTENSET.reg = TC_INTENSET_MC0;
break; break;
case 1: case 1:
TIMER_1_DEV.INTFLAG.reg |= TC_INTFLAG_MC1; TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC1;
TIMER_1_DEV.CC[1].reg = value; TIMER_1_DEV.CC[1].reg = value;
TIMER_1_DEV.INTENSET.bit.MC1 = 1; TIMER_1_DEV.INTENSET.reg = TC_INTENSET_MC1;
break; break;
default: default:
return -1; return -1;
...@@ -191,12 +191,12 @@ int timer_clear(tim_t dev, int channel) ...@@ -191,12 +191,12 @@ int timer_clear(tim_t dev, int channel)
case TIMER_0: case TIMER_0:
switch (channel) { switch (channel) {
case 0: case 0:
TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC0; TIMER_0_DEV.INTFLAG.reg = TC_INTFLAG_MC0;
TIMER_0_DEV.INTENCLR.bit.MC0 = 1; TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0;
break; break;
case 1: case 1:
TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC1; TIMER_0_DEV.INTFLAG.reg = TC_INTFLAG_MC1;
TIMER_0_DEV.INTENCLR.bit.MC1 = 1; TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1;
break; break;
default: default:
return -1; return -1;
...@@ -207,12 +207,12 @@ int timer_clear(tim_t dev, int channel) ...@@ -207,12 +207,12 @@ int timer_clear(tim_t dev, int channel)
case TIMER_1: case TIMER_1:
switch (channel) { switch (channel) {
case 0: case 0:
TIMER_1_DEV.INTFLAG.reg |= TC_INTFLAG_MC0; TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC0;
TIMER_1_DEV.INTENCLR.bit.MC0 = 1; TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC0;
break; break;
case 1: case 1:
TIMER_1_DEV.INTFLAG.reg |= TC_INTFLAG_MC1; TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC1;
TIMER_1_DEV.INTENCLR.bit.MC1 = 1; TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC1;
break; break;
default: default:
return -1; return -1;
...@@ -309,16 +309,16 @@ static inline void _irq_enable(tim_t dev) ...@@ -309,16 +309,16 @@ static inline void _irq_enable(tim_t dev)
void TIMER_0_ISR(void) void TIMER_0_ISR(void)
{ {
if (TIMER_0_DEV.INTFLAG.bit.MC0 && TIMER_0_DEV.INTENSET.bit.MC0) { if (TIMER_0_DEV.INTFLAG.bit.MC0 && TIMER_0_DEV.INTENSET.bit.MC0) {
TIMER_0_DEV.INTFLAG.reg = TC_INTFLAG_MC0;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0;
if(config[TIMER_0].cb) { if(config[TIMER_0].cb) {
TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC0;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC0;
config[TIMER_0].cb(config[TIMER_0].arg, 0); config[TIMER_0].cb(config[TIMER_0].arg, 0);
} }
} }
else if (TIMER_0_DEV.INTFLAG.bit.MC1 && TIMER_0_DEV.INTENSET.bit.MC1) { if (TIMER_0_DEV.INTFLAG.bit.MC1 && TIMER_0_DEV.INTENSET.bit.MC1) {
TIMER_0_DEV.INTFLAG.reg = TC_INTFLAG_MC1;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1;
if(config[TIMER_0].cb) { if(config[TIMER_0].cb) {
TIMER_0_DEV.INTFLAG.reg |= TC_INTFLAG_MC1;
TIMER_0_DEV.INTENCLR.reg = TC_INTENCLR_MC1;
config[TIMER_0].cb(config[TIMER_0].arg, 1); config[TIMER_0].cb(config[TIMER_0].arg, 1);
} }
} }
...@@ -332,16 +332,16 @@ void TIMER_0_ISR(void) ...@@ -332,16 +332,16 @@ void TIMER_0_ISR(void)
void TIMER_1_ISR(void) void TIMER_1_ISR(void)
{ {
if (TIMER_1_DEV.INTFLAG.bit.MC0 && TIMER_1_DEV.INTENSET.bit.MC0) { if (TIMER_1_DEV.INTFLAG.bit.MC0 && TIMER_1_DEV.INTENSET.bit.MC0) {
TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC0;
TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC0;
if (config[TIMER_1].cb) { if (config[TIMER_1].cb) {
TIMER_1_DEV.INTFLAG.reg |= TC_INTFLAG_MC0;
TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC0;
config[TIMER_1].cb(config[TIMER_1].arg, 0); config[TIMER_1].cb(config[TIMER_1].arg, 0);
} }
} }
else if (TIMER_1_DEV.INTFLAG.bit.MC1 && TIMER_1_DEV.INTENSET.bit.MC1) { if (TIMER_1_DEV.INTFLAG.bit.MC1 && TIMER_1_DEV.INTENSET.bit.MC1) {
TIMER_1_DEV.INTFLAG.reg = TC_INTFLAG_MC1;
TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC1;
if(config[TIMER_1].cb) { if(config[TIMER_1].cb) {
TIMER_1_DEV.INTFLAG.reg |= TC_INTFLAG_MC1;
TIMER_1_DEV.INTENCLR.reg = TC_INTENCLR_MC1;
config[TIMER_1].cb(config[TIMER_1].arg, 1); config[TIMER_1].cb(config[TIMER_1].arg, 1);
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment