industrialNETworXnetx

KJD

KJD

| 15.08.2008 | 14:45 | 12 replies

Interrupt - ISR vector address

Hi!
I'm using the nxhx500-re with the netx500.
I try to create an external interrupt at GPIO15. To do this i configure the follow registers:

-VIC_INT_EN = 0x00000040; //Enable Interrupt GPIO 15
-VIC_VECT_CTRL0 = 0x00000026; //Enable Vector Interrupt
//Interrupt Source -> GPIO 15
-GPIO_IRQ_MSK_SET = 0x00008000; //GPIO 15 Interrupt enable

Now my problem:
In the register VIC_VECT_ADDR0 i have to fill in the ISR vector address. I wrote a function which is called "ISR_GPIO_SW8". This function should be my ISR.

How i get the startaddress of this function into the "VIC_VECT_ADDR0" register?
In my understanding, if an interrupt ist generated my function (ISR_GPIO_SW8) would be called. Is that right?
Are there any examples on how to initialise interrupts and ISR's?

Thanks

simon

simon

| 15.08.2008 | 15:08

I'd try to put the address of the function (obtain this with the address-of operator) into the corresponding register:
POKE(VIC_VECT_ADDR0, &ISR_GPIO_SW8);

I haven't tested this, but I'm fairly certain it should work.

HTH

simon

KJD

KJD

| 15.08.2008 | 15:13

Thanks Simon!
But this doesn't work. I get the follow error:
'ISR_GPIO_SW8' undeclared (first use in this function)

Andreas Jacob

Andreas Jacob

Hilscher Gesellschaft fuer Systemautomation mbH

| 15.08.2008 | 15:24

Hi,

please have a look into the following topic: Interrupts, NXSB 100.

There you will find an example which shows how to configure the VIC.

KJD

KJD

| 15.08.2008 | 15:26

Thank You AJ!

simon

simon

| 15.08.2008 | 15:34

Where do you declare your function? You either have to write the function in the same file above the code where you try to set the interrupt handler or you have to write the function header in the code file before you try to take the address of your function.
variant 1:

void ISR_GPIO_SW8() {
...
}

void init_interrupts() {
...
POKE(VIC_VECT_ADDR0, &ISR_GPIO_SW8);
...
}

variant 2:

void ISR_GPIO_SW8(); /* declaration, so the compiler knows about your handler */

void init_interrupts() {
...
POKE(VIC_VECT_ADDR0, &ISR_GPIO_SW8);
...
}

/* implementation of the handler */
void ISR_GPIO_SW8() {
...
}

variant 3:

/* file: isr.c */
#include "isr.h"

/* implementation */
void ISR_GPIO_SW8() {
...
}



/* file: isr.h */
void ISR_GPIO_SW8();


/* file: init.c */
#include "isr.h"

void init_interrupts() {
...
POKE(VIC_VECT_ADDR0, &ISR_GPIO_SW8);
...
}

KJD

KJD

| 18.08.2008 | 15:59

Hi! Thanks Simon!

My program is build without any warnings or erros now.
But if i generate an interrupt at gpio12 (i changed my project from sw8 to gpio12), my isr won't be called.
Here's my code:

void init_VIC (void)
{
GPIO_CFG12 = 0x00000000;
VIC_INT_SEL = 0x00000000; //Only generate IRQ interrupts
VIC_INT_EN = VIC_INT_EN | 0x00001000; //Enable Interrupt GPIO 12
VIC_VECT_CTRL0 = VIC_VECT_CTRL0 | 0x00000030; //Enable Vector Interrupt
//Interrupt Source -> GPIO 12
GPIO_IRQ_MSK_SET = GPIO_IRQ_MSK_SET | 0x00001000; //GPIO 12 Interrupt enable
VIC_VECT_ADDR0 = (unsigned long)&isr_GPIO; //ISR Vector Adress

}


void isr_GPIO ( void )
{
while (1)
{
unsigned int IN = PIO_IN;
PIO_OUT = ~((IN & 0x00008000) <<8) ;
}
/* clear interrupt in VIC */
VIC_VECT_ADDR=0;
}

