Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

Why one interrupt request causes multiple times of responses (isr)?

Hi, Folks
 
I have a GPCT0 timer which will generate interrupt. with a oscilloscope, every time I run the code I saw a pulse was generated at the G0 output, but the isr run 51 times when I open the NI SPY to monitor it. When I turned off the NI SPY, it happened 6 to 8 times. I enabled the visa event, then configured the timer and turned on the hardware interrupt. Here is the code in main:
 
// enable the G0_TC interrupt
 theSTC->Interrupt_A_Enable.setG0_TC_Interrupt_Enable(1);
 theSTC->Interrupt_A_Enable.setG0_Gate_Interrupt_Enable(0);
 theSTC->Interrupt_A_Enable.flush();
 theSTC->Analog_Trigger_Etc.setGPFO_0_Output_Select(0);
 theSTC->Analog_Trigger_Etc.setGPFO_0_Output_Enable(1);
 theSTC->Analog_Trigger_Etc.flush();
// enable the interrupt A
 theSTC->Interrupt_Control.setRegister(0); // reset complete register
 theSTC->Interrupt_Control.setInterrupt_Output_Polarity(theSTC->Interrupt_Control.kInterrupt_Output_PolarityActive_Low);  
 theSTC->Interrupt_Control.setInterrupt_A_Output_Select(0);  
 theSTC->Interrupt_Control.setInterrupt_A_Enable(1);
 theSTC->Interrupt_Control.flush();
// start to run the timer
 theSTC->G0_Command.writeG0_Arm(1);

Here is code in the isr:
 
ViStatus _VI_FUNCH IHandler(ViSession vi, ViEventType etype, ViEvent event, ViAddr uhandle)
{
 tAddressSpace  Bar0, Bar1;
 tESeries *board;
 tSTC *theSTC;
 tMITE *mite;
 Bar0 = bus->createAddressSpace(kPCI_BAR0);
 Bar1 = bus->createAddressSpace(kPCI_BAR1);
 mite = new tMITE(Bar0);
 board = new tESeries(Bar1);
 theSTC = new tSTC(Bar1);
 i = i++;
 theSTC->Interrupt_A_Ack.writeG0_TC_Interrupt_Ack(1);
 theSTC->Interrupt_A_Enable.writeG0_TC_Interrupt_Enable(0);
 theSTC->Interrupt_Control.writeInterrupt_A_Enable(0);
/*
(function code here)
*/
 mite->LocalCpuInterruptMask2.setSetCpuIntIE(1);
 delete mite;
 delete theSTC;
 delete board;
 bus->destroyAddressSpace(Bar0);
 bus->destroyAddressSpace(Bar1);
 return VI_SUCCESS;
}
 
I suspect that there may be someting wrong with data passing between main and isr, don't know for sure.
Any help and advice will be appreciated greatly.
 
Best regards,
George
0 Kudos
Message 1 of 4
(7,510 Views)
Hi George,

I'm confused on what the interrupt handler is trying to do.   By disabling interrupts you should not get any more interrupts after the first interrupt is handle.  I think you are saying the problem is that the interrupt only occurs 51 times, but I don't know how it happens more than once!?.  Is there something missing?

---------------------------

One thing not related to the device programming... the interrupt event callback should not be create and destroy (new/delete) the chip objects eveytime is called for these reasons:
- The chipobjects maintain softcopies of the registers and they model the state of the hardware.  The new object does not represent the currently configured device.  There should be one instance of the chip the object is representing.  You should create one instance of the tSTC because there's one STC in the device.
- Memory operations can be very expensive.  A lot of time is consumed creating and destrying these objects.  Add to that the constructor and destructors of each object, which are called for every new and delete.

To solve both problems use the 'userHandle' parameter in viInstallHandler, from the description:

Applications can specify a value in the userHandle parameter that is passed to the handler on its invocation. VISA identifies handlers uniquely using the handler reference and this value.

This userHandle provides context for your interrupt callback.  If you only need the STC object to service the interrupt you can pass a pointer to the STC object as the user handle.  In your handler you would use the userHandle argument to get to the STC object:


ViStatus _VI_FUNCH IHandler(ViSession vi, ViEventType etype, ViEvent event, ViAddr uhandle)
{
    tSTC *stc;

    stc = (tSTC *) uhandle;

    stc->...
    [...]
}


Diego
0 Kudos
Message 2 of 4
(7,493 Views)

Hi, Diego

Thanks for the help.

One interrupt request should only invoke one time ISR. That's what I need. But what I got was too many times responses to one request.

I moved declaration of tSTC *theSTC, tESeries *board and tMITE *mite to outside as the file level globals. Problem is still there.

Best regards,

George  

0 Kudos
Message 3 of 4
(7,486 Views)
Hi George,

Thanks for the clarification.  Here's my guess...  If the interrupt rate is too fast the VISA interrupt event handler could run after several interrupts have occur.  Try slowing down the interrupt rate to verify if this is the case.

The reason is that the VISA event handler is not (can't be) the hardware level isr.  When an interrupt occurs, VISA's interrupt service routine uses the information in the inf file to detect and acknoledge the interrupt.  If an interrupt is correctly handle, an event is queued to notify thesession that an interrupt was received.  The event handler callback is a separate thread in user mode that's signal to run when there are events in this queue.  If the interrupts occur fast enough the OS might not have time to schedule the event handler thread, while VISA continues to receive interrupt and add events to the queue.

If this is what's happening, one solution would be to add the disable interrupt sequence in the inf file (using the VISA driver wizard).  This sequence is executed in the primary isr and would disable interrupts after the first one is handled.

Let me know what happens,
Diego.

0 Kudos
Message 4 of 4
(7,474 Views)