summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Mauderer <christian.mauderer@embedded-brains.de>2019-10-15 17:09:59 +0200
committerChristian Mauderer <christian.mauderer@embedded-brains.de>2019-10-23 10:41:34 +0200
commitd4b92da208ed41e72b07e0444a600c3e88b5ca88 (patch)
treee8d1ffdb743c5b95d5f0a8936b9cf55b98a71295
parentriscv: add freedom E310 Arty A7 bsp (diff)
downloadrtems-d4b92da208ed41e72b07e0444a600c3e88b5ca88.tar.bz2
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.
-rw-r--r--bsps/arm/atsam/contrib/libraries/libchip/source/pio_it.c26
1 files 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);
}
/*----------------------------------------------------------------------------