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.

Stellaris LaunchPad LM4F120 code

Hi,

I've just started learning the Stellaris LM4F120 LaunchPad. I cannot find information about how to generate an interrupt when a GPIO pin goes high. I have the following code:

main.c:

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
int PinData=8;

int main(void)
{
SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);

GPIOPinTypeGPIOInput(GPIO_PORTC_BASE, GPIO_PIN_7);

GPIOPinTypeGPIOInput(GPIO_PORTC_BASE,GPIO_PIN_7);
GPIOIntTypeSet(GPIO_PORTC_BASE,GPIO_PIN_7,GPIO_FALLING_EDGE);
GPIOPinIntEnable(GPIO_PORTC_BASE,GPIO_PIN_7);
IntMasterEnable();

}
void IntGPIOCHandler (void)
{
GPIOPinIntClear(GPIO_PORTC_BASE,GPIO_PIN_7);
}

startup_css.c

//*****************************************************************************
//
// startup_ccs.c - Startup code for use with TI's Code Composer Studio.
//
// Copyright (c) 2012 Texas Instruments Incorporated. All rights reserved.
// TI Information - Selective Disclosure
//
//*****************************************************************************

//*****************************************************************************
//
// Forward declaration of the default fault handlers.
//
//*****************************************************************************
void ResetISR(void);
static void NmiSR(void);
static void FaultISR(void);
static void IntDefaultHandler(void);

//*****************************************************************************
//
// External declaration for the reset handler that is to be called when the
// processor is started
//
//*****************************************************************************
extern void _c_int00(void);
extern void GPIOCIntHandler(void);

//*****************************************************************************
//
// Linker variable that marks the top of the stack.
//
//*****************************************************************************
extern unsigned long __STACK_TOP;