void isr_Default ( void )
{
/* clear interrupt in VIC */
VIC_VECT_ADDR=0;
}

Could anybody tell me what's wrong?
Thanks

Burkhard Ilsen

Burkhard Ilsen

Hilscher GmbH

| 19.08.2008 | 14:44

Setting the registers of the VIC is not enough.
Do you use the init functions of the VIC example?

KJD

KJD

| 19.08.2008 | 15:42

Hi bilsen!

I'm just looking for the init functions of the vic example.

Burkhard Ilsen

Burkhard Ilsen

Hilscher GmbH

| 19.08.2008 | 16:30

This topic is rather ARM specific. I'll try to recover what I know about this...

The VIC is a piece of hardware that puts a value into a register if an interrupt occurs - nothing more.

The interrupts must be enabled for the ARM CPU by setting a flag in the CPSR.
On interrupt, the CPU's program counter is set to address 0x18 - nothing more.

Now the CPU and the VIC need to work together, they don't do it automaticly.

What must happen on interrupt:
1. interrupt occurs
2. VIC sets ISR address at VIC_VECT_ADDR
3. CPU jumps to 0x18 - no problem until here
4. at 0x18 is a command that says: "Jump to the super-interrupt-handler, you find it's address at 0x20"
5. CPU jumps to super-interrupt-handler that does the following:
6a. read the ISR address from VIC_VECT_ADDR - VIC is locked
6b. execute ISR
6c. clear VIC_VECT_ADDR - VIC is unlocked

6a - 6c is implemented in the function IRQVectorHandler_C in the example.

Initially we have to do the following:
- disable interrupts - call IRQFIQ_LOCK or better fktIrqFiq_Lock()
- setup the CPU's vector table (put the jump command at 0x18 and store the ISR address at 0x20) - this is done by install_isr_vector(IRQVectorHandler_C);
- config the VIC (you have done this already)
- enable interrupts for the CPU - call IRQFIQ_UNLOCK or better fktIrqFiq_Unlock()

I hope this helps.

KJD

KJD

| 21.08.2008 | 11:35

Thank you bilsen!

| 21.10.2008 | 16:03

Hi

I'm configuring an interrupt-driven uart2 receive, but it doesn't work by now.
I read your posts and you wrote:

void init_VIC (void)
{
GPIO_CFG12 = 0x00000000; 
VIC_INT_SEL = 0x00000000; //Only generate IRQ interrupts
VIC_INT_EN = VIC_INT_EN | 0x00001000; //Enable Interrupt GPIO 12
VIC_VECT_CTRL0 = VIC_VECT_CTRL0 | 0x00000030; //Enable Vector Interrupt 
//Interrupt Source -> GPIO 12
GPIO_IRQ_MSK_SET = GPIO_IRQ_MSK_SET | 0x00001000; //GPIO 12 Interrupt enable 
VIC_VECT_ADDR0 = (unsigned long)&isr_GPIO; //ISR Vector Adress 

}

I think you enabled SPI interrupt, not GPIO interrupt, because of "VIC_INT_EN = VIC_INT_EN | 0x00001000; //Enable Interrupt GPIO 12", right mask is 0x00010000.

Anyway, does your ISR work now?
If so, please tell me what you write in the ISR body and in the interrupt initialization.
I use pure C, not rcX.
What about:

Quote:
3. CPU jumps to 0x18 - no problem until here
4. at 0x18 is a command that says: "Jump to the super-interrupt-handler, you find it's address at 0x20"
5. CPU jumps to super-interrupt-handler that does the following:

Thanks a lot

Burkhard Ilsen

Burkhard Ilsen

Hilscher GmbH

| 21.01.2009 | 14:46

Hi taz!

taz wrote:

I'm configuring an interrupt-driven uart2 receive, but it doesn't work by now.

Sorry for late reply, is your code still not working?

taz wrote:

I think you enabled SPI interrupt, not GPIO interrupt, because of "VIC_INT_EN = VIC_INT_EN | 0x00001000; //Enable Interrupt GPIO 12", right mask is 0x00010000.

You are right, thank you for that!
Anyway, it's better to use the #defined mask (in this case: MSK_NETX_VIC_IRQ_STAT_gpio)

Login