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
Thanks Simon!
But this doesn't work. I get the follow error:
'ISR_GPIO_SW8' undeclared (first use in this function)
Hilscher Gesellschaft fuer Systemautomation mbH
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.
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);
...
}
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
Setting the registers of the VIC is not enough.
Do you use the init functions of the VIC example?
Hi bilsen!
I'm just looking for the init functions of the vic example.
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.
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:
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
Hi taz!
I'm configuring an interrupt-driven uart2 receive, but it doesn't work by now.
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.
simon
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