/* This example illustrates the procedure to create and set up a simple * interrupt handler for the seven VXI interrupt levels. The procedure * involves creating a function that will get called everytime an interrupt * occurs. This function will get called * asynchrounously. That is, no matter what line your program happens to * be executing at the time the interrupt occurs, your handler function * will be invoked. When the handler completes, your main program will * continue from the point where it was interrupted. * * There are three major NI-VXI functions that you use to install an * interrupt handler. RouteVXIint instructs the driver on where to route * the interrupt. The first parameter specifies which controller to route the * interrupt for. Usually a '-1' is passed for this argument, which means use the * default controller. The second parameter is a bit vector that tells the driver * where to route a particular line. When a bit is zero, that tells the driver * to invoke an interrupt handler function for the level corresponding to that * bit position. If set to one, the interrupt is routed to the signal queue where * you can use signal functions to handler the interrupt. In this example, we'll * pass a zero to this parameter, telling the driver to set interrupt from any level * to an interrupt handler. * * SetVXIintHandler is what you use to set up a handler for a particular interrupt * level. The first parameter is a bit vector whose bits that are set to one indicate * what interrupt level we're setting the handler for. The second parameter is a pointer * to a function that will be invoked when an interrupt on one of those specified levels * occurs. We'll pass the value 0x7F for the first parameter so we can invoke the handler * no matter which interrupt level is asserted. * * EnableVXIint enables tells the CPU to watch for certain interrupt lines. We can use * the function DisableVXIint to tell the CPU to ignore certain levels. Each of * these functions takes a bit vector with bits corresponding to the different * interrupt lines and a parameter that specifies the controller we're enabling the * interrupts on. * * More information on these functoins can be found in the NI-VXI Software Reference * Manual in Chapter 10, 'VXI Interrupt Functions'. * */ #include "nivxi.h" #include #include #include NIVXI_HVXIINT myInterruptHandler; /* declare the custom interrupt handler * to be called at service time. */ int done = 0; /* set this to end program */ int interrupt_flag = 0; /* set this when handling an interrupt */ int number_of_interrupts = 0; main() { int iterations = 0; INT16 ret; printf("\nYou can use Victext with this example. In Victext, you can"); printf("\nassert interrupts by typing:"); printf("\n\n AssertVXIint -1, x, 0xfd00"); printf("\nwhere x is a number from 1 to 7 corresponding to the interrupt"); printf("\nline that you wish to assert. Refer to your documentation for more"); printf("\ninformation about AssertVXIint."); printf("\nIf you don't have VICtext running, you can quit this program,"); printf("\nlaunch VICtext, and run the program again to assert interrupts."); ret = InitVXIlibrary(); /* Always init the VXI library */ if (ret < 0) { printf("Init VXI library failed with %d\n", ret); exit(-1); /* if init fails, exit program */ } ret = RouteVXIint(-1, 0); /* Do not route interrupts to the * signal queue */ if (ret < 0) { printf("RouteVXIint failed with %d\n", ret); CloseVXIlibrary(); exit(-1); } ret = SetVXIintHandler(0x7F, myInterruptHandler); /* Tell NI-VXI to use * myInterruptHandler * as the interrupt * callback routine for * all seven levels*/ if (ret < 0) { printf("SetVXIintHandler failed with %d\n", ret); CloseVXIlibrary(); exit(-1); } ret = EnableVXIint(-1, 0x7F); /* Sensitize the CPU to all 7 * interrupt levels */ if (ret < 0) { printf("EnableVXIint failed with %d\n", ret); CloseVXIlibrary(); exit(-1); } printf("\nAssert an interrupt on line 3 or cntl-C to exit"); printf("\n"); /* new line */ while(!done) { /* This is the main program body. It will execute as long * as 'done' is cleared. Done will be set when you assert interrupt level 3. Notice below that the * interrupt handler sets the done variable when it detects an interrupt has * ocurred on level 3. */ iterations++; if (iterations%1000000 == 0) /* print a '.' every 1000000 loops */ printf("."); if (interrupt_flag) /* print a '!' everytime we get an interrupt * on any interrupt level. Notice that * the interrupt handler sets the * interrupt_flag variable. */ { printf("!"); interrupt_flag = 0; } } printf("\nNumber of interrupts: %d", number_of_interrupts); ret = DisableVXIint(-1, 0x7F); /* We're done, so tell the CPU to to * ignore subsequent interrupts */ ret = CloseVXIlibrary(); printf("\nPress any key to exit..."); while(!kbhit()); return 0; } NIVXI_HQUAL void NIVXI_HSPEC myInterruptHandler (INT16 controller, UINT16 level, UINT32 statusId) { /* This is the interrupt handler function. It is invoked whenever * an interrupt occurs on the VXI backplane. When this function * is called, we are given which controller handled the interrupt, * what level occured, and what the statusId passed by the device was. */ /* What we'll do in the handler is set a flag whenever an interrupt * happens, and we'll increment a variable that keeps track of the total * number of interrupts received. Also, if we get an interrupt on * level 3, tell the main program to stop by setting the done variable. */ number_of_interrupts++; interrupt_flag = 1; if (level == 3) done = 1; }