cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 5, 3 & 1

wwfeldman
New Contributor II

i have four switches attached to 4 input pins with resistive pull ups in a CY8CKIT-059 PSoC 5LP

pressing a switch or releasing a switch causes an interrupt that saves the time according to a

fixed function counter, 16 bit (interrupt occurs on rising and falling edges)

the interrupt routine writes a variety of information to a character LCD display

including which pin (switch) was pushed or released, how many datum have been recorded,

and the recorded data

after programming or after reset (switch on kit-059) the display shows "release"

but "release" is written to the display only on a rising edge (switch release) interrupt

in addition, count start command (API) is supposed to happen on first switch activation (regardless of switch)

but it appears to start immediately

also, if one waits a while before pressing a switch, it is clear that the counter has counted (is not at max count)

hence it looks like the interrupt service routine is run once before any switches are pressed

why is that happening and what can i do about it?

archive bundle attached

0 Likes
1 Solution
wwfeldman
New Contributor II

to BoTa: I will look into ButtonSw32

to Noriaki Tanaka and Motoo Tanaka:

I tried your suggestions

I ended up with

isr_1_ClearPending();

InPin_ClearInterrupt(); 

isr_1_StartEx(PinISRHandler);

isr_1_ClearPending();  

removing any of the clear statements did not solve my issue

Ii appears I need all three

to Motoo Tanaka:

Thank you for the re-write. I will follow your suggestion

View solution in original post

0 Likes
4 Replies
odissey1
Honored Contributor II

LaAd,

I may suggest using an existing switch-button library, which handles button press and release events with debouncing

ButtonSw32: button switch debouncer component

/odissey1

ButtonSw_basic_1a.png

NoriakiT_91
Employee

Please try isr_1_ClearPending(); after isr_1_StartEx(PinISRHandler);

MotooTanaka
Esteemed Contributor

Hi,

I think that I'd like to call

     isr_1_ClearPending() ;

and

    InPin_ClearInterrupt();

before calling

     isr_1_StartEx(PinISRHandler) ;

But as far as they are before "CyGlobalIntEnable ;" it may be OK.

And also I'd like to place following lines before  "for (;;) " loop

================

        //Set up interrupt and set address as the ISR vector for the interrupt.

        isr_1_StartEx(PinISRHandler);

  

        CyGlobalIntEnable;

================

And (sorry for being too picky), I'd suggest you not to place

LCD_Position() and/or LCD_PrintString() inside ISR.

In the ISR, just set flags to notify the main (or foreground) task

to take care of such time consuming procedures.

So I tried to modify your main.c like below, may be I'm mis-understanding the logic though.

====================

/*******************************************************************************

* File Name: main.c

* Pandrol / Vortok USA

* 5688 Tec Drive

* Avon New York 14414

* L M Adelson

* July 2  2019

*

* Version: 1.0

*

* Description:

*  This project writes text to a 4x20 LCD display

*  The operating device is PSoC CY8CKIT-059

*  The processor is CY8C5888LTI-LP097

*  The operating LCD Display is a Crystalfontz America CFAH2004A-TMI-JT

*  The processor communcates to the LCD in parallel using a 4 bit interface

*  Two switches are operated via interrupt to change the display

*

*******************************************************************************/

#include <project.h>

/*******************************************************************************

* Function Name: main

********************************************************************************

*

* Summary:

*  The main program does the following

*  1. Initializes the LCD.

*  2. Writes text to each of 4 lines of display.

*  3. waits for interrupt from 4 inputs indicating a change of state

*     either a switch is pushed (pin goes low) or released (pin goes high)

*     don't know what order push / release will be

*     first push starts timer and records time

*     subsequent push or release cause time to be recorded in appropriate memory

*     after 8 data recorded, write all 8 dataum to LCD as:

*     push switch 1       release switch 4

*     push switch 2       release switch 4

*     push switch 3       release switch 4

*     push switch 4       release switch 4

*  CAVEAT: if you write more than 20 charaters, it does a cr lf lf

*  so the line continues with a skipped line

*  anything on that line gets overwritten

*

* Parameters:

*  None.

*

* Return:

*  None.

*

*******************************************************************************/

// initialize parameters        

   

uint8 pos = 0u;                  // column of LCD dispaly to wrtie in     

uint8 row = 0u;                  // row of LCD dispaly to wrtie in        

uint8 count = 0u;                // count how many times get an interrunpt 

uint8 pin_stat = 0u;             // read interrupt vector value (stat for status)           

uint8 last_pin_stat = 0u;        // pin status before present switch operation

uint8 change_pin_stat = 0u;      // changed in pin status - i.e. which switch                   

uint8 mode = 0u;                 // counter for how many interrupts seen   

int counts[20];                  // variable to store counts               

int num = 0;                     // temp variable                          

uint8 i;                         // index variable for loops               

uint8 press_release_flag = 0;    // 0 is false for release 1 is true for press

volatile int intr_flag = 0 ;        // <-- added

volatile int pin_changed_flag = 0 ; // <-- added

// interupt prototype delcaration

// PinISRHandler is routine when get pin interrupt

CY_ISR_PROTO(PinISRHandler); 

void report_mode(void) ;            // <-- added

int main()

