M487KM can't clear GPIO Interrupt Flag

60 Views Asked by At

I want to turn ON LEDs with the help of buttons on my Nuvoton M487KM board. I have given a print function to see which button is clicked and then turn ON the respective LED. The LED does turn on but in the terminal, I see that the button is pressed multiple times.

Here is the code: (main.c)


#include <stdio.h>
#include "NuMicro.h"
#include "gpio.h"

void  BTN_Init(void);
void LED_Init(void);
void SYS_Init(void);
void delay(void);

volatile int delayFinished = 0;

#define GPIO_GET_INT_FLAG(port, u32PinMask)     ((port)->INTSRC & (u32PinMask))

#define PLL_CLOCK           192000000

#define LED_RED                 PH4
#define LED_GREEN               PH5

#define SW1                   PF11
#define SW2                   PG15



/*---------------------------------------------------------------------------------------------------------*/
/* Initialize System                                                                                       */
/*---------------------------------------------------------------------------------------------------------*/
void SYS_Init(void)
{
    /* Set XT1_OUT(PF.2) and XT1_IN(PF.3) to input mode */
    PF->MODE &= ~(GPIO_MODE_MODE2_Msk | GPIO_MODE_MODE3_Msk);

    /* Enable External XTAL (4~24 MHz) */
    CLK_EnableXtalRC(CLK_PWRCTL_HXTEN_Msk);

    /* Waiting for 12MHz clock ready */
    CLK_WaitClockReady(CLK_STATUS_HXTSTB_Msk);

    /* Set core clock as PLL_CLOCK from PLL */
    CLK_SetCoreClock(PLL_CLOCK);
    /* Set PCLK0/PCLK1 to HCLK/2 */
    CLK->PCLKDIV = (CLK_PCLKDIV_APB0DIV_DIV2 | CLK_PCLKDIV_APB1DIV_DIV2);

    /* Enable UART clock */
    CLK_EnableModuleClock(UART0_MODULE);
    //CLK_EnableModuleClock(UART1_MODULE);

    /* Select UART clock source from HXT */
    //CLK_SetModuleClock(UART0_MODULE, CLK_CLKSEL1_UART0SEL_HXT, CLK_CLKDIV0_UART0(1));
    /* Select UART clock source from HXT */
    CLK->CLKSEL1 = (CLK->CLKSEL1 & ~CLK_CLKSEL1_UART0SEL_Msk) | (0x0 << CLK_CLKSEL1_UART0SEL_Pos);


    /* Set GPB multi-function pins for UART0 RXD and TXD */
    SYS->GPB_MFPH &= ~(SYS_GPB_MFPH_PB12MFP_Msk | SYS_GPB_MFPH_PB13MFP_Msk);
    SYS->GPB_MFPH |= (SYS_GPB_MFPH_PB12MFP_UART0_RXD | SYS_GPB_MFPH_PB13MFP_UART0_TXD);

    /* Update System Core Clock */
    /* User can use SystemCoreClockUpdate() to calculate SystemCoreClock. */
    SystemCoreClockUpdate();
}


/*---------------------------------------------------------------------------------------------------------*/
/* Programmable Interrupt Timer Initialize                                                                                    */
/*---------------------------------------------------------------------------------------------------------*/
void PIT_Init(void)
{
    CLK_EnableModuleClock(TMR0_MODULE);
    TIMER_Open(TIMER0, TIMER_PERIODIC_MODE, 1);
    TIMER_EnableInt(TIMER0);
    NVIC_EnableIRQ(TMR0_IRQn);

    TIMER_Start(TIMER0);
}

void TMR0_IRQHandler(void)
{
    TIMER_ClearIntFlag(TIMER0);
    delayFinished = 1;
}

void delay(void)
{
    delayFinished = 0;
    while(!delayFinished)
    {
    }
}


/*---------------------------------------------------------------------------------------------------------*/
/* Button Initialize                                                                                       */
/*---------------------------------------------------------------------------------------------------------*/