//*****************************************************************************
//
// The vector table. Note that the proper constructs must be placed on this to
// ensure that it ends up at physical address 0x0000.0000 or at the start of
// the program if located at a start address other than 0.
//
//*****************************************************************************
#pragma DATA_SECTION(g_pfnVectors, ".intvecs")
void (* const g_pfnVectors[])(void) =
{
(void (*)(void))((unsigned long)&__STACK_TOP),
// The initial stack pointer
ResetISR, // The reset handler
NmiSR, // The NMI handler
FaultISR, // The hard fault handler
IntDefaultHandler, // The MPU fault handler
IntDefaultHandler, // The bus fault handler
IntDefaultHandler, // The usage fault handler
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
IntDefaultHandler, // SVCall handler
IntDefaultHandler, // Debug monitor handler
0, // Reserved
IntDefaultHandler, // The PendSV handler
IntDefaultHandler, // The SysTick handler
IntDefaultHandler, // GPIO Port A
IntDefaultHandler, // GPIO Port B
GPIOCIntHandler, // GPIO Port C
IntDefaultHandler, // GPIO Port D
IntDefaultHandler, // GPIO Port E
IntDefaultHandler, // UART0 Rx and Tx
IntDefaultHandler, // UART1 Rx and Tx
IntDefaultHandler, // SSI0 Rx and Tx
IntDefaultHandler, // I2C0 Master and Slave
IntDefaultHandler, // PWM Fault
IntDefaultHandler, // PWM Generator 0
IntDefaultHandler, // PWM Generator 1
IntDefaultHandler, // PWM Generator 2
IntDefaultHandler, // Quadrature Encoder 0
IntDefaultHandler, // ADC Sequence 0
IntDefaultHandler, // ADC Sequence 1
IntDefaultHandler, // ADC Sequence 2
IntDefaultHandler, // ADC Sequence 3
IntDefaultHandler, // Watchdog timer
IntDefaultHandler, // Timer 0 subtimer A
IntDefaultHandler, // Timer 0 subtimer B
IntDefaultHandler, // Timer 1 subtimer A
IntDefaultHandler, // Timer 1 subtimer B
IntDefaultHandler, // Timer 2 subtimer A
IntDefaultHandler, // Timer 2 subtimer B
IntDefaultHandler, // Analog Comparator 0
IntDefaultHandler, // Analog Comparator 1
IntDefaultHandler, // Analog Comparator 2
IntDefaultHandler, // System Control (PLL, OSC, BO)
IntDefaultHandler, // FLASH Control
IntDefaultHandler, // GPIO Port F
IntDefaultHandler, // GPIO Port G
IntDefaultHandler, // GPIO Port H
IntDefaultHandler, // UART2 Rx and Tx
IntDefaultHandler, // SSI1 Rx and Tx
IntDefaultHandler, // Timer 3 subtimer A
IntDefaultHandler, // Timer 3 subtimer B
IntDefaultHandler, // I2C1 Master and Slave
IntDefaultHandler, // Quadrature Encoder 1
IntDefaultHandler, // CAN0
IntDefaultHandler, // CAN1
IntDefaultHandler, // CAN2
IntDefaultHandler, // Ethernet
IntDefaultHandler, // Hibernate
IntDefaultHandler, // USB0
IntDefaultHandler, // PWM Generator 3
IntDefaultHandler, // uDMA Software Transfer
IntDefaultHandler, // uDMA Error
IntDefaultHandler, // ADC1 Sequence 0
IntDefaultHandler, // ADC1 Sequence 1
IntDefaultHandler, // ADC1 Sequence 2
IntDefaultHandler, // ADC1 Sequence 3
IntDefaultHandler, // I2S0
IntDefaultHandler, // External Bus Interface 0
IntDefaultHandler, // GPIO Port J
IntDefaultHandler, // GPIO Port K
IntDefaultHandler, // GPIO Port L
IntDefaultHandler, // SSI2 Rx and Tx
IntDefaultHandler, // SSI3 Rx and Tx
IntDefaultHandler, // UART3 Rx and Tx
IntDefaultHandler, // UART4 Rx and Tx
IntDefaultHandler, // UART5 Rx and Tx
IntDefaultHandler, // UART6 Rx and Tx
IntDefaultHandler, // UART7 Rx and Tx
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
IntDefaultHandler, // I2C2 Master and Slave
IntDefaultHandler, // I2C3 Master and Slave
IntDefaultHandler, // Timer 4 subtimer A
IntDefaultHandler, // Timer 4 subtimer B
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
0, // Reserved
IntDefaultHandler, // Timer 5 subtimer A
IntDefaultHandler, // Timer 5 subtimer B
IntDefaultHandler, // Wide Timer 0 subtimer A
IntDefaultHandler, // Wide Timer 0 subtimer B
IntDefaultHandler, // Wide Timer 1 subtimer A
IntDefaultHandler, // Wide Timer 1 subtimer B
IntDefaultHandler, // Wide Timer 2 subtimer A
IntDefaultHandler, // Wide Timer 2 subtimer B
IntDefaultHandler, // Wide Timer 3 subtimer A
IntDefaultHandler, // Wide Timer 3 subtimer B
IntDefaultHandler, // Wide Timer 4 subtimer A
IntDefaultHandler, // Wide Timer 4 subtimer B
IntDefaultHandler, // Wide Timer 5 subtimer A
IntDefaultHandler, // Wide Timer 5 subtimer B
IntDefaultHandler, // FPU
IntDefaultHandler, // PECI 0
IntDefaultHandler, // LPC 0
IntDefaultHandler, // I2C4 Master and Slave
IntDefaultHandler, // I2C5 Master and Slave
IntDefaultHandler, // GPIO Port M
IntDefaultHandler, // GPIO Port N
IntDefaultHandler, // Quadrature Encoder 2
IntDefaultHandler, // Fan 0
0, // Reserved
IntDefaultHandler, // GPIO Port P (Summary or P0)
IntDefaultHandler, // GPIO Port P1
IntDefaultHandler, // GPIO Port P2
IntDefaultHandler, // GPIO Port P3
IntDefaultHandler, // GPIO Port P4
IntDefaultHandler, // GPIO Port P5
IntDefaultHandler, // GPIO Port P6
IntDefaultHandler, // GPIO Port P7
IntDefaultHandler, // GPIO Port Q (Summary or Q0)
IntDefaultHandler, // GPIO Port Q1
IntDefaultHandler, // GPIO Port Q2
IntDefaultHandler, // GPIO Port Q3
IntDefaultHandler, // GPIO Port Q4
IntDefaultHandler, // GPIO Port Q5
IntDefaultHandler, // GPIO Port Q6
IntDefaultHandler, // GPIO Port Q7
IntDefaultHandler, // GPIO Port R
IntDefaultHandler, // GPIO Port S
IntDefaultHandler, // PWM 1 Generator 0
IntDefaultHandler, // PWM 1 Generator 1
IntDefaultHandler, // PWM 1 Generator 2
IntDefaultHandler, // PWM 1 Generator 3
IntDefaultHandler // PWM 1 Fault
};

