Question: How do you detect multiple GPIO interrupts from different GPIO pins in PSoC® 1?
The interrupt logic of a GPIO cell is shown in Figure 1. The PRTxICx registers set the type of interrupt (disabled, high, low, and change from last read). The corresponding PRTxIE bit enables or disables the interrupt for the GPIO. When the interrupt is enabled in the PRTxIE register and if the interrupt condition as configured by PRTxICx occurs on the GPIO pin, then the IRQ# line is asserted.
Figure 1. PSoC 1 GPIO Interrupt Logic
The IRQ# lines from all the GPIO cells are tied together. This creates a wired OR setup for the active LOW IRQ signal. The IRQ signal is considered edge-sensitive for asserting and level-sensitive for releasing the interrupt—that is, the interrupt controller registers a GPIO interrupt when a falling edge is detected on the IRQ line, but will not register any interrupts until the IRQ line goes back to a HIGH state. This creates problems in detecting multiple interrupts occurring simultaneously.
For example, consider the scenario shown in Figure 2.
Figure 2. Scenario 1
GPIO#1 is configured for high-level interrupt whereas GPIO#2 is configured for low-level interrupt. When GPIO#1 goes high, the IRQ line is asserted and the interrupt controller posts an interrupt. While GPIO#1 is high asserting the IRQ line, GPIO#2 too goes low asserting the IRQ signal, and goes high de-asserting it before GPIO#1 de-asserts the IRQ. As no change is registered on the IRQ line, the interrupt from GPIO#2 is not registered by the interrupt controller.
Now consider another scenario shown in Figure 3.
Figure 3. Scenario 2
In this case, GPIO#1 asserts the IRQ line. Before it de-asserts the IRQ line, GPIO#2 also asserts the IRQ line. GPIO#2 continues to assert the IRQ line even after GPIO#1 de-asserts. As there is no state change on the IRQ line, the interrupt controller does not register this interrupt as well.
These scenarios can be avoided by using the following techniques.
Apart from the above techniques, if you have free digital blocks or analog blocks left, then you can also route the GPIO pin to a digital buffer and enable the interrupt of that digital block, or connect the GPIO to a comparator and enable the interrupt of the comparator bus. This will provide dedicated interrupt vectors to the GPIOs.