I have been asked about how to use a GPIO as an interrupt input, without having to use the CSL. Below is one technique I have used successfully. It uses the Spectrum Digital BSL (board support library), which can be downloaded from their website (http://support.spectrumdigital.com/boards/usbstk5515_v2/reva/).
The steps for setting up a GPIO line using BSL code are as follows:
1. Define the GPIO registers in I/O memory (Note: I have added some registers that were not in the BSL). I created file called "gpio.h" and put this code there.
#define SYS_GPIO_DIR0 *(volatile ioport Uint16*)(0x1c06)
#define SYS_GPIO_DIR1 *(volatile ioport Uint16*)(0x1c07)
#define SYS_GPIO_DATAIN0 *(volatile ioport Uint16*)(0x1c08)
#define SYS_GPIO_DATAIN1 *(volatile ioport Uint16*)(0x1c09)
#define SYS_GPIO_DATAOUT0 *(volatile ioport Uint16*)(0x1c0a)
#define SYS_GPIO_DATAOUT1 *(volatile ioport Uint16*)(0x1c0b)
#define SYS_GPIO_INTEDGE0 *(volatile ioport Uint16*)(0x1c0c)
#define SYS_GPIO_INTEDGE1 *(volatile ioport Uint16*)(0x1c0d)
#define SYS_GPIO_INTEN0 *(volatile ioport Uint16*)(0x1c0e)
#define SYS_GPIO_INTEN1 *(volatile ioport Uint16*)(0x1c0f)
#define SYS_GPIO_INTFLG0 *(volatile ioport Uint16*)(0x1c10)
#define SYS_GPIO_INTFLG1 *(volatile ioport Uint16*)(0x1c11)
2. Next, initialize the GPIO port(s) you want to use. You must initialize
a) Direction (input for an interrupt),
b) Enable (temporarily disable the interrupt until you want to use it. Enable it later when ready.)
c) Rising/Falling Edge Trigger (I use rising edge trigger. Careful! Zero is rising edge, not "1").
c) Clear any existing interrupt flags.
void GPIO_init()
{
USBSTK5515_GPIO_setDirection(5,0); //Set 5 as input
USBSTK5515_GPIO_setIntEnable(5,0); //Disable int.
USBSTK5515_GPIO_setIntEdge(5,0); //Set rising edge
USBSTK5515_GPIO_clearIntFlag(5); //Clear any existing flags
}
Include the following code (from the BSL). I created a file called "gpio.c" and put the code there.
/* ------------------------------------------------------------------------ *
* *
* _GPIO_setIntEdge( number, direction ) *
* *
* number <- GPIO# *
* edge <- 1:Positive Edge Trigger 0:Negative Edge Trigger *
* *
* ------------------------------------------------------------------------ */
Int16 USBSTK5515_GPIO_setIntEdge( Uint16 number, Uint16 edge )
{Uint32 bank_id = ( number >> 4);
Uint32 pin_id = ( 1 << ( number & 0xF ) );if (bank_id == 0)
if ((edge & 1) == GPIO_INTEDGE_NEG)
SYS_GPIO_INTEDGE0 &= ~pin_id;
else
SYS_GPIO_INTEDGE0 |= pin_id;if (bank_id == 1)
if ((edge & 1) == GPIO_INTEDGE_NEG)
SYS_GPIO_INTEDGE1 &= ~pin_id;
else
SYS_GPIO_INTEDGE1 |= pin_id;return 0;
}Int16 USBSTK5515_GPIO_setIntEnable( Uint16 number, Uint16 enable )
{Uint32 bank_id = ( number >> 4);
Uint32 pin_id = ( 1 << ( number & 0xF ) );if (bank_id == 0)
if ((enable & 1) == GPIO_INT_DISABLE)
SYS_GPIO_INTEN0 &= ~pin_id;
else
SYS_GPIO_INTEN0 |= pin_id;if (bank_id == 1)
if ((enable & 1) == GPIO_INT_DISABLE)
SYS_GPIO_INTEN1 &= ~pin_id;
else
SYS_GPIO_INTEN1 |= pin_id;return 0;
}Int16 USBSTK5515_GPIO_clearIntFlag( Uint16 number)
{Uint32 bank_id = ( number >> 4);
Uint32 pin_id = ( 1 << ( number & 0xF ) );if (bank_id == 0) SYS_GPIO_INTFLG0 |= pin_id;
if (bank_id == 1) SYS_GPIO_INTFLG1 |= pin_id;
return 0;
}
Next, you must create an Interrupt Service Routine which captures the interrupt when it is triggered. To do this, modify the "vector.asm" file by adding the following:
GPIO: .ivec _GPIO_Isr ; GPIO Interrupt
(note the "_" underline before the GPIO_Isr label. This is necessary).
This points (vectors) the interrupt to a function called "GPIO_Isr" that you include somewhere in your code (put it in "gpio.c"). Here's some example code.
interrupt void GPIO_Isr(void)
{
interrupt_received = true;
}
Note how simple the code is in the ISR. Do not include a function call or time consuming code inside the ISR. Just set a simple flag ("interrupt_received") and do the heavy processing in you main code, otherwise you may end up with unexplained behavior.
Finally, in you "main.c" file, include some of the following:
a) Make sure the EBSR enables the GPIO line you are using:
b) Enable the GPIO system interrupt in IER1 (bit 5).
c) Enable Global Interrupts (another BSL function)
d) Initialize the GPIO functions (code is from above).
void main(void)
{
ConfigPort(0x5900); //set EBSR to enable your GPIO pin(s)
IER1 = 0x0020; //enable GPIO system interrupt
SYS_GlobalIntEnable(); //enable Global interrupt
GPIO_init(); //initialize the GPIO pins you want to use
.
.
.
}
I hope this helps! It took me literally about 2 weeks to get this working properly since you have to piece together information from several TI documents as well as Spectrum Digital code. I guess TI really wants this to be a challenge for engineers since its not well documented in any one place or application note.
Code On!