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.

GPIO Interrupt Problem when Debuging with BeagleboneBlack

Hello;

I have built a simple program using the gpioLEDBlink and gpioCardDetect StarterWare examples. I want to test the GPIO Interrupts. My idea consists of switching on a LED when a GPIO port detects an input (1) and switching it off when there is no input (0). I have included some printf to know where is the program. When I debug, my problem is that the GPIO Interrupt does not happen or that when it happes it does not enter into the GPIOIsr Interrupt sub-routine.

I am working with CCS v5 and with a Beaglebone Black, running my example into he CortxA8. My debugg device is a Texas Instruments XDS100v2 USB Emulator. I have make sure that the options "when assembly stepping, source stepping and running" are not enabled so that the interrupts are not disabled. Also, I have deselected "Automatically step over functions without debug information when source stepping". However, I keeps on not working.

How can I make it work? Is that a code problem or a CCS v5 problem?

Here I attach my code program.

/**
 * \file   gpioLEDBlink.c
 *
 *  \brief  This application uses a GPIO pin to blink the LED.
 *
 *          Application Configurations:
 *
 *              Modules Used:
 *                  GPIO1
 *
 *              Configuration Parameters:
 *                  None
 *
 *          Application Use Case:
 *              1) The GPIO pin GPIO1[23] is used as an output pin.
 *              2) This pin is alternately driven HIGH and LOW. A finite delay
 *                 is given to retain the pin in its current state.
 *
 *          Running the example:
 *              On running the example, the LED on beaglebone would be seen
 *              turning ON and OFF alternatively.
 *
 */

/*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
*/
/*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*    Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/


#include "soc_AM335x.h"
#include "evmAM335x.h"
#include "interrupt.h"
#include "gpio_v2.h"
#include "delay.h"

#include "pin_mux.h"

/*****************************************************************************
**                INTERNAL MACRO DEFINITIONS
*****************************************************************************/
#define GPIO_INSTANCE_ADDRESS         (SOC_GPIO_1_REGS)
#define GPIO_INSTANCE_PIN_NUMBER      (24)


#define GPIO_INSTANCE_ADDRESS_0       (SOC_GPIO_0_REGS)
#define GPIO_CD_PIN_NUM               (27)
#define GPIO_INST_SYS_INT_NUM         (SYS_INT_GPIOINT0A)

/*****************************************************************************
**                INTERNAL FUNCTION PROTOTYPES
*****************************************************************************/
static void Delay1(unsigned int count);
static void GPIOINTCConfigure(void);
static void CheckCardStatus(void);
static void GPIOIsr(void);

/*****************************************************************************
**                     INTERNAL VARIABLE DEFINITIONS
*****************************************************************************/
static volatile unsigned int gpioIsrFlag = 0;

