📄 pci.all
字号:
/*
'**********************************************************************
'* Program : CNTINT.C *
'* Revision : 1.00 *
'* Date : 06/25/2002 Arbor dvantech Corp. *
'*====================================================================*
'* *
'* pDAQ-722 has 2 16-bit Timer supporting this feature. *
'* They generate INTERRUPT if reaching the terminal count. *
'* *
'* This demo program performs Counter Interrupt by using Counter 2. *
'* It will generate interrupt after 100 event counts. *
'* *
'**********************************************************************
*/
#include <dos.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include "PCI.C"
#include "pDAQ722.h"
/************
* Global variable declare
************/
dword gdwBaseAddr; //CS0 Base address
dword gdwBaseAddrCs1; //CS1 Base address
dword gdwBaseAddrBa1; //Local contrl Base address
int giIrqNum; //IRQ number
int giIntControlRegAddr; //pDAQ-722 Interrupt control ragister address.
int giIrqFlagBit; //Interrupt flag
long glIntCount; //Interrupt generate count
/***********
* Local fucntion declare
***********/
void interrupt IrqHandler(void);
byte InitInterrupt( int iIrqNum,
void interrupt (*pIsrHandler)(),
void interrupt (**pOldIsr)() );
void RestoreOldIsr(int iIrqNum, byte ucIrqMask, void interrupt (*pOldIsr)() );
void main(void)
{
word wVendorId, wDeviceId, wIndex;
int iErrCode;
byte ucBusNumber, ucDevAndFunc;
dword dwData,dwINTCSR;
int iPort, iPortAddr, iCfgAddr;
byte ucCfgReg, ucDiCfgWord, ucTrigType;
word wCount;
void interrupt (*pOldIsr)(void);
byte ucIrqMask;
long lPreIntCount;
wVendorId = VENDOR_ID;
wDeviceId = DEVICE_ID;
wIndex = 0;
clrscr();
printf("Arbor Technology Corp.\n\n");
printf("Counter Interrupt demo program.\n");
printf("Signals connection:\n");
printf(" Channel 1 Clock : TCLK_B1(pin 16) and TCLK_A1(pin 34)\n");
printf(" Channel 1 GATE : TGT_B1(pin 17) and TGT_A1(pin 35)\n");
printf(" Channel 2 Clock : TCLK_B2(pin 18) and TCLK_A2(pin 36)\n");
printf(" Channel 2 GATE : TGT_B2(pin 19) and TGT_A2(pin 37)\n");
//Get IRQ source, Counter channel 1 or 2
do
{
printf("\nChoose interrupt source: 1=Counter1, 2=Counter2 ");
iPort=getche();
}while(iPort < 0x31 || iPort > 0x32);
iPort = iPort & 0x0f; //Select counter Port
wCount = 100; //Down count value
clrscr();
printf("This program generate interrupt every while the counter %d", iPort);
printf(" gets %d events.", wCount);
printf("\n\nPress any key to start this function...");
getch();
/***************************
* Get pDAQ-72x's resource
***************************/
//
// Search pDAQ-72x
//
for( wIndex=0; wIndex < 32; wIndex++)
{
iErrCode = find_pci_device(
wDeviceId,
wVendorId,
wIndex,
&ucBusNumber,
&ucDevAndFunc );
if (iErrCode == NOT_SUCCESSFUL )
{
printf("\n pDAQ-720/722 search fail.\n");
exit(1);
}
iErrCode = read_configuration_dword(
ucBusNumber,
ucDevAndFunc,
PCI_CS_SUBSYSTEM_ID,
&dwData);
if(dwData == SUBSYSTEM_ID)
break;
}
//
//Get base address, from PCI base address range 2
//
iErrCode = read_configuration_dword(
ucBusNumber,
ucDevAndFunc,
PCI_CS_BASE_ADDRESS_2,
&dwData);
if (iErrCode == NOT_SUCCESSFUL)
{
printf("\npDAQ-72x gets base address failure.\n");
exit(1);
}
else
gdwBaseAddr = dwData & 0xfffffffc;
//
//Get base address, from PCI base address range 3
//
iErrCode = read_configuration_dword(
ucBusNumber,
ucDevAndFunc,
PCI_CS_BASE_ADDRESS_3,
&dwData);
if (iErrCode == NOT_SUCCESSFUL)
{
printf("\npDAQ-722 gets base address fail.\n");
exit(1);
}
else
gdwBaseAddrCs1 = dwData & 0xfffffffc;
//
//Get base address, from PCI base address range 1
//
iErrCode = read_configuration_dword(
ucBusNumber,
ucDevAndFunc,
PCI_CS_BASE_ADDRESS_1,
&dwData);
if (iErrCode == NOT_SUCCESSFUL)
{
printf("\npDAQ-722 gets base address fail.\n");
exit(1);
}
else
gdwBaseAddrBa1 = dwData & 0xfffffffc;
/***************************
* Device configuration
***************************/
//Interrupt source selection
outportb(gdwBaseAddr+0x0c, 0x03);
//Clear Interrupt
outportb(gdwBaseAddrCs1, 0x00);
//
// enable PLX 9050 PCI interrupt
//
dwINTCSR = inportb(gdwBaseAddrBa1+0x4c);
dwData = dwINTCSR;
if(iPort == 1)
dwData = dwData | 0x01; //Local Interrupt 1 Enable
else
dwData = dwData | 0x08; //Local Interrupt 2 Enable
outportb(gdwBaseAddrBa1+0x4c, dwData);
//
// Get Interrupt line
//
iErrCode = read_configuration_dword(
ucBusNumber,
ucDevAndFunc,
PCI_CS_INTERRUPT_LINE,
&dwData);
if (iErrCode == NOT_SUCCESSFUL)
{
printf("\npDAQ-722 gets interrupt line fail.\n");
exit(1);
}
else
giIrqNum = dwData & 0xf;
/**************
* Install ISR.
**************/
ucIrqMask = InitInterrupt(giIrqNum, IrqHandler, &pOldIsr);
/*************************************
* Program counter to Mode 4 for generating interrupt cyclically.
*
* Base + 27, control register, standard mode
* bit# 7 6 5 4 3 2 1 0
* value SC1 SC2 RW1 RW0 M2 M1 M0 BCD
*
* SC1 SC0 Select Counter | RW1 RW2 Select R/W operation
* 0 0 0 | 0 0 Counter latch
* 0 1 1 | 0 1 Read/write LSB
* 1 0 2 | 1 0 Read/write MSB
* 1 1 Read-back comand | 1 1 R/W LSB first then MSB
*
* M2 M1 M0 Mode
* 0 0 0 0 Stop on terminal count
* 0 0 1 1 Programable one shot
* 0 1 0 2 Rate generate
* 0 1 1 3 Square wave generator
* 1 0 0 4 Software triggered strobe
* 1 0 1 5 Hardware triggered strobe
******************************/
iPortAddr = iPort + 8; //Counter's adress
iCfgAddr = 0x0b; //Counter configuration address
//Write counter configuration word
ucCfgReg = iPort << 6; //Select counter port
ucCfgReg = ucCfgReg | 0x30; //R/W LSB first, then MSB
ucCfgReg = ucCfgReg | 0x04; //Mode 2, Rate generate
ucCfgReg = ucCfgReg | 0; //Binary counting
outportb(gdwBaseAddr+iCfgAddr, ucCfgReg); //Write down control word
//Write down counting value
outportb(gdwBaseAddr+iPortAddr, wCount & 0xff); //Write LSB
outportb(gdwBaseAddr+iPortAddr, (wCount >> 8 ) & 0xff); //Write MSB
/*************************************
* Config to Counter interrupt mode
* port# Port C1 | Port C0
* bit # D7 D6 D5 D4 | D3 D2 D1 D0
* Abbreviation F1 E1 M11 M10 | F0 E0 M01 M00
*
* Mx1 Mx0 Port_GRP_x | Ex Triggering edge
* 0 0 Disable interrupt | 0 Rising edge trigger
* 0 1 Source=PCx0 | 1 Falling edge trigger
* 1 0 Source=PCx0 && PCx4 |
* 1 1 Counter | Fx Interrupt flag
*
*************************************/
giIntControlRegAddr = 32; //Interrupt Control Register address
ucCfgReg = inportb(gdwBaseAddr+giIntControlRegAddr);
switch(iPort)
{
case 1: //Timer 1
ucCfgReg = ucCfgReg & 0xf0; //Preserve not change bits
ucCfgReg = ucCfgReg | 0x3; //Source from Counter
ucTrigType = 0x4; //rising edge
giIrqFlagBit = 0x8; //Interrupt flag bit (F0)
break;
case 2: //Counter 2
ucCfgReg = ucCfgReg & 0xf; //Preserve not change bits
ucCfgReg = ucCfgReg | 0x30; //Source from counter
ucTrigType = 0x40; //rising edge
giIrqFlagBit = 0x80; //Interrupt flag bit (F1)
break;
default:
printf("\nChannel %d not support Interrupt function.", iPort);
printf("\nTerminate program!");
exit(1);
}
outportb(gdwBaseAddr+giIntControlRegAddr, ucCfgReg);
outportb(gdwBaseAddr+giIntControlRegAddr, ucCfgReg | ucTrigType);
/************
* Polling interrupt count
************/
glIntCount = 0;
lPreIntCount = -1;
while(!kbhit())
{
if(lPreIntCount < glIntCount)
{
printf("\n\nInterrupt generated count: %lu", glIntCount);
printf("\nPress any key to stop...");
lPreIntCount = glIntCount;
}
}
if(kbhit()) getch();
/************
* Restore interrupt Control/Status Register
************/
outportb(gdwBaseAddrBa1+0x4c,dwINTCSR);
/************
* Stop device to generate interrupt
************/
outportb(gdwBaseAddr+giIntControlRegAddr, 0);
/************
* Stop IRQ and restore system ISR
************/
RestoreOldIsr(giIrqNum, ucIrqMask, pOldIsr);
}//main
/************************************************************************
* Function: Init ISR to handle device generated IRQ
* Paramater: iIrqNum, IN, IRQ number.
* pIsrHandler,IN, ISR handler for installation.
* pOldIsr, OUT, Old ISR routine.
* return: IRQ mask
************************************************************************/
byte InitInterrupt( int iIrqNum,
void interrupt (*pIsrHandler)(),
void interrupt (**pOldIsr)() )
{
byte ucIrqMask, ucTotalMask;
//
// 1. DISABLE PC INTERRUPT
//
disable();
//
// 2. STORE OLD INT. HANDLER */
//
if ( iIrqNum < 8 )
*pOldIsr = getvect(iIrqNum+8);
else
*pOldIsr = getvect(iIrqNum-8+0x70);
//
// 3. SET INTERRUPT VECTOR
//
if(iIrqNum < 8)
setvect(iIrqNum+8, pIsrHandler);
else
setvect(iIrqNum-8+0x70, pIsrHandler);
//
// 4. ENABLE 8259 INT. MASK
//
if(iIrqNum < 8)
{
ucTotalMask = inportb(0x21);
ucIrqMask = ucTotalMask & (0x01<<iIrqNum);
outportb(0x21, ucTotalMask & ~(0x01<<iIrqNum) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -