mbed library sources

Dependents:   frdm_kl05z_gpio_test

Fork of mbed-src by mbed official

Revision:
254:181b5e179739
Parent:
251:de9a1e4ffd79
Child:
285:31249416b6f9
--- a/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/gpio_irq_api.c	Wed Jul 09 11:00:08 2014 +0100
+++ b/targets/hal/TARGET_Freescale/TARGET_KLXX/TARGET_KL46Z/gpio_irq_api.c	Thu Jul 10 09:00:09 2014 +0100
@@ -30,45 +30,51 @@
 #define IRQ_FALLING_EDGE    PORT_PCR_IRQC(10)
 #define IRQ_EITHER_EDGE     PORT_PCR_IRQC(11)
 
+const uint32_t search_bits[] = {0x0000FFFF, 0x000000FF, 0x0000000F, 0x00000003, 0x00000001};
+
 static void handle_interrupt_in(PORT_Type *port, int ch_base) {
-    uint32_t mask = 0, i;
+    uint32_t isfr;
+    uint8_t location;
 
-    for (i = 0; i < 32; i++) {
-        uint32_t pmask = (1 << i);
-        if (port->ISFR & pmask) {
-            mask |= pmask;
-            uint32_t id = channel_ids[ch_base + i];
-            if (id == 0) {
-                continue;
-            }
-
-            FGPIO_Type *gpio;
-            gpio_irq_event event = IRQ_NONE;
-            switch (port->PCR[i] & PORT_PCR_IRQC_MASK) {
-                case IRQ_RAISING_EDGE:
-                    event = IRQ_RISE;
-                    break;
+    while((isfr = port->ISFR) != 0) {
+        location = 0;
+        for (int i = 0; i < 5; i++) {
+            if (!(isfr & (search_bits[i] << location)))
+                location += 1 << (4 - i);
+        }
+        
+        uint32_t id = channel_ids[ch_base + location];
+        if (id == 0) {
+            continue;
+        }
 
-                case IRQ_FALLING_EDGE:
-                    event = IRQ_FALL;
-                    break;
+        FGPIO_Type *gpio;
+        gpio_irq_event event = IRQ_NONE;
+        switch (port->PCR[location] & PORT_PCR_IRQC_MASK) {
+            case IRQ_RAISING_EDGE:
+                event = IRQ_RISE;
+                break;
+
+            case IRQ_FALLING_EDGE:
+                event = IRQ_FALL;
+                break;
 
-                case IRQ_EITHER_EDGE:
-                    if (port == PORTA) {
-                        gpio = FPTA;
-                    } else if (port == PORTC) {
-                        gpio = FPTC;
-                    } else {
-                        gpio = FPTD;
-                    }
-                    event = (gpio->PDIR & pmask) ? (IRQ_RISE) : (IRQ_FALL);
-                    break;
-            }
-            if (event != IRQ_NONE)
-                irq_handler(id, event);
+            case IRQ_EITHER_EDGE:
+                if (port == PORTA) {
+                    gpio = FPTA;
+                } else if (port == PORTC) {
+                    gpio = FPTC;
+                } else {
+                    gpio = FPTD;
+                }
+                event = (gpio->PDIR & (1<<location)) ? (IRQ_RISE) : (IRQ_FALL);
+                break;
         }
+        if (event != IRQ_NONE) {
+            irq_handler(id, event);
+        }
+        port->ISFR = 1 << location;
     }
-    port->ISFR = mask;
 }
 
 void gpio_irqA(void) {