Category Name > Knowledge Base
KB00382: Using Interrupts on SyncClcok

Interrupt processing on the SYNCCLOCK

The SYNCCLOCK hardware interface to the PCI bus uses a FPGA containing the timing related registers which sits on a 32 local bus and a PLX PCI to local bus bridge device.

                              | PCI BUS | | PCI90XX | | 32 bit local bus| |FPGA|
                            gates LINTi
                            to gen INTA#

For non-interrupt programming of the SYNCCLOCK, no access to the registers inside the PLX part is needed - a user call to selectsyncclock maps all the SYNCCLOCK registers to user space. So, users don't have to deal directly with the PLX API. (The registers inside the PCI90XX are initialized by a EEPROM on the SYNCCLOCK board and by the host BIOS).

The FPGA device on the SYNCLOCK board generates an on-board interrupt request signal (LINTi1) which goes through the PLX device to drive the INTA# PCI bus interrupt request line when LINITi1 interrupt enable is set inside the PLX device (PCI9030 or PCI9050 or PCI9056). Inside the host backplane, multiple INTA# signals or Ored to drive a small number of IRQ levels. The IRQ level for a given device is usually assigned (along with the device's PCI address spaces) by the BIOS at power up. The operating system can change the assignments, but usually doesn't.

The SYNCCLOCK FPGA asserts the LINTi1 internal signal when (in standard boards):

a. An external time tag is ready (Ext_Ready=1) AND external time tag interrupts are

enabled (Ext_Intr_Enb=1)


b. A heartbeat has occurred (Heartbeat =1) AND heartbeat interrupts are enabled



c. a time match has occurred (Match=1) AND time match interrupts are enabled


SYNCCLOCKS with -TAG8I or some other options will have more/different ready/interrupt enable combinations.

The LINTi1 internal signal will assert the INTA# PCI bus interrupt request if the appropriate LINTi1 interrupt enable bit inside the PLX device is set - usually under PLX driver control.

Interrupt programming requires that more of the PLX API be used because:

  1. The PLX driver/API/dll is called every time its' shared IRQ line is asserted - even for non-SYNCCLOCK interrupts.. When a IRQ line is asserted, the driver for every device using that IRQ is called to determine if that device is causing the IRQ. When a device driver recognizes that its' hardware is causing the IRQ, the driver must make the IRQ de-assert. The PLX driver knows if it is asserting INTA# (without ANY knowledge of SYNCCLOCK registers) by knowing if LINTi1 is asserted AND if LINITi1 interrupt is enabled.
  2. Because the PLX device supports many types of user devices, it doesn't know how to de-assert the INTA# by reading SYNCCLOCK registers or disabling SYNCCLOCK interrupt enable bits. Instead, it turns off the LINTi1 interrupt enable inside the PLX device. So, user code specific to the SYNCCLOCK must then
    1. Clear the internal LINTi1 signal by (for standard boards with no options affecting interrupts)
      1. Reading the external time tag data (which will clear Ext_Ready)
      2. Clearing Heartbeat by writing Reset_Heartbeat to Status_Port
      3. Clearing Match by writing Reset_Match to Status_Port

The user application, based on which SYNCCLOCK interrupt enables are set will know whether to do 1. 2. or 3. If the user application has more than one of the SYNNCLOCK's interrupts enabled, the application will need to see which status bits (Ext_Ready,Match,Heartbeat) are set to decide which of 1. , 2. or 3. to perform.

  1. Make an API call (PlxIntrEnable)so the driver/DLL re-enables the LINITi1 interrupt enable for more SYNCCLOCK interrupts.

Why do we use the PLX driver (with no knowledge of SYNCCLOCK interrupt enables) instead of a custom driver ?

  1. PLX assumes burden of keeping up with OS changes in Windows and Linux.
  2. No driver changes are needed for supporting different SYNNCLOCK options
  3. As new PLX devices become available (for example PCI9056 used in Turbo), drivers are already ready.
Supportscreen tag