{  

    LCD_Start() ;

   

    /* Clear pin Interrupt */

    InPin_ClearInterrupt();

   

    isr_1_ClearPending() ;

   

    //Set up interrupt and set address as the ISR vector for the interrupt.

    isr_1_StartEx(PinISRHandler) ;

   

    CyGlobalIntEnable;

   

    for(;;)

    {

        CyDelay(2000);              //pause

 

        mode = 0;

       

        {       

            while (mode < 😎          //mode specifies number of edges detected

            {}                        //start with 0, end after 4 switches or

                                      //at 8 transitions

       

            for (i = 0; i < 4; i++)   //clear screen

            {

                LCD_Position(i, 0);

                LCD_PrintString("                    ");

            }

   

            for (i = 0; i < 19; i++)

            {

                if (counts == 0) counts = 65535;

            }

           

            if (intr_flag) {

                intr_flag = 0 ;

                if (press_release_flag) {

                    LCD_Position(0, 0);

                    LCD_PrintString(" push     ");

                } else {

                    LCD_Position(0, 0);

                    LCD_PrintString(" release     ");

                }

                if (pin_changed_flag) {

                    pin_changed_flag = 0 ;

                    report_mode() ;

                }

            }

       

            //write output to LCD

            LCD_Position(0, 0);

            LCD_PrintU32Number(counts[1]);

            LCD_Position(0, 8);

            LCD_PrintU32Number(counts[11]);

   

            LCD_Position(1, 0);

            LCD_PrintU32Number(counts[2]);

            LCD_Position(1, 8);

            LCD_PrintU32Number(counts[12]);

   

            LCD_Position(2, 0);

            LCD_PrintU32Number(counts[4]);

            LCD_Position(2, 8);

            LCD_PrintU32Number(counts[14]);

       

            LCD_Position(3, 0);

            LCD_PrintU32Number(counts[8]);

            LCD_Position(3, 8);

            LCD_PrintU32Number(counts[18]);

   

            mode = 0;

            Counter_Stop();

            Counter_WriteCounter(0);   //reset to full count via rollover

        }

    }

   

}

/*******************************************************************************

* Function Name: PinISRHandler

********************************************************************************

*

* Summary:

*  This subroutine handles the interrupts

   1. Initializes the LCD.

*  2. Writes text to each of 4 lines of display.

*  CAVEAT: if you write more than 20 charaters, it does a cr lf lf

*  so the line continues with a skipped line

*  anything on that line gets overwritten

*

* Parameters:

*  None.

*

* Return:

*  None.

*

*******************************************************************************/

CY_ISR(PinISRHandler)

   

    num = Counter_ReadCounter();

    pin_stat = InPin_Read();

   

    if (mode == 0)

    {

        Counter_Start();

        last_pin_stat = 0;

    }

   

    if (pin_stat > last_pin_stat)

    {

        change_pin_stat = pin_stat - last_pin_stat;

        press_release_flag = 1;  // 0 is false for release 1 is true for press    

    }

    else

    {

        change_pin_stat = last_pin_stat - pin_stat;

        press_release_flag = 0;  // 0 is false for release 1 is true for press

    }

   

     /* Clear pending Interrupt */

    isr_1_ClearPending();

      

    /* Clear pin Interrupt */

    InPin_ClearInterrupt();

   

    /* what changed?      */

   

    if (press_release_flag)          //here for switch pushed // 0 is false for release 1 is true for press

    {

        counts[change_pin_stat] = num;

//        LCD_Position(0, 0);

//        LCD_PrintString(" push     ");

    }

    if (! press_release_flag)          //here for switch released // 0 is false for release 1 is true for press

    {

        counts[change_pin_stat + 10] = num;

//        LCD_Position(0, 0);

//        LCD_PrintString(" release     ");

    }

   

    if (last_pin_stat != pin_stat)            // take care of change condition

    {

        pin_changed_flag = 1 ;

/*

        LCD_Position(1, 0);

        LCD_PrintString("mode     ");

        LCD_PrintNumber(mode);

        LCD_PrintString("   ");

   

        LCD_PrintString("pin ");

        LCD_PrintNumber(pin_stat);

        LCD_PrintString(" ");

   

        LCD_Position(2,0);

        LCD_PrintString("last ");

        LCD_PrintNumber(last_pin_stat);

        LCD_PrintString("  ");

        LCD_PrintString("change ");

        LCD_PrintNumber(change_pin_stat);

        LCD_PrintString(" ");

      

        LCD_Position(3, 0);

        LCD_PrintString(" counts   ");

        LCD_PrintNumber(num);

        LCD_PrintString("   ");

*/   

        mode = mode + 1;

        last_pin_stat = pin_stat;

    }

      

    if (mode > 😎

    {

        Counter_Stop();

        Counter_Init();

    }

}

void report_mode(void)

{

    LCD_Position(1, 0);

    LCD_PrintString("mode     ");

    LCD_PrintNumber(mode);

    LCD_PrintString("   ");

   

    LCD_PrintString("pin ");

    LCD_PrintNumber(pin_stat);

    LCD_PrintString(" ");

   

    LCD_Position(2,0);

    LCD_PrintString("last ");

    LCD_PrintNumber(last_pin_stat);

    LCD_PrintString("  ");

    LCD_PrintString("change ");

    LCD_PrintNumber(change_pin_stat);

    LCD_PrintString(" ");

      

    LCD_Position(3, 0);

    LCD_PrintString(" counts   ");

    LCD_PrintNumber(num);

    LCD_PrintString("   ");

}

/* [] END OF FILE */

====================

moto

wwfeldman
New Contributor II

to BoTa: I will look into ButtonSw32

to Noriaki Tanaka and Motoo Tanaka:

I tried your suggestions

I ended up with

isr_1_ClearPending();

InPin_ClearInterrupt(); 

isr_1_StartEx(PinISRHandler);

isr_1_ClearPending();  

removing any of the clear statements did not solve my issue

Ii appears I need all three

to Motoo Tanaka:

Thank you for the re-write. I will follow your suggestion

View solution in original post

0 Likes