Modified for BG96
Fork of mbed-dev by
Diff: targets/TARGET_STM/gpio_irq_api.c
- Revision:
- 187:0387e8f68319
- Parent:
- 170:19eb464bc2be
--- 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();