@@ -61,12 +61,26 @@ static void handle_interrupt_in(uint8_t pin)
6161 return ;
6262 }
6363
64- // Get trigger event
64+ // trying to discern which GPIO IRQ we got
6565 gpio_irq_event event = IRQ_NONE ;
66- if (GPIO -> EXTIFALL & (1 << pin )) {
66+ if (((GPIO -> EXTIFALL & (1 << pin )) != 0 ) && ((GPIO -> EXTIRISE & (1 << pin )) == 0 )) {
67+ // Only the fall handler is active, so this must be a falling edge
6768 event = IRQ_FALL ;
68- } else if (GPIO -> EXTIRISE & (1 << pin )) {
69+ } else if (((GPIO -> EXTIFALL & (1 << pin )) == 0 ) && ((GPIO -> EXTIRISE & (1 << pin )) != 0 )) {
70+ // Only the rise handler is active, so this must be a rising edge
6971 event = IRQ_RISE ;
72+ } else {
73+ // Ambiguous as to which IRQ we've received. Poll the pin to check which one to fire.
74+ // NOTE: If trying to detect a pulse where the width is shorter than this handler's
75+ // reaction time, there will only be one callback (for the trailing edge) called.
76+
77+ // we are storing two ports in each uint8, so we must acquire the one we want.
78+ // If pin is odd, the port is encoded in the 4 most significant bits.
79+ // If pin is even, the port is encoded in the 4 least significant bits
80+ uint8_t isRise = GPIO_PinInGet ((pin & 0x1 ) ?
81+ channel_ports [(pin >>1 ) & 0x7 ] >> 4 & 0xF :
82+ channel_ports [(pin >>1 ) & 0x7 ] >> 0 & 0xF , pin );
83+ event = (isRise == 1 ? IRQ_RISE : IRQ_FALL );
7084 }
7185 GPIO_IntClear (pin );
7286 irq_handler (channel_ids [pin ], event );
@@ -132,9 +146,6 @@ void gpio_irq_set(gpio_irq_t *obj, gpio_irq_event event, uint32_t enable)
132146 /* Disable, set config and enable */
133147 gpio_irq_disable (obj );
134148
135- bool was_disabled = false;
136- if (GPIO -> IEN == 0 ) was_disabled = true;
137-
138149 GPIO_IntConfig ((GPIO_Port_TypeDef )((obj -> pin >> 4 ) & 0xF ), obj -> pin & 0xF , obj -> risingEdge , obj -> fallingEdge , obj -> risingEdge || obj -> fallingEdge );
139150}
140151
0 commit comments