Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Valued Contributor III
704 Views

Why Vectored Interrupt Controller IRQ -1 ?

Hello Friends i have added Vectored Interrupt Controller and generate the BSP but system.h reflect that VIC IRQ is -1 

 

/* VIC configuration */ 

 

#define ALT_MODULE_CLASS_VIC altera_vic 

#define VIC_BASE 0x11041000 

#define VIC_DAISY_CHAIN_ENABLE 0 

#define VIC_INTERRUPT_CONTROLLER_ID 0 

#define vic_irq -1 

#define vic_irq_interrupt_controller_id -1 

#define VIC_NAME "/dev/VIC" 

#define VIC_NUMBER_OF_INT_PORTS 8 

#define VIC_RIL_WIDTH 4 

#define VIC_SPAN 1024 

#define VIC_TYPE "altera_vic"
0 Kudos
15 Replies
Highlighted
Valued Contributor III
24 Views

That's correct. AFAIK those defines are used for internal interrupt controller

0 Kudos
Highlighted
Valued Contributor III
24 Views

thanking you Cris72, 

 

i found that rc = alt_ic_irq_enable(vic_interrupt_controller_id,vic_irq); 

 

always return -1,
0 Kudos
Highlighted
Valued Contributor III
24 Views

The second function parameter must rather be the actual irq you want to be enabled, not VIC_IRQ. 

Moreover, did you succeed in registering the interrupt? I mean, did you already call lt_ic_isr_register() without errors?
0 Kudos
Highlighted
Valued Contributor III
24 Views

 

--- Quote Start ---  

The second function parameter must rather be the actual irq you want to be enabled, not VIC_IRQ. 

Moreover, did you succeed in registering the interrupt? I mean, did you already call lt_ic_isr_register() without errors? 

--- Quote End ---  

 

 

sorry Cris i didn't get you i mean "actual irq" mean what..? 

 

in my understanding VIC will take all the Interrupt and manage them based on priority ...correct me if i am wrong 

 

but before that i need to enable alt_ic_irq_enable(); 

 

* Yes ! i already call lt_ic_isr_register() without errors. 

 

below is the code i am using for understanding enhance vector interrupt 

 

# include <stdio.h># include "sys/alt_irq.h"# include "system.h"# include "altera_avalon_pio_regs.h" volatile int edge_capture; void handle_load_data_interrupts(void* context, alt_u32 id) { volatile int* edge_capture_ptr = (volatile int*) context; IOWR_ALTERA_AVALON_PIO_IRQ_MASK(LOAD_DATA_BASE, 0x1 ); *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_DATA_BASE); IOWR_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_DATA_BASE, 0x1); IORD_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_DATA_BASE); } void init_load_pio() { void* edge_capture_ptr = (void*) &edge_capture; IOWR_ALTERA_AVALON_PIO_IRQ_MASK(LOAD_DATA_BASE, 0x1); IOWR_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_DATA_BASE, 0x1); alt_ic_isr_register(LOAD_DATA_IRQ_INTERRUPT_CONTROLLER_ID, LOAD_DATA_IRQ, handle_load_data_interrupts, edge_capture_ptr, 0x0); } int main() { int rc; rc = alt_ic_irq_enable(VIC_INTERRUPT_CONTROLLER_ID,VIC_IRQ); if(rc<0) printf("\n\tEnhance Interrupt not enabled, Return value = %d",rc); else printf("\n\tEnhnace interrupt enabled, Return value = %d",rc); printf("\n\tInitillize the Enhanced Interrupt.."); init_load_pio(); return 0; }
0 Kudos
Highlighted
Valued Contributor III
24 Views

Hello Cris, i think you are indicating the Hardware Interrupt, i mean my LOAD_DATA pulse which is coming form outside having priority no. 3.  

 

i write the LOAD_DATA in place of VIC_IRQ and it return 0, mean interrupt is enabled. 

 

Thanking you. 

 

Kaushal
0 Kudos
Highlighted
Valued Contributor III
24 Views

Exactly. That's what I meant. 

Regards
0 Kudos
Highlighted
Valued Contributor III
24 Views

Thanking you Cris 

 

Will This Code work in OS environment (uc/OS-II) also, currently i am using HAL based platform only for understanding VIC....? 

In OS environment lot's of interrupt driven module working simultaneously....like networking , RS-232,...etc 

i mean will this same code work over OS-environment without affecting other functionality... 

i wanted to use this VIC on my project where networking based application (Client) running. 

 

Regards 

 

kaushal
0 Kudos
Valued Contributor III
24 Views

Using interrupts in OS environment is usually not recommended because it's easy to mess up everything. 

Anyway I myself have used VIC with uC-OS and I confirm it works, provided you know EXACTLY what you are doing and you are very careful.
0 Kudos
Highlighted
Valued Contributor III
24 Views

Hello There, 

External Interrupt controller VIC have better speed performance then internal interrupt controller but in my sample code (below) for understanding VIC, won't reflect edge_capture status on pin TEMP_OUT_BASE  

 

