cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Explorer
Explorer
5,264 Views
Registered: ‎04-18-2017

[Zedboard] AXI-GPIO interrupt not working

Jump to solution

Hello,

 

I have the following hardware:

 

hw.jpg

 

For the software, the interrupt part, I copied from a previous project where I had a custom IP generating the interrupt source so I thought it would be copying and pasting. Here is the software:

 

#include "xparameters.h"
#include "xil_printf.h"
#include "xgpio.h"
#include "xuartps.h"
#include "xscugic.h"

#define BUTTONS_channel		1
#define BUTTONS_AXI_ID		XPAR_AXI_GPIO_0_DEVICE_ID

#define SWITCHES_channel	1
#define SWITCHES_AXI_ID		XPAR_AXI_GPIO_1_DEVICE_ID

#define LEDS_channel		1
#define LEDS_AXI_ID			XPAR_AXI_GPIO_2_DEVICE_ID

#define UART_DEVICE_ID      XPAR_XUARTPS_0_DEVICE_ID

#define INTC_DEVICE_ID 		XPAR_PS7_SCUGIC_0_DEVICE_ID
#define INT_PushButtons		61

#define IDLE		0
#define STOP 		1
#define FORWARD 	16
#define BACKWARDS 	2
#define LEFT 		4
#define RIGHT 		8

XGpio BTNS, STWS, LEDS;
XUartPs Uart_Ps;		/* The instance of the UART Driver */
XUartPs_Config *Config;
static XScuGic INTCInst;

u32 buttons=0, switches=0;

u8 stop[] = "STOP 0\r";
u8 forward[] = "GO 15 15\r";
u8 backwards[] = "GO FFEC FFEC\r";	//Two's complement -20=FFEC
u8 left[] = "GO FFEC 15\r";
u8 right[] = "GO 15 FFEC\r";

static int IntcInitFunction(u16 DeviceId);
int InterruptSystemSetup(XScuGic *XScuGicInstancePtr);
void PushButtons_Intr_Handler(void *data);

void sendUART(u8* message, int len);

