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.

Tm4c129 - Interrupt Button

Other Parts Discussed in Thread: ENERGIA

Hi,


I wrote a short programm to light a led when I press the User 1 button, the logic "seem" right but the led isn't lighting up. What I got wrong?

#include <stdbool.h>
#include <stdint.h>
#include "inc/tm4c129xnczad.h"
#include "inc/hw_memmap.h"
#include "inc/hw_nvic.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"


void button_press(void){
    GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, GPIO_PIN_1);
	SysCtlDelay(10000);
	GPIOPinWrite(GPIO_PORTN_BASE, GPIO_PIN_1, 0);
    SysCtlDelay(10000);
    GPIOIntClear(GPIO_PORTJ_BASE,GPIO_INT_PIN_0);
}

int main(void) {
	//clock init
	SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);

	//button clock GPIO init
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
	while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOJ)));

	//led clock GPIO init
	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
	while(!(SysCtlPeripheralReady(SYSCTL_PERIPH_GPION)));

	//Led init
    GPIOPinTypeGPIOOutput(GPIO_PORTN_BASE,GPIO_PIN_1);
    //button init
	GPIOPinTypeGPIOInput(GPIO_PORTJ_BASE,GPIO_PIN_0);
	
	//interrupt set-up
	GPIOIntTypeSet(GPIO_PORTJ_BASE,GPIO_PIN_0,GPIO_FALLING_EDGE);
	GPIOIntRegister(GPIO_PORTJ_BASE,button_press);
	GPIOIntEnable(GPIO_PORTJ_BASE,GPIO_INT_PIN_0);


	//loop for ever waiting for the button to be pressed.
	while(1){

	}

}

I got questions upon the choice of Int Type. In the dev kit datasheet. the button USR 1 is connected to ground so it is logical to check for Falling_Edge right? Also I am not sure about the interrupt function(the interrupt function is correctly written in the interrup vector table), such delay aren"t too long?

  • Hello Mathieu,

    To detect a falling edge the signal has to be high. You would need to first enable the Pull Up of the GPIO.

    Also you would need to enable the interrupt in the NVIC using IntEnable(INT_GPIOJ) for the interrupt to be processed by the NVIC in the CPU.

    Regards
    Amit
  • Hi,

    but doesn`t

    GPIOIntRegister(GPIO_PORTJ_BASE,button_press);
    GPIOIntEnable(GPIO_PORTJ_BASE,GPIO_INT_PIN_0);

    enable the interrupt?
  • Hi,
    I only added the line
    GPIOPadConfigSet(GPIO_PORTJ_BASE,GPIO_PIN_0,GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);
    and it worked
    IntEnable(INT_GPIOJ) seem to be not necessary because it worked with out the line.
  • Mathieu L. said:
    GPIOPadConfigSet(GPIO_PORTJ_BASE,GPIO_PIN_0,GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD_WPU);



    The 4th parameter configures the pin to have a weak pull up like Amit said hence why it worked.

    Amit also suggested IntEnable() because it is needed (but there is more to it, read on)! You always need to enable the interrupt this way but... when you use GPIOIntRegister() (and others similar like TimerIntRegister() ) it simply calls with correct parameters IntRegister() (from the NVIC part of the API) and IntEnable() <- this is why your code still worked.
    Just wanted to explain this part :)

  • Hello Luis,

    An important thing to note is that when the IntRegister API are called the interrupt vector table is located to SRAM. Does the user want to lose 2K of precious SRAM!!!

    Regards
    Amit
  • Yea, it has that too, thanks for the addition Amit.

    But when I make my own APIs that use interrupts I always have to use it unfortunately... if there was already default names for each vector ISR I would not need to use IntRegister (suggestion). Or else I need to remember to edit also the startup and when I adapt them to work under energia that is not possible (so I always need to use IntRegister)
  • It appears that "energia" does so "little" - yet demands so "much!"
    Poster - and even the talented Luis - may wish to follow Amit's great guidance & "gain back" their "precious" Ram.
    May we note that poster's "Self Awarded" Verify will surely "bite him" - sooner rather than later. Rejecting Amit's guidance is never good - trading a "so limited & temporary" fix - for an established, safe one - makes NO sense!
  • "It appears that "energia" does so "little" - yet demands so "much!" "
    So true... -.-
    But it's a high school that uses it so it's ok for me (now when it's above that Energia/Arduino is the only way... ).

    Lately I have tried to keep all the RAM but now I keep forgetting to add the ISR names to the vector table :p
  • Luis Afonso said:
    I keep forgetting to add the ISR names to the vector table

    And won't your faulting program very well "signal" that forgetfulness?

    Bad habits are not quick/easy to break/replace.   Yet - dreaded, "ram-shrink" (inflicting an already limited resource) may just provide the needed motivation...

    (self-awarded "verifies" should exist only in Ram - so that they "die" when power is removed...)   (and poster has returned to his/her senses)

  • Luis Afonso said:
    if there was already default names for each vector ISR I would not need to use IntRegister (suggestion). Or else I need to remember to edit also the startup and when I adapt them to work under energia that is not possible (so I always need to use IntRegister)

    Luis Afonso said:
    Lately I have tried to keep all the RAM but now I keep forgetting to add the ISR names to the vector table :p

    It pays to know what your tools (and standard professional tools) are capable of.

    A standard linker will be able to define 'weak symbols', the terminology will differ but the concept is the same from vendor to vendor.

    The interrupt table is filled with standard names for each interrupt function.  These are either defined separately as functions or aliased to a single standard default function (the latter probably being preferable). These symbols are defined as weak meaning they are tentative placeholders used only if no other definitions are available.

    The actual interrupt functions are defined in your program using the same names. These are normal or strong definitions

    When the program is linked the strong symbols replace the weak (with no error) so you end up with a default routine for any interrupt you have not replaced and your replacement (with a standard name) for any that you define.

    Hand holding can be comforting when you start to walk but as soon as you have to step off of the paved path you are likely to find you need both hands free.

    Robert

  • Again, "Knocked out of the Park!" (I need 9 more "IDs" to properly "Like" that one!)

    Your "wrap up" sentence says it all - in an especially memorable & compelling manner.    Simply inspired - Happy 4th (should that apply!)

  • You talk about GPIOintRegister function?
  • Hello Mathieu

    Yes. IntRegister is the generic function from the interrupt.c which is called by the driverlib

    Regards
    Amit
  • Thank you kindly.

    Robert

    Had our fireworks last night (for the occasion formerly known as Dominion Day)
  • Robert Adsett said:
    Had our fireworks last night

    In our beloved mid-west "big city" we (almost) can hear the fireworks!   (when not drowned out by gunfire, giant trucks, trains or 747s on final...)

    I can (just) recall Maurice, "Le Rocket" beating the brains out of our (past) beloved NY Rangers...   Again - great job...