cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
4,259 Views
Registered: ‎11-01-2010

The correct way to use an external interrupt?

 

First a bit of an introduction on my project.

I am working on a project that connects a Spartan 3 to an eDiptft43 touchscreen display via UART.

I have been able to send a command to the display using the UARTLITE ip.

I want to be able to push on a button on my touchscreen and have the microblaze send something back.

The display puts a data packet in it's send buffer and pulls a pin low to indicate that there is data in its send buffer.

 

I have tried polling, but no luck.

So I wanted to make an interrupt. So when the pin is pulled low by the display I get an interrupt.

This system might use more hardware in the future, so I wanted to use the interrupt controller (xps_intc).

 

Now the problem is that I don't seem to find any consistent(and valid) way of doing this on the internet, or in the examples in EDK.

 

I have added a simpified bit of code which is supposed to write an array spot to the uart. When the interrupt has occurred another spot will be written. Simply to prove that the interrupt works.

 

What am I doing wrong?

 


#include "xparameters.h"

#include "stdio.h"

#include "xintc.h"
#include "intc_header.h"

#include "uartlite_header.h"
#include "xuartlite.h"

// global vars
int command;
unsigned char array[255] = { 0x1B, 0x47, 0x44, 0x00 }

#define UartLite XPAR_UARTLITE_1_BASEADDR
XUartLite UartLite_Instance;
static XIntc InterruptController; /* Instance of the Interrupt Controller */


// interrupt ------------------------------------------
void ExtInterruptHandler (void *CallBackRef) ;

//=====================================================
//=====================================================
// main

int main (void)
{
unsigned int init_status;
command = 0x00;

// setup interrupt---------------------------------------
init_status = XIntc_Initialize ( &InterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
microblaze_enable_interrupts();
init_status = XIntc_Connect ( &InterruptController, XPAR_XPS_INTC_0_SYSTEM_EXTERNAL_INTERRUPT_INTR, (XInterruptHandler)ExtInterruptHandler, (void *)0 );
init_status = XIntc_Start ( &InterruptController, XIN_REAL_MODE );
XIntc_Enable ( &InterruptController, XPAR_XPS_INTC_0_SYSTEM_EXTERNAL_INTERRUPT_INTR );
// ------------------------------------------------------

// setup UART--------------------------------------------
init_status = XUartLite_Initialize(&UartLite_Instance, XPAR_UARTLITE_1_DEVICE_ID);
XUartLite_ResetFifos(&UartLite_Instance);
// ------------------------------------------------------

while(1)
{
Wait_busy(); //for loop to waste some time
XIntc_Disable ( &InterruptController, XPAR_XPS_INTC_0_SYSTEM_EXTERNAL_INTERRUPT_INTR );
if (command == 0x0A)
{
XUartLite_SendByte(UartLite, array[1]);
}
else if ( command == 0x00)
{
XUartLite_SendByte(UartLite, array[3]);
}
XIntc_Enable ( &InterruptController, XPAR_XPS_INTC_0_SYSTEM_EXTERNAL_INTERRUPT_INTR );
}

// interrupt service routine -----------------------------------

void ExtInterruptHandler (void *CallBackRef)
{
command = 0x0A;
XIntc_Acknowledge ( &InterruptController, XPAR_XPS_INTC_0_DEVICE_ID );
}

 


 

As the interrupt is supposed to happen on the falling edge, these lines are in my xparameters.h

 

 

#define XPAR_MICROBLAZE_0_INTERRUPT_IS_EDGE 1
#define XPAR_MICROBLAZE_0_EDGE_IS_POSITIVE 0

#define XPAR_MICROBLAZE_INTERRUPT_IS_EDGE 1
#define XPAR_MICROBLAZE_EDGE_IS_POSITIVE 0

 

 

Could you please show me a way to use my interrupt so that it works.

 

Thanks in advance for your efforts.

 

 

 

 

0 Kudos
4 Replies
Highlighted
Adventurer
Adventurer
4,251 Views
Registered: ‎09-30-2009

 

Hi
consult XAPP778 to know more about interrupts usage
max

 

0 Kudos
Highlighted
Explorer
Explorer
4,218 Views
Registered: ‎05-15-2009

Hi,

 

This should be straightforward. You need to route the pin to the primary interrupt controller and then handle it using software. Simply add a Net with the pin name and its location in the *.ucf and then route it as a direct source in the PIC using "External Ports" in XPS Ports view. You may use a pin in the expansion connector of your board to "read" the voltage level of the "send buffer out" pin of the LCD. Remember to check the voltage level compatibility of the LCD pin and the input pin on the board, it should pass the input's Vth when high.

 

 

Best,

JM

0 Kudos
Highlighted
4,198 Views
Registered: ‎11-01-2010

Thanks for your help. It works now.

 

The thing I did wrong was that I didn't give my variable "command" the proper keywords.

So instead of :

 

int command;

 

 

It was supposed to be:

 

static volatile int command;

 

 

0 Kudos
Highlighted
4,164 Views
Registered: ‎11-01-2010

OK, like I said previously, it works in GDB. (running on real hardware)

No matter how many times I use the interrupt, it does what it is supposed to.

 

But when I run it normally without using the debugger it works one or two times and than it just wont.

 

Anyone seen something like that before?

 

0 Kudos