int main(void)
{
	int Status;

	// Initializes AXI-GPIO_0 (Touch buttons)
	Status = XGpio_Initialize(&BTNS, BUTTONS_AXI_ID);
	if (Status != XST_SUCCESS)
	{
		xil_printf("Buttons error\n");
		return XST_FAILURE;
	}

	// Initializes AXI-GPIO_1 (Switches)
	Status = XGpio_Initialize(&STWS, SWITCHES_AXI_ID);
	if (Status != XST_SUCCESS)
	{
		xil_printf("Switches error\n");
		return XST_FAILURE;
	}

	// Initializes AXI-GPIO_2 (LEDs)
	Status = XGpio_Initialize(&LEDS, LEDS_AXI_ID);
	if (Status != XST_SUCCESS)
	{
		xil_printf("LEDs error\n");
		return XST_FAILURE;
	}

	// Sets AXI-GPIO's directions,
	XGpio_SetDataDirection(&BTNS, BUTTONS_channel, 0xFF);	// Input
	XGpio_SetDataDirection(&STWS, SWITCHES_channel, 0xFF);	// Input
	XGpio_SetDataDirection(&LEDS, LEDS_channel, 0x00);		// Output


	/*
	 * Initialize the UART driver so that it's ready to use
	 * Look up the configuration in the config table and then initialize it.
	 */
	Config = XUartPs_LookupConfig(UART_DEVICE_ID);
	if (NULL == Config) {
		return XST_FAILURE;
	}

	Status = XUartPs_CfgInitialize(&Uart_Ps, Config, Config->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	XUartPs_SetBaudRate(&Uart_Ps, 115200);

	// Initializes interruptions.
	Status = IntcInitFunction(INTC_DEVICE_ID);

	while(1)
	{
	/*	buttons = XGpio_DiscreteRead(&BTNS, BUTTONS_channel);

		switch(buttons)
		{
			case STOP:
				XGpio_DiscreteWrite(&LEDS, LEDS_channel, 1);	// LD0.
				sendUART(stop, sizeof(stop));
				break;
			case FORWARD:
				XGpio_DiscreteWrite(&LEDS, LEDS_channel, 2);	// LD1.
				sendUART(forward, sizeof(forward));
				break;
			case BACKWARDS:
				XGpio_DiscreteWrite(&LEDS, LEDS_channel, 4);	// LD2.
				sendUART(backwards, sizeof(backwards));
				break;
			case LEFT:
				XGpio_DiscreteWrite(&LEDS, LEDS_channel, 8);	// LD3.
				sendUART(left, sizeof(left));
				break;
			case RIGHT:
				XGpio_DiscreteWrite(&LEDS, LEDS_channel, 16);	// LD4.
				sendUART(right, sizeof(right));
				break;
		}*/
	}

	return 0;
}

void sendUART(u8* message, int len)
{
	int SentCount = 0;
	while (SentCount < (len-1))
	{
		/* Transmit the data */
		SentCount += XUartPs_Send(&Uart_Ps, &message[SentCount], 1);
	}
}

static int IntcInitFunction(u16 DeviceId)
{
	int Status;

	XScuGic_Config *IntcConfig;

	// Interrupt controller initialization
	IntcConfig = XScuGic_LookupConfig(DeviceId);
	Status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);
	if(Status != XST_SUCCESS) return XST_FAILURE;

	// Call to interrupt setup
	Status = InterruptSystemSetup(&INTCInst);
	if(Status != XST_SUCCESS) return XST_FAILURE;

	XScuGic_SetPriorityTriggerType(&INTCInst, INT_PushButtons, 0, 3);	//Max priority, rising edge.

	Status = XScuGic_Connect(&INTCInst,	INT_PushButtons, (Xil_ExceptionHandler)PushButtons_Intr_Handler, (void *) 0);
	if(Status != XST_SUCCESS) return XST_FAILURE;

	XScuGic_Enable(&INTCInst, INT_PushButtons);

	return XST_SUCCESS;
}
int InterruptSystemSetup(XScuGic *XScuGicInstancePtr)
{
	/*
	 * Initialize the interrupt controller driver so that it is ready to use.
	 * */
	Xil_ExceptionInit();

	// Enable interrupt


	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			 	 	 	 	 	 (Xil_ExceptionHandler)XScuGic_InterruptHandler,
			 	 	 	 	 	 XScuGicInstancePtr);
	Xil_ExceptionEnable();

	return XST_SUCCESS;
}
void PushButtons_Intr_Handler(void *data)
{
	buttons = XGpio_DiscreteRead(&BTNS, BUTTONS_channel);

	switch(buttons)
	{
		case STOP:
			XGpio_DiscreteWrite(&LEDS, LEDS_channel, 1);	// LD0.
			sendUART(stop, sizeof(stop));
			break;
		case FORWARD:
			XGpio_DiscreteWrite(&LEDS, LEDS_channel, 2);	// LD1.
			sendUART(forward, sizeof(forward));
			break;
		case BACKWARDS:
			XGpio_DiscreteWrite(&LEDS, LEDS_channel, 4);	// LD2.
			sendUART(backwards, sizeof(backwards));
			break;
		case LEFT:
			XGpio_DiscreteWrite(&LEDS, LEDS_channel, 8);	// LD3.
			sendUART(left, sizeof(left));
			break;
		case RIGHT:
			XGpio_DiscreteWrite(&LEDS, LEDS_channel, 16);	// LD4.
			sendUART(right, sizeof(right));
			break;
	}
}

If I don't use the interrupt, it works but i want to avoid doing it in the while loop. Have I missed something or not configured a register?

 

Thank you for the help.

 

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Explorer
Explorer
6,956 Views
Registered: ‎06-19-2015

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

Hi @aripod

 

yes.. You need to clear the interupt...

 

Call this function... XGpio_InterruptClear(GpioInstance,InterptMask);

 

----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------------

 

Thank you

Madhu

View solution in original post

15 Replies
Highlighted
Explorer
Explorer
5,229 Views
Registered: ‎06-19-2015

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

Hi @aripod

 

You haven't enabled the interrupts in AXI_GPIO...

 

Use these functions

	/*
	 * Enable the GPIO channel interrupts so that push button can be
	 * detected and enable interrupts for the GPIO device
	 */
	XGpio_InterruptEnable(InstancePtr, IntrMask);
	XGpio_InterruptGlobalEnable(InstancePtr);

Go through the file xgpio_intr_tapp_example.c (located at <xilinx_instal_folder>\SDK\2017.1\data\embeddedsw\XilinxProcessorIPLib\drivers\gpio_v4_3\examples)

 


----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------------

 

Thanks

Madhu

Highlighted
Explorer
Explorer
5,178 Views
Registered: ‎04-18-2017

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

Hello @madhu.mami60,

 

Thank you for your help. I checked the example and compared it with my code and I was only missing the two lines that you said. I added them just before the while loop, but I am still not getting the interruption when I press a push button.

 

#include "xparameters.h"
#include "xil_printf.h"
#include "xgpio.h"
#include "xuartps.h"
#include "xscugic.h"

#define BUTTONS_channel		1
#define BUTTONS_AXI_ID		XPAR_AXI_GPIO_0_DEVICE_ID

#define SWITCHES_channel	1
#define SWITCHES_AXI_ID		XPAR_AXI_GPIO_1_DEVICE_ID

#define LEDS_channel		1
#define LEDS_AXI_ID			XPAR_AXI_GPIO_2_DEVICE_ID

#define UART_DEVICE_ID      XPAR_XUARTPS_0_DEVICE_ID

#define INTC_DEVICE_ID 		XPAR_PS7_SCUGIC_0_DEVICE_ID
#define INT_PushButtons		61

#define IDLE		0
#define STOP 		1
#define FORWARD 	16
#define BACKWARDS 	2
#define LEFT 		4
#define RIGHT 		8

XGpio BTNS, STWS, LEDS;
XUartPs Uart_Ps;		/* The instance of the UART Driver */
XUartPs_Config *Config;
static XScuGic INTCInst;

u32 buttons=0, switches=0, IntrMask;

u8 stop[] = "STOP 0\r";
u8 forward[] = "GO 15 15\r";
u8 backwards[] = "GO FFEC FFEC\r";	//Two's complement -20=FFEC
u8 left[] = "GO FFEC 15\r";
u8 right[] = "GO 15 FFEC\r";

static int IntcInitFunction(u16 DeviceId);
int InterruptSystemSetup(XScuGic *XScuGicInstancePtr);
void PushButtons_Intr_Handler(void *data);

void sendUART(u8* message, int len);

