This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Why do button interrupts stop working when I merge two working projects?

Other Parts Discussed in Thread: TM4C123GH6PM

Hello

I want to merge by button interrupt project with a "hello world" lcd example. It should be straight forward as neither program changes, just shares the same main method. Everything compiles fine and the LCD display works, but my button interrupts (which toggle the onboard LEDs) no longer work. I've tried this in both CCS and uVision4.

Even after I edit out all of the code associated with the LCD my buttons still do not work. 

Any advice?

//*****************************************************************************
//
// scribble.c - A simple scribble pad to demonstrate the touch screen driver.
//
//*****************************************************************************
#include <stdint.h>
#include <stdbool.h>

#include "inc/hw_types.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_memmap.h"
#include "driverlib/flash.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/rom.h"
#include "driverlib/pin_map.h"
#include "driverlib/interrupt.h"
#include "grlib/grlib.h"
#include "grlib/widget.h"
#include "utils/ringbuf.h"
#include "utils/ustdlib.h"
#include "inc/hw_gpio.h"

#include "inc/tm4c123gh6pm.h"
#include "drivers/Kentec320x240x16_ssd2119_8bit.h"
//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif

//*****************************************************************************
//
// The graphics context used by this application.
//
//*****************************************************************************
tContext g_sContext;



volatile unsigned long counter = 0;

void
PortFunctionInit(void)
{
    //
    // Enable Peripheral Clocks 
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);

    //
    // Enable pin PF2 for GPIOOutput
    //
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);

    //
    // Enable pin PF0 for GPIOInput
    //

    //
    //First open the lock and select the bits we want to modify in the GPIO commit register.
    //
    HWREG(GPIO_PORTF_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
    HWREG(GPIO_PORTF_BASE + GPIO_O_CR) = 0x1;

    //
    //Now modify the configuration of the pins that we unlocked.
    //
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_0);

    //
    // Enable pin PF4 for GPIOInput
    //
    GPIOPinTypeGPIOInput(GPIO_PORTF_BASE, GPIO_PIN_4);

    //
    // Enable pin PF1 for GPIOOutput
    //
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);
		
		//Enable pull-up on PF0 and PF4 (switch2 and switch1)
		GPIO_PORTF_PUR_R |= 0x11; // decimal 17 to turn on  
		//GPIO_PORTF_PUR_R |= 0x01; 
		
}

//////////////////////////////////////////////////
void
Interrupt_Init(void)
{
	
	
	IntEnable(INT_GPIOF);  							// enable interrupt 30 in NVIC (GPIOF)
	IntPrioritySet(INT_GPIOF, 0x00); 		// configure GPIOF interrupt priority as 0
	GPIO_PORTF_IM_R |= 0x11;   		// arm interrupt on PF0 and PF4
	GPIO_PORTF_IS_R &= ~0x11;     // PF0 and PF4 are edge-sensitive
  GPIO_PORTF_IBE_R &= ~0x11;   	// PF0 and PF4 not both edges trigger 
  GPIO_PORTF_IEV_R &= ~0x11;  	// PF0 and PF4 falling edge event
	IntMasterEnable();       		// globally enable interrupt
}
/////////////////////////////////////////////////////////


//interrupt handler
void GPIOPortF_Handler(void)
{
	
	
		
	
		//debounce
		IntDisable(INT_GPIOF);//disable inturrupt
		SysCtlDelay(53333333);//short delay
		IntEnable(INT_GPIOF);
	
		//SW1 is pressed (if flag recieved) 
		if(GPIO_PORTF_RIS_R&0x10 )
			{
				// acknowledge flag for PF4
				GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_4); 
				//counter incremented by 1
				counter=counter+1;
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x04); //blue on
			}
			
		//SW2 is pressed (if flag recieved) 
		if(GPIO_PORTF_RIS_R&0x01 )
			{
				// acknowledge flag for PF0
				GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_0); 
				//counter decremented by 1
				counter--;
GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x04); //blue on
			}
		
}

//////////////////////////////////////////