/*****************************************************************************
**                INTERNAL FUNCTION DEFINITIONS
*****************************************************************************/
/*
** The main function. Application starts here.
*/
int main()
{
    /* INICIALIZACIÓN GPIO1 - LED */


	/* Enabling functional clocks for GPIO1 instance. */
    GPIO1ModuleClkConfig();

    /* Selecting GPIO1[23] pin for use. */
    GPIO1Pin23PinMuxSetup();

    /* Enabling the GPIO module. */
    GPIOModuleEnable(GPIO_INSTANCE_ADDRESS);

    /* Resetting the GPIO module. */
    GPIOModuleReset(GPIO_INSTANCE_ADDRESS);

    /* Setting the GPIO pin as an output pin. */
    GPIODirModeSet(GPIO_INSTANCE_ADDRESS, GPIO_INSTANCE_PIN_NUMBER, GPIO_DIR_OUTPUT);


    GPIOPinWrite(GPIO_INSTANCE_ADDRESS, GPIO_INSTANCE_PIN_NUMBER, GPIO_PIN_HIGH);
    Delay1(0x3FFFF);
    Delay1(0x3FFFF);
    GPIOPinWrite(GPIO_INSTANCE_ADDRESS, GPIO_INSTANCE_PIN_NUMBER, GPIO_PIN_LOW);

    /* INICIALIZACIÓN GPIO0 - DETECCIÓN */

    /* This function enables the functional clocks for the GPIO1 instance. */
    GPIO0ModuleClkConfig();

    /* Perform Pin Multiplexing for the pin GPIO0[6]. */
    GPIO_PMUX_OFFADDR_VALUE(0, 27, PAD_FS_RXE_PU_PUPDE(7));

    /* Enable the GPIO Module. */
    GPIOModuleEnable(GPIO_INSTANCE_ADDRESS_0);

    /* Perform a reset of the GPIO Module. */
    GPIOModuleReset(GPIO_INSTANCE_ADDRESS_0);

    /* Configure the Card Detection Pin as an Input Pin. */
    GPIODirModeSet(GPIO_INSTANCE_ADDRESS_0, GPIO_CD_PIN_NUM, GPIO_DIR_INPUT);

    /* Enable Debouncing feature for the Intput GPIO Pin. */
    GPIODebounceFuncControl(GPIO_INSTANCE_ADDRESS_0, GPIO_CD_PIN_NUM, GPIO_DEBOUNCE_FUNC_ENABLE);

    /* Configure the Debouncing Time for all the input pins of the seleceted GPIO instance. */
    GPIODebounceTimeConfig(GPIO_INSTANCE_ADDRESS_0, 48);

    /* Configure the INTC to receive GPIO Interrupts. */
    GPIOINTCConfigure();

    /* Disable interrupt generation on detection of a logic HIGH or LOW levels. */
    GPIOIntTypeSet(GPIO_INSTANCE_ADDRESS_0, GPIO_CD_PIN_NUM, GPIO_INT_TYPE_NO_LEVEL);

    /* Enable interrupt generation on detection of a rising or a falling edge. */
    GPIOIntTypeSet(GPIO_INSTANCE_ADDRESS_0, GPIO_CD_PIN_NUM, GPIO_INT_TYPE_BOTH_EDGE);

    /* Enable interrupt for the specified GPIO Input Pin. */
    GPIOPinIntEnable(GPIO_INSTANCE_ADDRESS_0, GPIO_INT_LINE_1, GPIO_CD_PIN_NUM);

    /* Clear the Interrupt Status of the GPIO Card Detect pin. */
    //GPIOPinIntClear(GPIO_INSTANCE_ADDRESS_0, GPIO_INT_LINE_1, GPIO_CD_PIN_NUM);

    while(1)
    {

    	/* Read the data on the GPIO Card Detect Pin. */
		if(GPIOPinRead(GPIO_INSTANCE_ADDRESS_0, GPIO_CD_PIN_NUM))
		{
			/* Drive a logic LOW on the GPIO Pin controlling the LED. */
			GPIOPinWrite(GPIO_INSTANCE_ADDRESS, GPIO_INSTANCE_PIN_NUMBER, GPIO_PIN_HIGH);
			printf("Connected.\n");

		}
		else
		{
			/* Drive a logic HIGH on the GPIO Pin controlling the LED. */
			GPIOPinWrite(GPIO_INSTANCE_ADDRESS, GPIO_INSTANCE_PIN_NUMBER, GPIO_PIN_LOW);
			printf("Disconnected\n");
		}


    	if(1 == gpioIsrFlag)
		{
			CheckCardStatus();
		}
    }

}


/*
** This function checks the insertion and ejection status of the MicroSD card
** and does appropriate operations.
*/
static void CheckCardStatus(void)
{
    /* Read the data on the GPIO Card Detect Pin. */
    if(GPIOPinRead(GPIO_INSTANCE_ADDRESS_0, GPIO_CD_PIN_NUM))
    {
        printf("Connection removed.\n");

        /* Drive a logic LOW on the GPIO Pin controlling the LED. */
        GPIOPinWrite(GPIO_INSTANCE_ADDRESS, GPIO_INSTANCE_PIN_NUMBER, GPIO_PIN_LOW);

    }
    else
    {
    	printf("Connection added.\n");

        /* Drive a logic HIGH on the GPIO Pin controlling the LED. */
        GPIOPinWrite(GPIO_INSTANCE_ADDRESS, GPIO_INSTANCE_PIN_NUMBER, GPIO_PIN_HIGH);
    }

    gpioIsrFlag = 0;
}

/*
** GPIO Interrupt Service Routine.
*/
static void GPIOIsr(void)
{

	printf("Enter interrupt routine.");

    /* Check the Interrupt Status of the GPIO Card Detect pin. */
    if(GPIOPinIntStatus(GPIO_INSTANCE_ADDRESS_0, GPIO_INT_LINE_1, GPIO_CD_PIN_NUM) & (1 << GPIO_CD_PIN_NUM))
    {
        /* Clear the Interrupt Status of the GPIO Card Detect pin. */
        GPIOPinIntClear(GPIO_INSTANCE_ADDRESS_0, GPIO_INT_LINE_1, GPIO_CD_PIN_NUM);
    }

    gpioIsrFlag = 1;
}


static void GPIOINTCConfigure(void)
{
    /* Initialize the ARM Interrupt Controller. */
    IntAINTCInit();

    /* Register the Interrupt Service Routine(ISR). */
    IntRegister(GPIO_INST_SYS_INT_NUM, GPIOIsr);

    /* Set the priority for the GPIO0 system interrupt in INTC. */
    IntPrioritySet(GPIO_INST_SYS_INT_NUM, 0, AINTC_HOSTINT_ROUTE_IRQ);

    /* Enable the GPIO0 system interrupt in INTC. */
    IntSystemEnable(GPIO_INST_SYS_INT_NUM);
}


/*
** A function which is used to generate a delay.
*/
static void Delay1(volatile unsigned int count)
{
    while(count--);
}

/******************************* End of file *********************************/

  • Without digging through your code, to set up an ISR reacting on GPI has to be done like this:

    - set up proper pin mux

    - set up ISR (in this example for GPIO0)

    IntRegister(SYS_INT_GPIOINT0A, GPIO0Isr);
    IntPrioritySet(SYS_INT_GPIOINT0A,20, AINTC_HOSTINT_ROUTE_IRQ);
    IntSystemEnable(SYS_INT_GPIOINT0A);

    - set interrupt type and enable it for a specifig GPI (in this example also debuncing function is configured)

    GPIODebounceFuncControl(SOC_GPIO_0_REGS,DIN0_IN,GPIO_DEBOUNCE_FUNC_ENABLE);
    GPIODebounceTimeConfig(SOC_GPIO_0_REGS,globalConfig.debounceTime);
    GPIOIntTypeSet(SOC_GPIO_0_REGS,DIN0_IN,GPIO_INT_TYPE_BOTH_EDGE);
    GPIOPinIntEnable(SOC_GPIO_0_REGS,GPIO_INT_LINE_1,DIN0_IN);

    That's it!

  • Hello Hans;


    Thanks for your answer. However, I already have these three steps icluded in my code and my program still does not work when debuging. I am starting to think that it may be a bad configuration of the CCS Project Debug configuration. I have configured my debug session as shown in the two attached images but I still does not enter into the ISR code region. do not know why.

    I have tried many options but I don't know where may be the problem. Thanks a lot.

  • I have kept investigating the lack of interrupts in my GPIOport. One test I have done is to generate an internal interrupt in my code using GPIOTriggerPinInt, like this:

    printf("Enters interrupt\n");
    GPIOTriggerPinInt(GPIO_INSTANCE_ADDRESS_0, GPIO_INT_LINE_1, GPIO_CD_PIN_NUM);
    printf("Exits interrupt\n");

    In my GPIOIsr I have my own code (LEDs related and one printf). However, it does not enter in any moment to this region of code. Interrupts does not happen, although I can see clearly how the flags are changing from 0 to 1.


    What can be the reason of this wrong working? What am I overlooking? Any ideas?

    Thanks

  • Are you still trying to see these interrupts in debugger? If yes I'd recommend to let the code run freely on your board and to toggle an LED out of your GPI-ISR. This way you can verify if it isn't working in general or if it isn't working in your debugger only.

  • Hello, Hans.


    Thanks for the reply. Your suggestion looks like a good idea. I did the debug without any printf or console instructions but it still does not work. How can I load the code into the beaglebone board without debuging it? Do I have to use an SD Card or is it possible to load it directly into the board? Thanks a lot.

  • You need to build the MMCSD-variant of bootloader-project and place the resulting "MLO" file on a FAT32 formatted Micro-SD-card with BOT-flag set. Next you need to build you app, apply the TI-headers and place the resutling binary with name "APP" on same SD-card. During power-up you need to press the boot-switch on BBB.

    Full procedure is described here: http://processors.wiki.ti.com/index.php/Quick_Start_Guide_StarterWare_02.00.XX.XX_(supports_AM335x)

  • Hello Hans et al.,

    If I load my program into the SD Card and the BBB, it works correctly. I could not watch the interrupts using the debugger but I can see them working without problems using the console prompts.

    Thanks a lot.

  • Hey Hans & Pedro,

    is there really no other way of using Interrupts with a debugger? The development process would be pretty hard otherwise (compile, copy to sd, reboot, "debug" over serial console messages?!)

    We're currently using an XDS200 debugger, is there an other one that works with the beagle bone black interrupts?

    Thanks,

    Richard

    -- Nevermind, we got it working with the debugger :)

  • Hello Richard,

    I have the same problem. No callback in the ISR.
    >> -- Nevermind, we got it working with the debugger :)
    What was the solution?

    Thanks in advance,
    Stephan
  • I registered the wrong interrupt number for my GPIO3 pin. How stupid.
    The numbers are:
    SYS_INT_GPIOINT2A 32
    SYS_INT_GPIOINT2B 33
    SYS_INT_GPIOINT3A 62
    SYS_INT_GPIOINT3B 63
    SYS_INT_GPIOINT0A 96
    SYS_INT_GPIOINT0B 97
    SYS_INT_GPIOINT1A 98
    SYS_INT_GPIOINT1B 99

    Regards,
    Stephan
  • Hello Stephan, how are you?

    Can you still remember what you did to make interrupts work in debugging mode?

    Thank you

  • Hello Atila,

    so far I didn't use the GPIO interrupt feature. Maybe you want to reply to Pedro, who started this thread. In the starterware is the example AM335X_StarterWare\examples\beaglebone\demo\ with the file demoMain.c. This one registers the GPIOIsr in Line 558. This one was adapted to the BeagleBoneBlack and should work.

    Best Regards,
    Stephan
  • Thank you for your help, Stephan.