- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm trying to use a Status Register to debounce a switch, which is wired to a GPIO. I'd like to get an interrupt when the status changes.
Here is what I've tried:
I made an ISR declared like this:
void card_detect_ISR();
and tried to hook it up like this:
Cy_SysInt_Init(&Card_Detect_Interrupt_cfg, card_detect_ISR);
NVIC_ClearPendingIRQ(Card_Detect_Interrupt_cfg->intrSrc);
NVIC_EnableIRQ(Card_Detect_Interrupt_cfg->intrSrc);
Card_Detect_Status_InterruptEnable() ;
but card_detect_ISR() doesn't get called.
This was all a guess. How is this supposed to work? Is there a code sample somewhere that illustrates this?
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Carl-san,
I also tried a similar circuit with yours using CY8CKIT-062-BLE.
In my case, I could trigger the interrupt, but I could not figure out how to clear it.
I tested only SW2... worked OK.
I tested the value of the Status Register... I could not make it work as I expected.
So I took another approach, hand-crafted debounce! (lol)
Note: This is a circuit I teach in a university FPGA design course,
and it has been working well for last 12 years 😉
schematic
pins
main.c
===============
#include "project.h"
#define LED_ON (0u)
#define LED_OFF (1u)
volatile int card_detect_flag = 0 ;
void card_detect_ISR(void)
{
/* Clears the triggered pin interrupt */
NVIC_ClearPendingIRQ(Card_Detect_Interrupt_cfg.intrSrc);
card_detect_flag = 1 ;
}
void init_hardware(void)
{
Cy_SysInt_Init(&Card_Detect_Interrupt_cfg, card_detect_ISR);
NVIC_ClearPendingIRQ(Card_Detect_Interrupt_cfg.intrSrc);
NVIC_EnableIRQ(Card_Detect_Interrupt_cfg.intrSrc);
}
int main(void)
{
int flag = LED_OFF ;
__enable_irq(); /* Enable global interrupts. */
/* Enable CM4. CY_CORTEX_M4_APPL_ADDR must be updated if CM4 memory layout is changed. */
// Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR);
init_hardware() ;
for(;;)
{
if (card_detect_flag) {
card_detect_flag = 0 ;
if (flag == LED_OFF) {
flag = LED_ON ;
Cy_GPIO_Write(LED_G_PORT, LED_G_NUM, LED_ON) ;
} else {
flag = LED_OFF ;
Cy_GPIO_Write(LED_G_PORT, LED_G_NUM, LED_OFF) ;
}
}
}
}
===============
Best Regards,
9-Apr-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
How about trying CE219521 - PSoC 6 MCU - GPIO Interrupt?
https://www.cypress.com/documentation/code-examples/ce219521-psoc-6-mcu-gpio-interrupt
PSoC Creator
https://www.cypress.com/file/385796/download
https://www.cypress.com/file/386176/download
ModusToolbox
https://www.cypress.com/file/455466/download
https://www.cypress.com/file/455471/download
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi moto-
I did try that, first. It does work, but the switch doesn't make or break
cleanly and the interrupt fires multiple times. I got the idea to use a
Status Register from CE223727 EmWin EInk Display, but that example doesn't
use an interrupt; it simply loops:
void WaitforSwitchPressAndRelease(void)
{
/* Wait for SW2 to be pressed */
while(Status_SW2_Read() != 0);
/* Wait for SW2 to be released */
while(Status_SW2_Read() == 0);
}
-Carl
On Wed, Apr 8, 2020 at 4:54 PM Motoo Tanaka <community-manager@cypress.com>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear Carl-san,
I also tried a similar circuit with yours using CY8CKIT-062-BLE.
In my case, I could trigger the interrupt, but I could not figure out how to clear it.
I tested only SW2... worked OK.
I tested the value of the Status Register... I could not make it work as I expected.
So I took another approach, hand-crafted debounce! (lol)
Note: This is a circuit I teach in a university FPGA design course,
and it has been working well for last 12 years 😉
schematic
pins
main.c
===============
#include "project.h"
#define LED_ON (0u)
#define LED_OFF (1u)
volatile int card_detect_flag = 0 ;
void card_detect_ISR(void)
{
/* Clears the triggered pin interrupt */
NVIC_ClearPendingIRQ(Card_Detect_Interrupt_cfg.intrSrc);
card_detect_flag = 1 ;
}
void init_hardware(void)
{
Cy_SysInt_Init(&Card_Detect_Interrupt_cfg, card_detect_ISR);
NVIC_ClearPendingIRQ(Card_Detect_Interrupt_cfg.intrSrc);
NVIC_EnableIRQ(Card_Detect_Interrupt_cfg.intrSrc);
}
int main(void)
{
int flag = LED_OFF ;
__enable_irq(); /* Enable global interrupts. */
/* Enable CM4. CY_CORTEX_M4_APPL_ADDR must be updated if CM4 memory layout is changed. */
// Cy_SysEnableCM4(CY_CORTEX_M4_APPL_ADDR);
init_hardware() ;
for(;;)
{
if (card_detect_flag) {
card_detect_flag = 0 ;
if (flag == LED_OFF) {
flag = LED_ON ;
Cy_GPIO_Write(LED_G_PORT, LED_G_NUM, LED_ON) ;
} else {
flag = LED_OFF ;
Cy_GPIO_Write(LED_G_PORT, LED_G_NUM, LED_OFF) ;
}
}
}
}
===============
Best Regards,
9-Apr-2020
Motoo Tanaka
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Motoo-san,
That looks very good. Thanks!
-Carl
On Wed, Apr 8, 2020 at 7:58 PM Motoo Tanaka <community-manager@cypress.com>
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I integrated this into my project*, and had a hard time getting it working. Through a lot of trial and error, I narrowed it down to this:
In FreeRTOSConfig.h:
#define configUSE_IDLE_HOOK 1
In main_cm4.c:
void vApplicationIdleHook(void)
{
/* Enter sleep-mode */
Cy_SysPm_Sleep(CY_SYSPM_WAIT_FOR_INTERRUPT);
}
(Obviously, this is a FreeRTOS project.) I got that from code sample CE220331 BLE_UI_RTOS.
I've got a couple other interrupts in my project:
and they seem to work fine with the Cy_SysPm_Sleep. But, for some reason, Interrupt Number 122 doesn't wake up the CM4. I really don't understand why.
Anyway, everything works well if I turn off configUSE_IDLE_HOOK.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I wonder if UDB, which is clocked by IMO (HF CLK) to CLK_Peri to Clock_1. is working during the sleep mode.
May be you need to provide another interrupt directly triggered from the GPIO to wake up from low power mode.
And enable that interrupt before entering sleep mode then disable it after wake-up.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Motoo-san,
Brilliant! That works.
-Carl