void  BTN_Init(void)
{
    /*      Set GPIO pins as i/p Mode       */
    GPIO_SetMode(PG, BIT15, GPIO_MODE_INPUT);  //1`bu
    GPIO_EnableInt(PG, 15, GPIO_INT_FALLING);
    NVIC_EnableIRQ(GPG_IRQn);

    //GPIO_CLR_INT_FLAG(PG, BIT15);
    //NVIC_SetPriority(GPG_IRQn, 1);

    GPIO_SetMode(PF, BIT11,GPIO_MODE_INPUT);
    GPIO_EnableInt(PF, 11, GPIO_INT_FALLING);
    NVIC_EnableIRQ(GPF_IRQn);

    //GPIO_CLR_INT_FLAG(PF, BIT11);
    //NVIC_SetPriority(GPF_IRQn, 3);
    //sw3=0;
}



/*---------------------------------------------------------------------------------------------------------*/
/* LED Initialize                                                                                          */
/*---------------------------------------------------------------------------------------------------------*/
void LED_Init(void)
{
    /*      Set LED pins as output Mode     */
    GPIO_SetMode(PH,(BIT4| BIT5 ),GPIO_MODE_OUTPUT);

}


/*---------------------------------------------------------------------------------------------------------*/
/* ISR for SW1                                                                                             */
/*---------------------------------------------------------------------------------------------------------*/
void Button1_ISR(void)
{
        printf("\n First Button");
        /*      Turn RED LED ON     */
        LED_RED     = 0;
        LED_GREEN   = 1;
}


/*---------------------------------------------------------------------------------------------------------*/
/* Interrupt Handler PF                                                                                    */
/*---------------------------------------------------------------------------------------------------------*/
void GPF_IRQHandler(void)
{
    if (GPIO_GET_INT_FLAG(PF, BIT11))
    {
        GPIO_CLR_INT_FLAG(PF, BIT11);
        //LED_RED       = 0;
        //LED_GREEN = 1;
        //printf("I am in");
    }

    else
    {
        GPIO_CLR_INT_FLAG(PF, BIT11);
        printf("Un-expected Interrupt");
    }
}


/*---------------------------------------------------------------------------------------------------------*/
/* ISR for SW2                                                                                             */
/*---------------------------------------------------------------------------------------------------------*/
void Button2_ISR(void)
{
    if(SW2==0)
    {
        printf("\n Second Button");
        /*      Turn GREEN LED ON       */
        LED_RED     = 1;
        LED_GREEN   = 0;
    }
}



/*---------------------------------------------------------------------------------------------------------*/
/* Interrupt Handler PG                                                                                    */
/*---------------------------------------------------------------------------------------------------------*/
void GPG_IRQHandler(void)
{
    if (GPIO_GET_INT_FLAG(PG, BIT15))
    {
        GPIO_CLR_INT_FLAG(PG, BIT15);
        Button2_ISR();
    }
    else
    {
        GPIO_CLR_INT_FLAG(PG, BIT15);
        printf("Un-expected Interrupt");
    }
}



/*---------------------------------------------------------------------------------------------------------*/
/* Main Program                                                                                            */
/*---------------------------------------------------------------------------------------------------------*/
void main(void)
{
    /*      Unlock Protected Registers      */
    SYS_UnlockReg();

    /*      Start System        */
    SYS_Init();

    /*      PIT Start       */
    PIT_Init();

    /*      Start Button        */
    BTN_Init();

    /*      Start LEDs      */
    LED_Init();

    /*      Open UART if need serial Communication      */
    UART_Open(UART0, 115200);

    while(1)
    {
        printf("\n EMS");
        delay();
    }
}

The Output I get:

EMS
EMS
EMS
Second Button
Second Button
Second Button
Second Button
Second Button
EMS
EMS
EMS
First Button
First Button
EMS
Second Button
Second Button
Second Button
Second Button
Second Button
Second Button
Second Button
Second Button
Second Button

I tried clearing it before calling the interrupt, no change. I tried Rising Edge and Falling Edge but same result. (Rising Edge was worst.) I tried Disabling Interrupt Mode to see if that clears the flag, at first it did, but when I enable the interrupt again it falls back in the same loop. If I press and hold the button, it only prints once. Is my clearing method wrong? Is my entire method for calling Interrupt wrong? Can it be a timer flag issue? Is it possible that the button itself is misbehaving?

0

There are 0 best solutions below