//*****************************************************************************
//
// This is the code that gets called when the processor first starts execution
// following a reset event. Only the absolutely necessary set is performed,
// after which the application supplied entry() routine is called. Any fancy
// actions (such as making decisions based on the reset cause register, and
// resetting the bits in that register) are left solely in the hands of the
// application.
//
//*****************************************************************************
void
ResetISR(void)
{
//
// Jump to the CCS C initialization routine. This will enable the
// floating-point unit as well, so that does not need to be done here.
//
__asm(" .global _c_int00\n"
" b.w _c_int00");
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives a NMI. This
// simply enters an infinite loop, preserving the system state for examination
// by a debugger.
//
//*****************************************************************************
static void
NmiSR(void)
{
//
// Enter an infinite loop.
//
while(1)
{
}
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives a fault
// interrupt. This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void
FaultISR(void)
{
//
// Enter an infinite loop.
//
while(1)
{
}
}

//*****************************************************************************
//
// This is the code that gets called when the processor receives an unexpected
// interrupt. This simply enters an infinite loop, preserving the system state
// for examination by a debugger.
//
//*****************************************************************************
static void
IntDefaultHandler(void)
{
//
// Go into an infinite loop.
//
while(1)
{
}
}

I get the following errors:

Description Resource Path Location Type
#10010 errors encountered during linking; "Lab4.out" not built Lab4 C/C++ Problem

Description Resource Path Location Type
<a href="file:/C:/ti/ccsv5/tools/compiler/dmed/HTML/10234.html">#10234-D</a> unresolved symbols remain Lab4 C/C++ Problem

Description Resource Path Location Type
unresolved symbol GPIOCIntHandler, first referenced in ./startup_ccs.obj Lab4 C/C++ Problem

I need some help with this.

Thank you,

Ioana

  • Hi,

    Ioana Oprescu said:
    I cannot find information about how to generate an interrupt when a GPIO pin goes high. I have the following code:

    See, GPIOIntTypeSet(), at Peripheral Driver Library User's Guide. What are you connecting to PC7 as trigger source? switch? 

    Ioana Oprescu said:
    Description Resource Path Location Type
    unresolved symbol GPIOCIntHandler, first referenced in ./startup_ccs.obj Lab4 C/C++ Problem

    typo error? 

    extern void GPIOCIntHandler(void);

    void IntGPIOCHandler (void)

    -kel

  • Ioana Oprescu said:
    how to generate an interrupt when a GPIO pin goes high

    Yet code shows, "GPIOIntTypeSet(GPIO_PORTC_BASE,GPIO_PIN_7,GPIO_FALLING_EDGE);"

    Does not your expressed goal (interrupt upon a "high") conflict w/your, "Falling_Edge" parameter?

    Driverlib file gpio.h reveals:

    // Values that can be passed to GPIOIntTypeSet as the ulIntType parameter, and returned from GPIOIntTypeGet.
    //
    //*****************************************************************************
    #define GPIO_FALLING_EDGE       0x00000000  // Interrupt on falling edge
    #define GPIO_RISING_EDGE        0x00000004  // Interrupt on rising edge
    #define GPIO_BOTH_EDGES         0x00000001  // Interrupt on both edges
    #define GPIO_LOW_LEVEL          0x00000002  // Interrupt on low level
    #define GPIO_HIGH_LEVEL         0x00000007  // Interrupt on high level
    #define GPIO_DISCRETE_INT       0x00010000  // Interrupt for individual pins

    Suspect the highlighted parameter better suits your goal - provided you seek a, "level" rather than "edge" type trigger.

    These are complex devices - demand great attention to detail - answers abound - require time/effort to navigate/digest...

  • I would be tempted to use GPIO_RISING_EDGE instead so that you detect the pin going high (as requested in the original post) and don't end up with an interrupt asserted constantly while the pin is high. Also, you shouldn't need to call GPIOPinTypeGPIOInput() twice back-to-back. The choice of edge vs. level depends very much upon the hardware you have tied to that GPIO line, though.

  • Don't believe poster has provided the necessary detail to know for sure if interrupt favors level or edge.  The level interrupt is more certain to trigger - and indeed may assert too frequently - if safeguards are not emplaced.  My experience teaches that "obtaining" the interrupt is the "usual" - best first order of business.  (too easy for one "new" to "miss" a brief, pulse created interrupt)

    No matter - level or edge - that input pin must be, "held low" (usually by pull-down R or external signal) for any interrupt on "high" to properly function.

    And - always be mindful that any use of Port C (by a relatively new user) places JTAG in jeopardy.  My preference is to "steer" towards safer Port.  (ha!) 

  • Thank you for your answer!

     

    I haven't connected anything yet because the code doesn't compile and I cannot load it to the processor. My goal is to connect a sensor to it so that the interrupt does something when the sensor detects. But right now I am trying to write basic code to make a GPIO interrupt work and expand it later. I've checked all the possible ways one can type the GPIOCIntHandler and none of them works, I get these errors

  • I will change FALLING_EDGE to HIGH_LEVEL but at the moment I am trying to figure out where the error is coming from. It seems that I cannot find the proper name for something like GPIOCIntHandler

  • In your code you define a function called IntGPIOCHandler but in your startup file, it's looking for something called GPIOCIntHandler . If you make sure all these places agree, I bet you'll find that everything starts working nicely.

  • Thank you very much!

     

    I've made these changes and it works!

  • Hi,

        From my first reply, I gave you the hint, that error was caused by a typographical error or wrong naming.

    -kel

  • did you make your goal? i mean you said "My goal is to connect a sensor to it so that the interrupt does something when the sensor detects". did you code that sensor? I'm also working on this.