[an error occurred while processing this directive]
  Home    Prev Next    
Contents
Programming For PCI Device
Overview
Programmers Guide
Scenario
Access to PCI devices information
How to work with PCI header
Accessing PCI registers
Accessing BAR0-BAR5 areas
I/O Ports control
Single read/write operations
Data array read/write operations
Accessing Physical Memory Addresses
Memory Mapping
Additional Functions
Hardware interrupts handling at user level
Common Issues
Extended options of hardware interrupt handling
PCI Support Routines And Structures
Common Procedures
OpenRapidPci
IsRapidPciOpened
CloseRapidPci
GetHardwareConfiguration
GetPciLocation
PCI specific functions
PCI Header
GetPciHeader
SetPciHeader
ReadFromPci
WriteToPci
PCI BAR Areas
GetNumOfPciBars
GetPciBarLength
GetPciBarPhysicalAddress
GetPciBarLinearAddress
ReadPciBarByte
ReadPciBarWord
ReadPciBarLong
WritePciBarByte
WritePciBarWord
WritePciBarLong
PCI Registers
ReadPciCommandReg
WritePciCommandReg
ControlPciCommandRegBits
ReadPciStatusReg
Memory Access
MapPhysToLinear
UnmapMemory
GetMem
GetMemW
GetMemL
SetMem
SetMemW
SetMemL
Direct Port I/O
GetPortByte
GetPortWord
GetPortLong
SetPortByte
SetPortWord
SetPortLong
ReadPortBuffer
WritePortBuffer
Hardware Interrupts
UnmaskPciIrq
MaskPciIrq
GetInterruptCounter
Extended options of hardware interrupt handling
Go to RapidDriver Main Page

As it was mentioned earlier, there are two main problems when we are trying to handle PCI interruption.
First, all PCI interruptions are shared. It means that we must provide information for driver to determine if it is our interruption or not.
Second, it's very important for level sensitive interrupts to inactivate bus interrupt level just after it's activation (clear interruption or acknowledge interruption, in other words).

Let's assume that we have to write 0x0F0F to some register for interrupt acknowledge. Register is a word displacement 0x320 in the memory area with the physical address 0x3C000:
 
IRQ_CLEAR_REC ClearRec;  // Clear control structure  
      
IRQ_SHARE_REC ShareRec;  // sharing control structure  
     
memset(&ClearRec,0,sizeof(ClearRec)); // clean structures    
memset(&ShareRec,0,sizeof(ShareRec));  
 
ClearRec.ClearIrq = 1; // Interrupt acknowledge needed  
ClearRec.TypeOfRegister = 1; // Register type - memory-mapped  
ClearRec.WideOfRegister = 2; // Register size - 2 bytes (a word)    
ClearRec.ReadOrWrite = 1;    // acknowledge means write to a register  
ClearRec.RegBaseAddress = 0x3C000;  // base physical memory address  
ClearRec.RegOffset = 0x320; // register first byte displacement in memory  
 
ClearRec.ValueToWrite = 0x0F0F;    // A value to write to a register for interrupt acknowledge  


Also assume we should see 1 in bit 5 of memory mapped register if it is our interruption and the driver must handle it.
 
ShareRec.ShareIrq = 1; // Irq can be shared  
ShareRec.TypeOfRegister = 0; // memory-mapped register  
ShareRec.WideOfRegister = 1; // 1 - Byte  
SharRec.RegBaseAddress = PhysAddr; // Memory register base address  
ShareRec.RegOffset = 0x40; // Register offset  
ShareRec.MaskValue = 0x20; // Bitmap mask to make AND operation  
ShareRec.ResultMask = 0x20; // What should be in result if it is our interrupt  
 
// Set an interrupt handler and unmask Irq  
UnmaskPciIrq(hPci,&ShareRec, &ClearRec,MyInterruptHandler);  
 
   Copyright © 1997-2008, EnTech Taiwan.