//*****************************************************************************
//
// Print "Hello World!" to the display on the Intelligent Display Module.
//
//*****************************************************************************
int
main(void)
{
    //tRectangle sRect;
		PortFunctionInit();
	Interrupt_Init();
    //
    // Set the clocking to run directly from the crystal.
 
	//
	
	/*
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
                   SYSCTL_XTAL_16MHZ);


    //
    // Initialize the display driver.
    //
    Kentec320x240x16_SSD2119Init();

    //
    // Initialize the graphics context.
    //
    GrContextInit(&g_sContext, &g_sKentec320x240x16_SSD2119);

    //
    // Fill the top 24 rows of the screen with blue to create the banner.
    //
    sRect.i16XMin = 0;
    sRect.i16YMin = 0;
    sRect.i16XMax = GrContextDpyWidthGet(&g_sContext) - 1;
    sRect.i16YMax = 23;
    GrContextForegroundSet(&g_sContext, ClrDarkBlue);
    GrRectFill(&g_sContext, &sRect);

    //
    // Put a white box around the banner.
    //
    GrContextForegroundSet(&g_sContext, ClrWhite);
    GrRectDraw(&g_sContext, &sRect);

    //
    // Put the application name in the middle of the banner.
    //
    GrContextFontSet(&g_sContext, &g_sFontCm20);
    GrStringDrawCentered(&g_sContext, "hello", -1,
                         GrContextDpyWidthGet(&g_sContext) / 2, 11, 0);

    //
    // Say hello using the Computer Modern 40 point font.
    //
    GrContextFontSet(&g_sContext, &g_sFontCm40);
    GrStringDrawCentered(&g_sContext, "Hello World!", -1,
                         GrContextDpyWidthGet(&g_sContext) / 2,
                         ((GrContextDpyHeightGet(&g_sContext) - 24) / 2) + 24,
                         0);

    //
    // The boot loader should take control, so this should never be reached.
    // Just in case, loop forever.
		
		*/
    //
    while(1)
    {
										//	GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x04); //blue on
				//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1,0x02); //red on
						if (counter==0)
			{
				
			
				GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x00); //blue off
				GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1,0x00); //red off
						
			}
			
			if (counter==1)
			{
								GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x00); //blue off
				GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1,0x02); //red on
			}
									
			if (counter==2)
			{
								GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x04); //blue on
				GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1,0x00); //red off
			}
												
			if (counter==3)
			{
								GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0x04); //blue on
				GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1,0x02); //red on
			}
			
			if (counter>3)
				
				counter=0; //counter reset
    }
}

  • Feel your pain - yet my firm uses IAR so I'm essentially blind to your specifics.

    That said - why not AVOID that "merge" - instead open (just) your working "button interrupt" program - and then gradually/systematically - adding one "Hello world" code line at a time - "paste in" - "Hello World."   After each line is added - test/verify to confirm that "buttons still work."

    I suspect that your "merge" proved the culprit - and the "KISS" method (suggested) enables your discovery of the EXACT line (or lines) which "blocks your path."

  • Hello Sergey,

    Have a closer look at the functions being called and what they are doing with the defines passed to them. You should pay special attention to the bit packing within the bytes that are sent to the functions to insure other bits are not being overwritten such that initializations are undone or bit values inappropriately changed.

    In general, my advice would be to go back to your working code and look for differences or start with your original code and incrementally add back the LCD project until you see an issue. I am assuming that when you did the merge, hello world was still being displayed on the LCD prior to removing the LCD related code? Is this a correct assumption?

    Also, it would be helpful if you could provide details of which board you are using for your project along with any other details that might be relevant such as which IDE, compiler, etc.
  • Chuck,

    Great idea, seems obvious now!

    The function at fault is Kentec320x240x16_SSD2119Init(); The display driver initializer.

    I'm using the Tiva C TM4C123GH6PM board with keil uVision 4
  • Great success! I've edited the driver and now no problems! Thanks!
  • Did you mean "Chuck" or (really) the earlier - more direct responding "cb1?" (the sole advocate here for KISS)

    Either way - glad you succeeded - and surely my quick, precise guide assisted.
  • You're right, sorry about that.
  • Thank you for your quick correction (Verify) - appreciated.

    Both Chuck & I agreed that you're smart enough to solve such issues. By thinking KISS you'll be far ahead of the game...