• 0
fpga_babe

Arty A7 GPIO interrupt issue

Question

Posted (edited)

Hi,

I am having a problem with GPIO interrtupt on Arty A7 board.

+ 2 GPIO with each of them is dual channel.

+ INTC instance to connect the interrtup with Microblaze.

After I used below software, I can not see the interrupt. Would you please tell me how to debug in next step ?

Sorry, I am new to SDK and Arty A7.

 

I want to connect the switch or button as interrupt, and do some task inside a handler.

I want to clarify below of my understanding, whether it is correct or not:

1. hardware:

   - Enable register access in INTC to make the software can access INTC registers.

   - Choose level (high) as interrupt type.

   - Fast interrupt is enable.

 

2. Software:

#---------------------------------

/***************************** Include Files *********************************/

#include "xparameters.h"
#include "xil_exception.h"
#include "xintc.h"
#include "xgpio.h"
#include "xil_printf.h"


#define UART_INT_CHANNEL 0
#define GPIO0_INT_CHANNEL 1
#define GPIO1_INT_CHANNEL 2

XGpio Gpio0; /* The Instance of the GPIO0 Driver */
XGpio Gpio1; /* The Instance of the GPIO1 Driver */

XIntc Intc; /* The Instance of the Interrupt Controller Driver */

void UART_HANDLER(void *Callbackref);
void GPIO0_HANDLER(void *Callbackref);
void GPIO1_HANDLER(void *Callbackref);

void GPIO0_HANDLER(void *Callbackref)
{
xil_printf("Handler GPIO0 !! \r\n");
//write out GPIO0, LED 0101
XGpio_DiscreteWrite(&Gpio0, 1, 0x05);
//Write out GPIO1, LED RGB
XGpio_DiscreteWrite(&Gpio1, 1, 0xAA55);
}

// Main program

int main(void)
{

// 0. Initial GPIO0

Status = XGpio_Initialize(&Gpio1, XPAR_GPIO_1_DEVICE_ID);

if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

//Configure the IO direction for GPIO0 ( push button is in channel2):  

XGpio_SetDataDirection(&Gpio1, 1, 0x00000 );
XGpio_SetDataDirection(&Gpio1, 2, 0xFFFFF );

//1. Init the Interrupt controller
Status = XIntc_Initialize(&Intc, 0);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}

//2. Connect the handlers
Status = XIntc_Connect(&Intc, GPIO0_INT_CHANNEL,
(XInterruptHandler) &GPIO0_HANDLER,
(void *) 0);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}


//3. Enable the INTC
XIntc_Enable(&Intc, GPIO0_INT_CHANNEL);
XIntc_Enable(&Intc, GPIO1_INT_CHANNEL);


//4. Start the INTC
Status = XIntc_Start(&Intc, XIN_REAL_MODE);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}


//5. Enable interrupt for GPIO0
XGpio_InterruptEnable( &Gpio0, 0x0000);
XGpio_InterruptGlobalEnable( &Gpio0 );

// 6. Initi the exception
Xil_ExceptionInit();
//
 Xil_ExceptionRegisterHandler(1,
 (Xil_ExceptionHandler)GPIO0_HANDLER, 0);
//
// /* Enable non-critical exceptions */
Xil_ExceptionEnable();


xil_printf("Waiting for interrupt... !! \r\n");
while(1) {

}

//return
return XST_SUCCESS;
}

//--------------------------------------------------------------------------------

Edited by fpga_babe
edit the code and highlight

Share this post


Link to post
Share on other sites

3 answers to this question

Recommended Posts

  • 0
On 4/12/2019 at 1:47 AM, jpeyron said:

Hi @fpga_babe,

Welcome to the forums!

Here is verified Arty-A7 35T GPIO interrupt project using Vivado 2018.3 that should be helpful for your project.

best regards,

Jon

Hi Jon,

 

Thank you for your response.

Before trying your reference design, I modifed my code below: 

[ORG] 

//2. Connect the handlers
Status = XIntc_Connect(&Intc, GPIO0_INT_CHANNEL, (XInterruptHandler) &GPIO0_HANDLER, (void *) 0);

 

[MOD]

//2. Connect the handlers
Status = XIntc_Connect(&Intc, GPIO0_INT_CHANNEL, (XInterruptHandler) GPIO0_HANDLER, (void *) 0);

I could see the interrupt happened. I think the arrgument passed to the function is not correct.

 

I will check your program as well.

Share this post


Link to post
Share on other sites
  • 0

The version of "arty_a7_gpio_interrupt.zip" appears to have been modified and doesn't work:

 

(A) The two commented lines at the bottom need to be uncommented:

DOESN"T WORK:

int Init_Interrupt(void)
{

    . . . .
    //XGpio_InterruptEnable(&Gpio, 0xf);
    usleep(100);
    //XGpio_InterruptGlobalEnable(&Gpio);
    usleep(100);
    return stat;

}

DOES WORK:

int Init_Interrupt(void)
{
   . . . .
    XGpio_InterruptEnable(&Gpio, 0xf);
    usleep(100);
    XGpio_InterruptGlobalEnable(&Gpio);
    usleep(100);
    return stat;

}

 

(B) The  "XGpio_InterruptClear(&Gpio, 0x0)" parameters need to be changed:

DOESN"T WORK:

void InterruptHandler(void *CallbackRef)
{
    xil_printf("Received the Interrupt\n\r");
    XGpio_InterruptClear(&Gpio, 0x0);
    XIntc_Acknowledge(&Intc, XPAR_MICROBLAZE_0_AXI_INTC_AXI_GPIO_0_IP2INTC_IRPT_INTR);

}

DOES WORK:

void InterruptHandler(void *CallbackRef)
{
    xil_printf("Received the Interrupt\n\r");
    XGpio_InterruptClear(&Gpio, 0xF);
    XIntc_Acknowledge(&Intc, XPAR_MICROBLAZE_0_AXI_INTC_AXI_GPIO_0_IP2INTC_IRPT_INTR);

}

Not sure what was intended with the 0xF.  As they are, the interrupt will be enabled for the Switches and the Buttons.  To only monitor the buttons use 0x2.  Also the main() program seems to be reporting Switch status, but is labeling it as Buttons.

 

 

Edited by aadgl
Pushed Tab by accident

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now