Jump to content
  • 0

Arty A7 GPIO interrupt issue


fpga_babe

Question

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;
}

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

Link to comment
Share on other sites

3 answers to this question

Recommended Posts

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.

Link to comment
Share on other sites

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.

 

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...