/***************************************************************************** * This code will watch for an interrupt on the line specified by the user. * * You must be careful which interrupt you select because at least one * * interrupt is reserved for use by the system. In addition, when asserting * * an interrupt, some status/ID's will not be serviced by the installed * * VXIhandler. The reason is that the driver will automatically service the * * interrupts from the MITE and TIC chip and will recognize these interrupts * * by their Status/ID's. The status/ID 0xFD00 will always be serviced. * * Therefore use this as the status/ID when asserting an interrupt from VIC * * or VICtext. * ******************************************************************************/ #include #include #include #include static char ch; static int int_to_watch, Received_level, intevent = 0; static unsigned int level, Received_statusid; static unsigned short int irq_levels, Sroute, MyLevels; static NIVXI_STATUS Status; static NIVXI_HVXIINT *new_irq_handler; static short int controller; /**************************************************************************** * The following code is the interrupt handler. In this handler, I get the * * data concerning the interrupt and save it to global variables so that it * * can be seen in later code. DO NOT attempt to do any UIR or stdio calls * * inside the handler. Save the info that you need to a global, then exit * * the handler as quickly as possible and manipulate the globals later. * ****************************************************************************/ NIVXI_HQUAL static void NIVXI_HSPEC MyVXIintHandler (INT16 ctrlr, UINT16 level, UINT32 statusid) { Received_statusid = statusid; //save status/ID to global. Received_level = level; //save the level the int was seen on intevent = 1; //set flag so I know an interrupt occurred. } /*************************************************************************** * Here is the main code. First I setup the handler, but do not sensitize * * the CPU to the interrupt level. This is becuase "main" is only executed * * once while the call-back "Detect" is executed every time the user presses* * the "Detect" button. The general flow of the code (excluding UIR fancy * * stuff) is: * * * * 1) InitVXIlibrary: used to initialize the VXI library * * 2) SetVXIintHandler: changes from the default handler to the handler * * that I have written. * * 3) RouteVXIint: to handle interrupts by interrupt handler, not signal * * 4) EnableVXIint: to sensitize CPU to the interrupt level. * * 5) stay in a loop until we see the interrupt. * * 6) CloseVXIlibrary: uninitializes the VXI library. * ***************************************************************************/ void main () { Cls(); //clear STDIO window if ( InitVXIlibrary() ) //This function must be called in order to user VXI func. { printf ("Unable to initialize the VXI library... exiting.\n"); exit(0); //if can't initialize the library -> quit. } /* * I now need to replace the current interrupt handler my new handler * called "MyIntVXIHandler". To do this, use function SetVXIintHandler. * The parameters for this function are: * * irq_levels: bit vector of the VXI interrupt levels for which the * current interrupt handler will handle. * new_irq_handler: a pointer to the new VXI interrupt handler. */ irq_levels = 0x7F; //I will assume to handle all interrupts. new_irq_handler = MyVXIintHandler; //point to the handler code above. Status = SetVXIintHandler (irq_levels, new_irq_handler); if ( Status ) printf ("Unable to set the new interrupt handler\n"); /* * Now we need to specify whether the status/ID value is routed toward * the VXI interrupt handler or toward the signal interrupt handler. In * this code, we will route the status/ID into the interrupt handler. * Parameters are as follows: * * controller: logical address of the controller to use. A value * of -1 denotes the local controller. * Sroute: a bit vector that specifies whether to handle VXI interrupt * as a signal or route it to the VXI interrupt handler. */ controller = -1; //use default controller. Sroute = 0x0; //handle all interrupt status/ID's by int handler Status = RouteVXIint (controller, Sroute); if ( Status ) printf ("Unalbe to route interrupts.\n"); /* * We need to find out which interrupt the user wants to watch. */ printf ("Which interrupt do you want to watch? (1-7) >> "); scanf ("%d", &int_to_watch); /* * Now we will sensitize the CPU to the interrupt level specified * by the user. The parameters are: * * controller: the logical address of the controller to use. A * value of -1 denotes the local controller. * level: a bit vector that indicates which VXI interrupts to enable. */ controller = -1; //use default controller. level = 1 << int_to_watch-1; //create the bit vector with the correct bit set. Status = EnableVXIint (controller, level); if ( Status ) printf ("Could not enable this interrupt. Are you the handler for it?\n"); /* * Now whenever there is a VXI interrupt on the level specified by the user, * it will be serviced by the installed handler. You can generate an interrupt * while running this code by using VIC. */ intevent = 0; //clear the flag that says that there was an interrupt printf ("Waiting for interrupt...\n"); while ( intevent == 0 ) { //wait in this loop until an interrupt is seen on the correct level } //since we have dropped out of the loop, we saw an interrupt. Need to report results. printf ("An interrupt was see on IRQ %d\n", Received_level); printf ("Status/ID = 0x%x\n", Received_statusid); printf (""); getchar (); scanf ("%c", &ch); //wait for user to hit a key to quit CloseVXIlibrary(); //uninitialize VXI library }