mbed library sources. Supersedes mbed-src.

Dependents:   Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more

Revision:
187:0387e8f68319
Parent:
170:19eb464bc2be
Child:
188:bcfe06ba3d64
--- a/targets/TARGET_STM/gpio_irq_api.c	Fri Jun 22 16:45:37 2018 +0100
+++ b/targets/TARGET_STM/gpio_irq_api.c	Thu Sep 06 13:40:20 2018 +0100
@@ -43,7 +43,7 @@
 typedef struct gpio_channel {
     uint32_t pin_mask;                   // bitmask representing which pins are configured for receiving interrupts
     uint32_t channel_ids[MAX_PIN_LINE];  // mbed "gpio_irq_t gpio_irq" field of instance
-    GPIO_TypeDef* channel_gpio[MAX_PIN_LINE]; // base address of gpio port group
+    GPIO_TypeDef *channel_gpio[MAX_PIN_LINE]; // base address of gpio port group
     uint32_t channel_pin[MAX_PIN_LINE];  // pin number in port group
 } gpio_channel_t;
 
@@ -94,12 +94,30 @@
                     continue;
                 }
 
-                // Check which edge has generated the irq
-                if ((gpio->IDR & pin) == 0) {
-                    irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_FALL);
+                // Trying to discern which edge caused the IRQ
+                gpio_irq_event event = IRQ_NONE;
+                if (LL_EXTI_IsEnabledFallingTrig_0_31(pin) && !LL_EXTI_IsEnabledRisingTrig_0_31(pin)) {
+                    // Only the fall handler is active, so this must be a falling edge
+                    event = IRQ_FALL;
+                } else if (LL_EXTI_IsEnabledRisingTrig_0_31(pin) && !LL_EXTI_IsEnabledFallingTrig_0_31(pin)) {
+                    // Only the rise handler is active, so this must be a rising edge
+                    event = IRQ_RISE;
                 } else {
-                    irq_handler(gpio_channel->channel_ids[gpio_idx], IRQ_RISE);
+                    // Ambiguous as to which edge caused the IRQ
+                    //
+                    // The state of the pin could/should indicate which edge
+                    // has occurred but this can go wrong if the IRQ caused a
+                    // transition from a low power mode. In some circumstances
+                    // only the trailing edge callback will be called.
+                    if ((gpio->IDR & pin) == 0) {
+                        event = IRQ_FALL;
+                    } else {
+                        event = IRQ_RISE;
+                    }
                 }
+
+                irq_handler(gpio_channel->channel_ids[gpio_idx], event);
+
                 return;
             }
         }
@@ -168,7 +186,9 @@
     gpio_channel_t *gpio_channel;
     uint32_t gpio_idx;
 
-    if (pin == NC) return -1;
+    if (pin == NC) {
+        return -1;
+    }
 
     /* Enable SYSCFG Clock */
     __HAL_RCC_SYSCFG_CLK_ENABLE();