Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

PCI-6509 - interrupt handling issues

Solved!
Go to solution

<<posted for darius.dubash@ccur.com>>


I am basically seeing two problems: in providing interupt support for the PCI-6509 board:

1) To generate Falling or Rising Interrupts, I need to set THREE bits in the Master Interrupt Control Register: (1) Either Falling or Rising Edge IntEnable (2) Master Interrupt Enable (3) Edge Interrupt Enable. Without these three bits, an interrupt will not occur. I would have thought that the third Edge Interrupt Enable bit should have been an –OR- rather than an –AND- with the Falling/Rising Edge Enable bit. i.e. I was expecting that if we set Edge Interrupt Enable only with the Master Interrupt Control, I should get either rising or falling edge interrupt. Similarly, if I wanted only the Rising or Falling edge, there would be no need to set the Edge Interrupt Enable bit.
2) When a Falling or Rising Edge interrupt occurs, I get TWO back-to-back interrupts (1) with the correct Change Status Register value (0x15 for Falling edge interrupt or 0x0D for Rising edge interrupt) (2) a second interrupt with Change Status Register of 0x0. This second interrupt appears to be incorrect. Then next back-to-back interrupt occurs every 4 seconds.
3) If I repeat the step (2) with BOTH Falling or Rising Edge interrupts enabled, I get 4 back-to-back interrupts. One showing a status of Falling Edge + dummy interrupt (zero status) and the other showing a status of Rising Edge + dummy interrupt (zero status).

The setup:
1) I have a signal generator generating a square wave of 4 second period with an amplitude of +3V/0V connected to channel 0 (P0.0 – positive connected to pin 47, negative to ground pin 50).
2) Reset the board. All registers set to 0, All IOSelect set to 1 (for input).
3) Master Interrupt Control Register at offset 0x03 set to 0x15 for Falling Edge interrupt or 0x0D for Rising Edge Interrupt.
4) FallingEdgeEnable for channel 0 at offset 0x43 set to 1 if Falling Edge interrupt is to be detected, or RisingEdgeEnable for channel 0 at offset 0x42 set to 1 if Rising Edge interrupt is to be detected.
5) Interrupt Handler: (1) print Change Status Register at offset 0x02 (2) Set Clear Register at offset 0x01 to 0x7C.

Please verify the boards behavior and advise me about the findings. darius.dubash@ccur.com.

0 Kudos
Message 1 of 3
(8,246 Views)
Solution
Accepted by topic author RHebert

Hello Darius,

 

What operating system/platform are you using with this board?

 

1.  We also noticed that the three bits needed to be set in order to get an interrupt.  This is expected behavior.  Is this behavior preventing you from moving forward?

 

2.  From looking at our driver, there doesn't seem to be any indication about a double interrupt that occurs for each change detection.  One difference in our driver is that we write ClearEdge to the Clear Register instead of the blanket 0x7C.

 

Do you have a complete list of register accesses generated from your application so we can better compare the accesses?

 

Thanks,

Steven T.

0 Kudos
Message 2 of 3
(8,231 Views)
  •  What operating system/platform are you using with this board?

The system we are using our Linux Based, with the latest kernel.org kernel 2.6.32.13. The h/w is a Intel Based Xeon 3.20GHz CPU with 2 hyper-threads. Our kernel is a real time kernel is a high speed kernel that goes thorough the interrupt handler very fast.

 

  • 1. We also noticed that the three bits needed to be set in order to get an interrupt. This is expected behavior. Is this behavior preventing you from moving forward?

No, this does not prevent me from continuing. This was not a behavior that I would have expected. Consider this issue closed.

 

  • 2. From looking at our driver, there doesn't seem to be any indication about a double interrupt that occurs for each change detection. One difference in our driver is that we write ClearEdge to the Clear Register instead of the blanket 0x7C.

It does not matter what clear bits I use as I still get the spurious interrupt. My official driver only clears bits that are specific to the interrupt that occurred, i.e. it clears only the ClearEdge if the condition occurs. If an overflow occurs, it clears both Overflow and ClearEdge.

 

I believe the problem appears to be because we are running on a fast processor with a fast kernel and possible doing write posting. I put a delay in the interrupt handler before exiting it and was able to stop the spurious interrupts being generated. Playing some more with the code, I was able to provide a work around by issuing a dummy read of the change_status register after performing the clear of the interrupt. I believe this is forcing the NI-PCI 6509 hardware to clear the spurious interrupt. It is possible that the clear register call is being write posted, with the result that when I exit the interrupt handler, the PCI 6509 has still not cleared the interrupt and returns back to the interrupt handler as a spurious interrupt with a change_status of zero.

 

With this change, I am able to receive interrupts (both rise and fall edge) at a period of approx. 200 micro-seconds (by using a signal generator – square wave) without any missed interrupts or overflow condition. Anything lower than 150 micro-second period results in errors. I believe this is acceptable.

 

  • Do you have a complete list of register accesses generated from your application so we can better compare the accesses?

Before the workaround, the interrupt handler performed three register accesses: (1) read the master interrupt control register (2) read the change status register (3) based on the results of these two registers, determine which interrupts are pending and issue a clear register with appropriate bits.

The workaround (4th register access) is to issue a dummy read change status register if the clear register is written too.

0 Kudos
Message 3 of 3
(8,226 Views)