PSoC6 GPIO Interrupt usage is slightly different with PSoC3/4/5. Both pin component and Global Signal component should be configured to use a PICU interrupt on PSoC6 Project. Please refer below code example to know how to use it in detail.
CE219521 – PSoC 6 MCU - GPIO Interrupt http://www.cypress.com/documentation/code-examples/ce219521-psoc-6-mcu-gpio-interrupt
Thank you for quick reply.
Let me ask you a few clarification questions:
- I want to use GlobalSignal component to handle an interrupt from a peripheral sensor - how I can assign a specific pin/port to which sensor is connected? I don't see how PICU[n] is translated into a specific pin.
- It seems interrupt doesn't support falling edge mode: I found only "auto-select trigger", "rising-edge triggered", "level triggered". Is there a way to use falling edge mode?
To your questions -
1) PSoC 6 (for that matter even PSoC 4) does not support pin specific interrupts. They support port specific interrupts. So you will need to figure out the IO that triggered the interrupt in the Port interrupt handler. If you want to check if a particular pin has triggered the interrupt, then use "Cy_GPIO_GetInterruptStatusMasked" API in the handler. If you want to check the interrupt status register in general, then directly read the "GPIO_PRTx->INTR_MASKED" register in the handler.
2)PSoC 6 GPIO supports - rising/falling/both edge interrupts. You can select the edge you want to trigger the Port interrupt by setting it in the "input" tab as shown below. You can also use "Cy_GPIO_SetInterruptEdge" in the code to set interrupt edge. In addition, you will need to call "Cy_GPIO_SetInterruptMask" in the code to enable the pin interrupt to the port.
Let me know if this helps.
Meenakshi Sundaram R
thank you for the comments.
1) By pin interrupt I meant "dedicated interrupt" option that was around in PSoC 4 with Digital Output/Bidirectional pin. With PSoC Creator 4.2
I don't see "dedicated interrupt" option in Digital pin component - and the picture that you shared doesn't have this checkbox next to Interrupt dropdown list neither.
2) Yes, I can see how Falling edge option can be set with Pin component but as I understood I cannot use Pin component with external interrupt in PSoC 6 - I was told here to use GlobalSignal component instead. But with GlobalSignal I'm facing 2 problems - how to get physical port name assigned to PICU[0..N] and its interrupt type has only next options: "auto-select trigger", "rising-edge triggered", "level triggered".
So, I guess the main question to me now - should I connect GlobalSignal component to some Pin component or GlobalSignal can be assigned to a certain physical port by itself?
The dedicated pin interrupt you are referring to in PSoC 4 was not really a dedicated interrupt for the pin. It usually maps the ISR component to the port's interrupt handler (you can easily test this by trying to use dedicated interrupt for two different pin components and trying to map them to the same port).
Now in PSoC 6 this option is removed and the GlobalSignalReference component provides the port interrupt signal (PICUn - Port Interrupt Controller Unit for Port n - Port n's interrupt). You can follow the below procedure for the GPIO interrupt configuration -
- Place a pin, configure the pin settings as per your need (You will need either Digital Input or Bidrectional type IO for generating the interrupt)
- In the "Input" sub-tab, select the "Interrupt" type as per your requirement - Rising/Falling/Both edges
- Place a GlobalSignalReference component and select the PICU[n] as the signal (e.g. PICU for Port 0). The GlobalSignal should be connected to an interrupt component (by default it is connected)
- Optionally you can check the "DeepSleep" capable checkbox in the SysInt component that get placed along with the GlobalSignal - this is not necessary but this will ensure your interrupt always gets placed on a DeepSleep capable vector for a particular CPU (useful for CM0+ mapping)
- The interrupt type in the SysInt component should be "Auto-Select" as this will automatically use the interrupt type selected in the Pin component.
- Build the project and in the main you can use Cy_GPIO_SetInterruptMask(GPIO_PRTn, GPIO_PIN, 1) to enable the pin interrupt (other pin related configuration is handled in cyfitter_cfg.c as part of system init)
- You can define an interrupt handler - this interrupt handler will be called for any pin interrupt that is enabled for interrupt generation in the port.
- You can call Cy_SysInt_Init() to initialize the interrupt and the NVIC_EnableIRQ to enable the interrupt
I am attaching a simple project illustrating the above steps and it works in the CY8CKIT-062-BLE (each SW2 press toggles the Green LED)
Note that you can also connect an interrupt component to the pin directly as shown below. But this will map the pin to a UDB based interrupt. Though the interrupt will be dedicated to the pin, it will not be deep sleep capable as UDB routing and interrupt detection logic is not available in deep sleep
Hope this helps.
Meenakshi Sundaram R
thanks a lot for such thorough response and instructions - I do appreciate it!
Now I think it makes things much more clear - let me ask you one clarification question to make sure I got it right:
In case of your test project if I'd need to setup interrupt handler for Pin 2 (which is P1) then new GlobalSignal instance(PICU) should be placed in schematics, right (because existing GlobalSignal_1 serves Port 0)?
Yes, that is correct. You need one GlobalSignalRef component for every port (not every pin) interrupt.
I see - again thanks a lot for your help!