int main(void)
{
	int Status;
	u8 recv[256] = {0};
	u32 nbytes;
	// Initializes AXI-GPIO_0 (Touch buttons)
	Status = XGpio_Initialize(&BTNS, BUTTONS_AXI_ID);
	if (Status != XST_SUCCESS)
	{
		xil_printf("Buttons error\n");
		return XST_FAILURE;
	}

	// Initializes AXI-GPIO_1 (Switches)
	Status = XGpio_Initialize(&STWS, SWITCHES_AXI_ID);
	if (Status != XST_SUCCESS)
	{
		xil_printf("Switches error\n");
		return XST_FAILURE;
	}

	// Initializes AXI-GPIO_2 (LEDs)
	Status = XGpio_Initialize(&LEDS, LEDS_AXI_ID);
	if (Status != XST_SUCCESS)
	{
		xil_printf("LEDs error\n");
		return XST_FAILURE;
	}

	// Sets AXI-GPIO's directions,
	XGpio_SetDataDirection(&BTNS, BUTTONS_channel, 0xFF);	// Input
	XGpio_SetDataDirection(&STWS, SWITCHES_channel, 0xFF);	// Input
	XGpio_SetDataDirection(&LEDS, LEDS_channel, 0x00);		// Output

	// Enable AXI-GPIO's interruption.
	XGpio_InterruptEnable(&BTNS, IntrMask);
	XGpio_InterruptGlobalEnable(&BTNS);


	/*
	 * Initialize the UART driver so that it's ready to use
	 * Look up the configuration in the config table and then initialize it.
	 */
	Config = XUartPs_LookupConfig(UART_DEVICE_ID);
	if (NULL == Config) {
		return XST_FAILURE;
	}

	Status = XUartPs_CfgInitialize(&Uart_Ps, Config, Config->BaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	XUartPs_SetBaudRate(&Uart_Ps, 115200);

	// Initializes interruptions.
	Status = IntcInitFunction(INTC_DEVICE_ID);

	while(1)
	{
		buttons = XGpio_DiscreteRead(&BTNS, BUTTONS_channel);
		//XUartPs_Recv(&Uart_Ps, recv, nbytes);	//To test if Tx and Rx on the PMOD were working.

		/*switch(buttons)
		{
			case STOP:
				XGpio_DiscreteWrite(&LEDS, LEDS_channel, 1);	// LD0.
				sendUART(stop, sizeof(stop));
				break;
			case FORWARD:
				XGpio_DiscreteWrite(&LEDS, LEDS_channel, 2);	// LD1.
				sendUART(forward, sizeof(forward));
				break;
			case BACKWARDS:
				XGpio_DiscreteWrite(&LEDS, LEDS_channel, 4);	// LD2.
				sendUART(backwards, sizeof(backwards));
				break;
			case LEFT:
				XGpio_DiscreteWrite(&LEDS, LEDS_channel, 8);	// LD3.
				sendUART(left, sizeof(left));
				break;
			case RIGHT:
				XGpio_DiscreteWrite(&LEDS, LEDS_channel, 16);	// LD4.
				sendUART(right, sizeof(right));
				break;
		}*/
	}

	return 0;
}

void sendUART(u8* message, int len)
{
	int SentCount = 0;
	XUartPs_Send(&Uart_Ps, message, len-1);
	/*while (SentCount < (len-1))
	{
		// Transmit the data
		SentCount += XUartPs_Send(&Uart_Ps, &message[SentCount], 1);
	}*/
}

static int IntcInitFunction(u16 DeviceId)
{
	int Status;

	XScuGic_Config *IntcConfig;

	// Interrupt controller initialization
	IntcConfig = XScuGic_LookupConfig(DeviceId);
	Status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);
	if(Status != XST_SUCCESS) return XST_FAILURE;

	// Call to interrupt setup
	Status = InterruptSystemSetup(&INTCInst);
	if(Status != XST_SUCCESS) return XST_FAILURE;

	XScuGic_SetPriorityTriggerType(&INTCInst, INT_PushButtons, 0, 3);	//Max priority, rising edge.

	Status = XScuGic_Connect(&INTCInst,	INT_PushButtons, (Xil_ExceptionHandler)PushButtons_Intr_Handler, (void *) 0);
	if(Status != XST_SUCCESS) return XST_FAILURE;

	XScuGic_Enable(&INTCInst, INT_PushButtons);

	return XST_SUCCESS;
}
int InterruptSystemSetup(XScuGic *XScuGicInstancePtr)
{
	/*
	 * Initialize the interrupt controller driver so that it is ready to use.
	 * */
	Xil_ExceptionInit();

	// Enable interrupt


	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			 	 	 	 	 	 (Xil_ExceptionHandler)XScuGic_InterruptHandler,
			 	 	 	 	 	 XScuGicInstancePtr);
	Xil_ExceptionEnable();

	return XST_SUCCESS;
}
void PushButtons_Intr_Handler(void *data)
{
	buttons = XGpio_DiscreteRead(&BTNS, BUTTONS_channel);

	switch(buttons)
	{
		case STOP:
			XGpio_DiscreteWrite(&LEDS, LEDS_channel, 1);	// LD0.
			sendUART(stop, sizeof(stop));
			break;
		case FORWARD:
			XGpio_DiscreteWrite(&LEDS, LEDS_channel, 2);	// LD1.
			sendUART(forward, sizeof(forward));
			break;
		case BACKWARDS:
			XGpio_DiscreteWrite(&LEDS, LEDS_channel, 4);	// LD2.
			sendUART(backwards, sizeof(backwards));
			break;
		case LEFT:
			XGpio_DiscreteWrite(&LEDS, LEDS_channel, 8);	// LD3.
			sendUART(left, sizeof(left));
			break;
		case RIGHT:
			XGpio_DiscreteWrite(&LEDS, LEDS_channel, 16);	// LD4.
			sendUART(right, sizeof(right));
			break;
	}
}

Should I call XGpio_InterruptEnable and XGpio_InterruptGlobalEnable somewhere else?

Thank you.