like if edge_capture get high it will put 1 on TEMP_OUT_BASE otherwise put 0 on TEMP_OUT_BASE. 

 

my aim is to reading 2D-array whenever edge_capture get interrupt. 

 

"IOWR_ALTERA_AVALON_PIO_DATA(TEMP_OUT_BASE,0x1)" 

 

*i have attached my sopcinfo for refrence. 

 

int main() { int rc; unsigned long int count =0; printf("\n\tInitillize the Enhanced Interrupt.."); # ifdef LOAD_DATA_BASE init_load_data(); # endif rc = alt_ic_irq_enable(VIC_INTERRUPT_CONTROLLER_ID,LOAD_DATA_IRQ); if(rc<0) printf("\n\tEnhance Interrupt NOT enabled, Return value = %d\n",rc); else printf("\n\tEnhnace interrupt ENABLED, Return value = %d\n",rc); /* //---Should i add these alt_ic_irq_enable for other peripheral also...........?? rc = alt_ic_irq_enable(VIC_INTERRUPT_CONTROLLER_ID,JTAG_UART_IRQ); rc = alt_ic_irq_enable(VIC_INTERRUPT_CONTROLLER_ID,SYS_CLK_TIMER_IRQ); */ IOWR_ALTERA_AVALON_PIO_DATA(STRT_OUT_BASE,HIGH); //Generate Start Signal do { if(edge_capture) { IOWR_ALTERA_AVALON_PIO_DATA(TEMP_OUT_BASE,0x1); //TEMP_OUT not Visible on Oscilloscope edge_capture = 0; //Clear Interrupt //printf("\nHIGH"); //Visible on Console } IOWR_ALTERA_AVALON_PIO_DATA(TEMP_OUT_BASE,0x0); //printf("\t\tLOW\n"); //Visible on Console }while(1); return 0; }  

 

Regards 

 

kaushal
0 Kudos
Highlighted
Valued Contributor III
24 Views

You set TEMP_OUT to 1 then you immediately deassert it to 0. If you are sure your isr is being serviced, then you simply can't see the pulse on oscilloscope because the signal doesn't have enough time to switch high. 

Add some delay before IOWR_ALTERA_AVALON_PIO_DATA(TEMP_OUT_BASE,0x0) 

You could also toggle TEMP_OUT upon receipt of edge_capture and then connect the pio to some logic which generates a fixed length pulse on each transition.
0 Kudos
Highlighted
Valued Contributor III
24 Views

 

--- Quote Start ---  

You set TEMP_OUT to 1 then you immediately deassert it to 0. If you are sure your isr is being serviced, then you simply can't see the pulse on oscilloscope because the signal doesn't have enough time to switch high. 

Add some delay before IOWR_ALTERA_AVALON_PIO_DATA(TEMP_OUT_BASE,0x0) 

You could also toggle TEMP_OUT upon receipt of edge_capture and then connect the pio to some logic which generates a fixed length pulse on each transition. 

--- Quote End ---  

 

 

adding delay may result loosing some of interrupt... 

 

i have done this exercise using Internal interrupt without VIC and comfortably able to see edge_capture register status on oscilloscope using same procedure. 

 

as i got the edge_capture status HIGH i assert HIGH on TEMP_OUT and then this value visible on oscilloscope.
0 Kudos
Highlighted
Valued Contributor III
24 Views

Hello There, 

 

vic start working .....without os (uc/os-ii). 

 

Still struggling with OS environment..... 

 

i add the same peace of code in OS environment....but it won't work. 

 

below is the sample code which i am using in OS environment.... 

 

what else i should add in my OS environment to start Enhance interrupt 

 

/* MicroC/OS-II definitions */ # include "includes.h" /* Simple Socket Server definitions */ # include "simple_socket_server.h" /* Nichestack definitions */ # include "ipport.h" # include "tcpport.h" //--------------------------------------------------------------------------------- # define HIGH 1 # define LOW 0 /* A variable to hold the value of the button pio edge capture register. */ //---------------------------------------------------------------------------------- # define PktSize 640 # define PktCount 460 unsigned char ImgBuff={0}; volatile int edge_capture; # ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT static void handle_load_interrupts(void* context) # else static void handle_load_interrupts(void* context, alt_u32 id) # endif { // Cast context to edge_capture's type. It is important that this be declared volatile to avoid unwanted compiler optimization. volatile int* edge_capture_ptr = (volatile int*) context; // Read the edge capture register on the button PIO. Store value. *edge_capture_ptr = IORD_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_DATA_BASE); // Write to the edge capture register to reset it. IOWR_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_DATA_BASE, 0x1); // Read the PIO to delay ISR exit. This is done to prevent a spurious interrupt in systems with high processor -> piolatency and fast interrupts. IORD_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_DATA_BASE); } /* Declare a global variable to hold the edge capture value. */ //volatile int edge_capture; // Initialize the LOAD_DATA PIO. static void init_load_data() { // Recast the edge_capture pointer to match the alt_irq_register() function prototype. void* edge_capture_ptr = (void*) &edge_capture; // Enable LOAD interrupts. IOWR_ALTERA_AVALON_PIO_IRQ_MASK(LOAD_DATA_BASE, 0x01); // Reset the edge capture register. IOWR_ALTERA_AVALON_PIO_EDGE_CAP(LOAD_DATA_BASE, 0x1); // Register the ISR. # ifdef ALT_ENHANCED_INTERRUPT_API_PRESENT alt_ic_isr_register(LOAD_DATA_IRQ_INTERRUPT_CONTROLLER_ID,LOAD_DATA_IRQ,handle_load_interrupts,edge_capture_ptr, 0x0); # else alt_irq_register( LOAD_DATA_IRQ,edge_capture_ptr,handle_load_interrupts ); # endif } void SSSSimpleSocketServerTask() { int rc; unsigned int LPktCount = 0,Count =0;//,mycount =0; unsigned int DataCount = 0; //---VECTORED INTERRUPT CONTROLLER------------------------------------------------- printf("\n\tInitillize the Enhanced Interrupt.."); # ifdef LOAD_DATA_BASE init_load_data(); # endif rc = alt_ic_irq_enable(VIC_INTERRUPT_CONTROLLER_ID,LOAD_DATA_IRQ); if(rc<0) printf("\n\tEnhance Interrupt NOT enabled, Return value = %d\n",rc); else printf("\n\tEnhnace interrupt ENABLED, Return value = %d\n",rc); //Should i add these highlighted portion to enable other ibterrupt also.. rc = alt_ic_irq_enable(VIC_INTERRUPT_CONTROLLER_ID,HIGH_RES_TIMER_IRQ); if(rc<0) printf("\n\tHIGH RES TIMER not Enabled, Return value = %d\n",rc); else printf("\n\tHIGH RES TIMER ENABLED, Return value = %d\n",rc); rc = alt_ic_irq_enable(VIC_INTERRUPT_CONTROLLER_ID,SYS_CLK_TIMER_IRQ); if(rc<0) printf("\n\tSYS CLOCK TIMER not Enabled, Return value = %d\n",rc); else printf("\n\tSYS CLOCK TIMER ENABLED, Return value = %d\n",rc); //------------------------------------------------------------------------------------ usleep(10000); //------------------------------------------------------------------------------------------ IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xFC); fflush(stdin); fflush(stdout); LPktCount = 0; Count = 0; usleep(10000); while(1) { DataCount = 0; LPktCount = 0; printf("\n\t# Read Data at Edge Capture-Interrupt"); //------Enable start in for serializear------------------- Count = 0; LPktCount = 0; edge_capture = 0; IOWR_ALTERA_AVALON_PIO_DATA(STRT_OUT_BASE,HIGH); //Generate Start Signal do { if(edge_capture) { edge_capture = 0; //Clear Interrupt IOWR_ALTERA_AVALON_PIO_DATA(TEMP_OUT_BASE,1); //Send High to Test Pin TEMP_OUT IOWR_ALTERA_AVALON_PIO_DATA(DATA_BASE,ImgBuff); //Send Data to DATA Bus Count++; printf("\nHIGH"); //not getting High } if(Count == PktSize) //check end of packet-data { Count = 0; //Point to Start of packet data LPktCount++; //Increment packet Count } IOWR_ALTERA_AVALON_PIO_DATA(TEMP_OUT_BASE,0); //Send LOW to Test Pin TEMP_OUT printf("\nLOW"); //always getting low }while(LPktCount != (PktCount+1)); IOWR_ALTERA_AVALON_PIO_DATA(STRT_OUT_BASE,LOW); //Generate Stop Signal //printf("\n\t# Assert LOW"); printf("\n\t#%d\t%d\t%d",ImgBuff,ImgBuff,ImgBuff); printf("\n\t#Send Done..!!\n"); usleep(100000); IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE,0xF0); } printf("\n\t\t\tConnection Closed ..."); } //Close Simple_SOcket_Server
0 Kudos
Highlighted
Valued Contributor III
24 Views

If I remember correctly your irq must have higher priority than the interrupts used by OS. 

In the case of SSS application, you must assign a lower priority to system timer and network IRQs.
0 Kudos
Highlighted
Valued Contributor III
24 Views

Hello Cris, 

 

as soon as i given lower priority to sys_clock_timer etc.,It start working in OS (uC/OS-II) environment.  

 

just for curiosity why this happen , mean why lowering the sys_clock_timer priority will trigger my application ?. 

 

regards 

 

kaushal
0 Kudos
Highlighted
Valued Contributor III
24 Views

Most OS relies on a few hw interrupts for scheduling tasks and performing other time critical tasks. 

As I said before, I believe uC/OS only uses system timer and network interrupt. 

All other application interrupts are actually sw emulated by OS which calls the proper isr when the hw event occurs; so these IRQs works in polling mode, instead of using interrupts controller and the irq table. The application tasks themselves are indeed executed as part of the timer/scheduler isr 

Your application can override this and request 'real' interrupts to be serviced, like you did. However this will never work if the OS IRQs (thus the application task which is supposed to be interrupted) have higher priority.
0 Kudos