cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC™ 6

CaKu_4284131
Contributor II

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:

pastedImage_0.png

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?

0 Likes
1 Solution
MotooTanaka
Esteemed Contributor

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

000-schematic.JPG

pins

001-pins.JPG

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

View solution in original post

0 Likes
7 Replies
CaKu_4284131
Contributor II

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>

0 Likes
MotooTanaka
Esteemed Contributor

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

000-schematic.JPG

pins

001-pins.JPG

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

View solution in original post

0 Likes
CaKu_4284131
Contributor II

Motoo-san,

That looks very good. Thanks!

-Carl

On Wed, Apr 8, 2020 at 7:58 PM Motoo Tanaka <community-manager@cypress.com>

CaKu_4284131
Contributor II

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:

pastedImage_4.png

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.

* GitHub - carlk3/FreeRTOS-FAT-CLI-for-PSoC-63

0 Likes
MotooTanaka
Esteemed Contributor

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

CaKu_4284131
Contributor II

Motoo-san,

Brilliant! That works.

  -Carl

Top labels