0 Kudos
Highlighted
Explorer
Explorer
5,164 Views
Registered: ‎06-19-2015

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

Hi @aripod

You are missing the "IntrMask" variable assignment. No mash value assigned. Assign the mask value to which port you want get interrupt. 

 

And, in your main function, do nothing in while(1) loop. Add comment to this also 

buttons = XGpio_DiscreteRead(&BTNS, BUTTONS_channel);

As you continuously performing a read operation, the interrupt may clear.

 

 

Thanks

Madhu

0 Kudos
Highlighted
Explorer
Explorer
5,150 Views
Registered: ‎04-18-2017

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

Hello @madhu.mami60

 

Sorry for the dumb question. By port you mean which AXI-IP? Or as I have 5 buttons, which button I want get interrupt?

 

Thank you!

0 Kudos
Highlighted
Explorer
Explorer
5,126 Views
Registered: ‎04-18-2017

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution
I believe you meant I have to do something similar when I assign if they are input or ouput: XGpio_SetDataDirection(&BTNS, BUTTONS_channel, 0xFF); Right? So for the IntrMask it should also be 0xFF if I am not mistaken.
0 Kudos
Highlighted
Explorer
Explorer
5,055 Views
Registered: ‎06-19-2015

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution
Yes...
0 Kudos
Highlighted
Explorer
Explorer
5,049 Views
Registered: ‎04-18-2017

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

Hello @madhu.mami60. I have just tested this with XGpio_InterruptEnable(&BTNS, 0xFF);. The interruption happened but only once. Do I need to clear something before leaving the interrupt handler function?

 

Thank you again for your help.

0 Kudos
Highlighted
Explorer
Explorer
6,957 Views
Registered: ‎06-19-2015

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

Hi @aripod

 

yes.. You need to clear the interupt...

 

Call this function... XGpio_InterruptClear(GpioInstance,InterptMask);

 

----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------------

 

Thank you

Madhu

View solution in original post

Highlighted
Explorer
Explorer
5,038 Views
Registered: ‎04-18-2017

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution
Not it is working. Thank you very much for your big help!
0 Kudos
Highlighted
Explorer
Explorer
3,451 Views
Registered: ‎04-18-2017

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution
Ok, now the interruptions works but the uart does not output anything else. Can they be related?
0 Kudos
Highlighted
Explorer
Explorer
3,442 Views
Registered: ‎06-19-2015

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

Hi @aripod

 

1) Check the Uart Terminal baudrate in your pc... Both should be 115200 as you set.

2) Check the Rx and Tx connections are proper,

3) Set the operation mode

XUartPs_SetOperMode(&Uart_PS, XUARTPS_OPER_MODE_NORMAL);

4) 

void sendUART(u8* message, int len)
{
	int SentCount = 0;
	XUartPs_Send(&Uart_Ps, message, len); //Send full lentgh. Why -1??
}

 

----------------------------------------------------------------------------------------------
Kindly note- Please mark the Answer as "Accept as solution" if information provided is helpful.

Give Kudos to a post which you think is helpful and reply oriented.
----------------------------------------------------------------------------------------------

 

Thanks

Madhu

Highlighted
Explorer
Explorer
3,431 Views
Registered: ‎04-18-2017

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

Hi @madhu.mami60,

 

I also tested the UART through the PMOD and this is why I was not seeing anything on the terminal. Thank you for the help again. 

0 Kudos
Highlighted
Explorer
Explorer
3,426 Views
Registered: ‎06-19-2015

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution
Hi,
Once try simple Hello world.
0 Kudos
Highlighted
Visitor
Visitor
2,362 Views
Registered: ‎12-07-2018

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

Can post the complete code again please?

I don't know how to clear the interrupt. I'm adding at the end of the GpioHandler the following line:

XGpio_InterruptClear(data,IntrMask);

It doens't work :(

0 Kudos
Highlighted
Visitor
Visitor
1,848 Views
Registered: ‎07-30-2018

Re: [Zedboard] AXI-GPIO interrupt not working

Jump to solution

I'm also having trouble replicating the solution. My code does not resume the stack after the handler function is called and I am calling XGpio_InterruptClear(data,IntrMask);. 

0 Kudos