[PATCH 1/3] bsps/atsam: Improve case for level triggered IRQs.

Christian Mauderer christian.mauderer at embedded-brains.de
Tue Oct 15 15:09:59 UTC 2019


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);
 }
 
 /*----------------------------------------------------------------------------
-- 
2.16.4



More information about the devel mailing list