From d4b92da208ed41e72b07e0444a600c3e88b5ca88 Mon Sep 17 00:00:00 2001 From: Christian Mauderer Date: Tue, 15 Oct 2019 17:09:59 +0200 Subject: bsps/atsam: Improve case for level triggered IRQs. For level triggered interrupts currently the handler would have been called two times (assuming no one cleared the mask in a handler which would have been bad because the handler couldn't process all other that got cleared by accident). This patch allows the handler only to return if nothing is left to do. --- .../contrib/libraries/libchip/source/pio_it.c | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/bsps/arm/atsam/contrib/libraries/libchip/source/pio_it.c b/bsps/arm/atsam/contrib/libraries/libchip/source/pio_it.c index 2c619db136..f3745281dd 100644 --- a/bsps/arm/atsam/contrib/libraries/libchip/source/pio_it.c +++ b/bsps/arm/atsam/contrib/libraries/libchip/source/pio_it.c @@ -90,24 +90,28 @@ static uint32_t _dwNumSources = 0; static void PIO_Interrupt(Pio *pPio, uint32_t id) { uint32_t status; + uint32_t status_save; size_t i; - status = pPio->PIO_ISR; - status &= pPio->PIO_IMR; + do { + status = pPio->PIO_ISR; + status &= pPio->PIO_IMR; + status_save = status; - for (i = 0; status != 0 && i < MAX_INTERRUPT_SOURCES; ++i) { - const InterruptSource *is = &_aIntSources[i]; - const Pin *pin = is->pPin;; + for (i = 0; status != 0 && i < MAX_INTERRUPT_SOURCES; ++i) { + const InterruptSource *is = &_aIntSources[i]; + const Pin *pin = is->pPin;; - if (pin->id == id) { - uint32_t mask = pin->mask; + if (pin->id == id) { + uint32_t mask = pin->mask; - if ((status & mask) != 0) { - status &= ~mask; - (*is->handler)(pin, is->arg); + if ((status & mask) != 0) { + status &= ~mask; + (*is->handler)(pin, is->arg); + } } } - } + } while (status_save != 0); } /*---------------------------------------------------------------------------- -- cgit v1.2.3