[rtems commit] bsps/atsam: Improve case for level triggered IRQs.

Christian Mauderer christianm at rtems.org
Wed Oct 23 08:43:15 UTC 2019


Module:    rtems
Branch:    master
Commit:    d4b92da208ed41e72b07e0444a600c3e88b5ca88
Changeset: http://git.rtems.org/rtems/commit/?id=d4b92da208ed41e72b07e0444a600c3e88b5ca88

Author:    Christian Mauderer <christian.mauderer at embedded-brains.de>
Date:      Tue Oct 15 17:09:59 2019 +0200

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 2c619db..f374528 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);
 }
 
 /*----------------------------------------------------------------------------



More information about the vc mailing list