diff --git a/cpu/cc2538/periph/gpio.c b/cpu/cc2538/periph/gpio.c index 95cf7ae18b..9356205390 100644 --- a/cpu/cc2538/periph/gpio.c +++ b/cpu/cc2538/periph/gpio.c @@ -213,10 +213,20 @@ static inline void handle_isr(uint8_t port_num) port->IC = 0x000000ff; port->IRQ_DETECT_ACK = (0xff << (port_num * GPIO_BITS_PER_PORT)); - for (int i = 0; i < GPIO_BITS_PER_PORT; i++) { - if (state & (1 << i)) { - isr_ctx[port_num][i].cb(isr_ctx[port_num][i].arg); - } + /* If only one bit it is set in state (one GPIO pin caused an interrupt), + * don't loop over all 8 bits. + * + * Use clz to get the position of the first interrupt bit and clear it, + * looping only as many times as there are actual interrupts. + */ + + /* mask all non-GPIO bits */ + state &= (1 << GPIO_BITS_PER_PORT) - 1; + while (state) { + /* we want the position of the first one bit, so N_bits - (N_zeros + 1) */ + int pin = 32 - __builtin_clz(state) - 1; + state &= ~(1 << pin); + isr_ctx[port_num][pin].cb(isr_ctx[port_num][pin].arg); } cortexm_isr_end();