Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

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"

15 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- 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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.