⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cntint.c

📁 在dos下读写pci卡
💻 C
字号:
/*
   '**********************************************************************
   '*  Program  : CNTINT.C                                               *
   '*  Revision : 1.00                                                   *
   '*  Date     : 06/25/2004                         Shen Xinyang        *
   '*====================================================================*
   '*                                                                    *
   '*  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 "PCI32.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; //PCI32 Interrupt control register address.
int   giIrqFlagBit;        //Interrupt flag
long  glIntCount;          //Interrupt generate count
dword IntCount;				//accepted interrupt counter

 static dword inpd(int portnum);  //input 32 bit ward


/***********
 * 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();
  iPort = 0x31;

  iPort = iPort & 0x0f;        //port for input
  wCount = 100;                //Down count value

 /***************************
  * Get pci32ad resource
  ***************************/
  //
  // Search pci32ad
  //
  for( wIndex=0; wIndex < 32; wIndex++)
  {
    iErrCode = find_pci_device(
				  wDeviceId,
                  wVendorId,
				  wIndex,
                  &ucBusNumber,
                  &ucDevAndFunc );
    if (iErrCode == NOT_SUCCESSFUL )
    {
       printf("\n pci32ad 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("\npci32ad gets base address failure.\n");
	exit(1);
  }
  else
	gdwBaseAddr = dwData & 0xfffffffc;//base address of Local space 0

  //
  //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("\npci32ad gets base address fail.\n");
	exit(1);
  }
  else
	gdwBaseAddrCs1 = dwData & 0xfffffffc;//base address of local space 1

  //
  //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("\npci32ad gets base address fail.\n");
	  exit(1);
   }
   else
	  gdwBaseAddrBa1 = dwData & 0xfffffffc;//address for i/o access to local address

  /***************************
   * Device configuration
   ***************************/

  //
  // enable PLX 9054 PCI interrupt
  //
//  dwINTCSR = inportb(gdwBaseAddrBa1+0xe8);
  dwINTCSR = inpd(gdwBaseAddrBa1+0x68);
  dwData = dwINTCSR;

	dwData = dwData | 0x01;    //Local Interrupt 1 Enable


  outportb(gdwBaseAddrBa1+0x68, dwData);

  //
  // Get Interrupt line
  //
  iErrCode = read_configuration_dword(
				ucBusNumber,
				ucDevAndFunc,
				PCI_CS_INTERRUPT_LINE,
				&dwData);
  if (iErrCode == NOT_SUCCESSFUL)
  {
	printf("\npci32ad gets interrupt line fail.\n");
	exit(1);
  }
  else
	giIrqNum = dwData & 0xf;

 /**************
  * Install ISR.
  **************/
  ucIrqMask = InitInterrupt(giIrqNum, IrqHandler, &pOldIsr);


   /************
	* 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();
   printf("\n The number of interrupt is %lu",IntCount);

   /************
	* Restore interrupt Control/Status Register
	************/
   outportb(gdwBaseAddrBa1+0x68,dwINTCSR);


   /************
	* 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
 * note:   当中断号小于8时,中断向量号为iIrqNum+8,否则为iIrqNum-8+0x70
 ************************************************************************/
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) );
   }
   else
   {
	  ucTotalMask = inportb(0xa1);
	  ucIrqMask = ucTotalMask & ~(0x01 << (iIrqNum-8));
	  outportb(0xa1, ucTotalMask & ~(0x01<<(iIrqNum-8)));
   }
	IntCount=0;
   //
   // 5. ENABLE  PC INTERRUPT
   //
   enable();
   return(ucIrqMask);
}//InitInterrupt

/**************************************************************
 * Function:  Restore system ISR.
 * Paramater: iIrqNum, IN, IRQ number
 *            ucIrqMask, IN, IRQ mask before install ISR
 *            pOldIsr, IN, Old ISR. restore it as service routine.
 *
 **************************************************************/
void RestoreOldIsr( int iIrqNum,
					byte ucIrqMask,
					void interrupt (*pOldIsr)() )
{
	byte ucTotalMask;

	disable();
	if ( iIrqNum < 8 )
	{
		ucTotalMask = (inportb(0x21) & ~(0x01<<iIrqNum)) | ucIrqMask;//inputb(0x20) shen
		outportb(0x21, ucTotalMask);
		setvect(iIrqNum+8, pOldIsr);
	}
	else
	{
		ucTotalMask = (inportb(0xa1) & ~(0x01<<(iIrqNum-8))) | ucIrqMask;
//		ucTotalMask = (inportb(0xa0) & ~(0x01<<(iIrqNum-8))) | ucIrqMask;
		outportb(0xa1, ucTotalMask);
		setvect(iIrqNum-8+0x70, pOldIsr);
	}
	enable();
}

/**************************************************************
 * Function : IrqHandler
 *            Interrupt service routine for pci32ad DI interrupt.
 *            fucntion.
 **************************************************************/
void interrupt IrqHandler(void)
{
   byte ucRegVal;
   dword dPCM[8192];
   int i,j;
   disable();
   for(i=0;i<16;i++)//16 channels
   {
	for(j=0;j<8192;j++)
	{
		dPCM[j]=inpd(gdwBaseAddr+0x31);
	}
   }
	IntCount++;
   //Enable system to accept next interrupt
 /*  outportb(0x20,0x20);
   if ( giIrqNum > 7 )
	  outportb(0xa0,0x20);
*/
    if (giIrqNum < 8)
		outportb(0x20,0x20);
	else
		outportb(0xa0,0x20);
   enable();
}//IrqHandler


/**************************************************************
 * Function : inpd(int portnum)
 *            dword input from portnum.
 *            fucntion.
 **************************************************************/
 static dword inpd(int portnum)
 {
 	static dword value;
 	asm mov dx,portnum;
 	asm lea bx,value;
	__emit__(0x66,0x50,  //push eax
 	       0x66,0xED,  //in eax,dx
 	       0x66,0x89,0x07,  //mov [bx],eax
 	       0x66,0x58); //pop eax
 	return value;	
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -